1
/* reloc_ia32.c - position independent x86 ELF shared object relocator
2
Copyright (C) 1999 Hewlett-Packard Co.
3
Contributed by David Mosberger <davidm@hpl.hp.com>.
5
This file is part of GNU-EFI, the GNU EFI development environment.
7
GNU EFI is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
12
GNU EFI is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with GNU EFI; see the file COPYING. If not, write to the Free
19
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23
#include <link.h> /* get _DYNAMIC decl and ElfW and ELFW macros */
26
#define uint64_t efi_uint64_t
27
#define int64_t efi_int64_t
28
#define uint32_t efi_uint32_t
29
#define int32_t efi_int32_t
30
#define uint16_t efi_uint16_t
31
#define int16_t efi_int16_t
32
#define uint8_t efi_uint8_t
33
#define int8_t efi_int8_t
36
#define uint64_t efi_uint64_t
37
#define int64_t efi_int64_t
38
#define uint32_t efi_uint32_t
39
#define int32_t efi_int32_t
40
#define uint16_t efi_uint16_t
41
#define int16_t efi_int16_t
42
#define uint8_t efi_uint8_t
43
#define int8_t efi_int8_t
49
_relocate (long ldbase, ElfW(Dyn) *dyn, EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
51
extern EFI_STATUS efi_main (EFI_HANDLE, EFI_SYSTEM_TABLE *);
52
long relsz = 0, relent = 0;
56
for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
57
switch (dyn[i].d_tag) {
59
rel = (ElfW(Rel)*) ((long) dyn[i].d_un.d_ptr + ldbase);
63
relsz = dyn[i].d_un.d_val;
67
relent = dyn[i].d_un.d_val;
79
if (!rel || relent == 0)
80
return EFI_LOAD_ERROR;
82
/* apply the relocs */
83
switch (ELF32_R_TYPE (rel->r_info)) {
91
addr = (long *) (ldbase + rel->r_offset);
97
return EFI_LOAD_ERROR;
99
rel = (ElfW(Rel)*) ((char *) rel + relent);