Rev 2726 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2726 | Rev 3888 | ||
---|---|---|---|
1 | /* reloc_ia32.c - position independent x86 ELF shared object relocator |
1 | /* reloc_ia32.c - position independent x86 ELF shared object relocator |
2 | Copyright (C) 1999 Hewlett-Packard Co. |
2 | Copyright (C) 1999 Hewlett-Packard Co. |
3 | Contributed by David Mosberger <davidm@hpl.hp.com>. |
3 | Contributed by David Mosberger <davidm@hpl.hp.com>. |
4 | 4 | ||
5 | This file is part of GNU-EFI, the GNU EFI development environment. |
5 | This file is part of GNU-EFI, the GNU EFI development environment. |
6 | 6 | ||
7 | GNU EFI is free software; you can redistribute it and/or modify |
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 |
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) |
9 | the Free Software Foundation; either version 2, or (at your option) |
10 | any later version. |
10 | any later version. |
11 | 11 | ||
12 | GNU EFI is distributed in the hope that it will be useful, |
12 | GNU EFI is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | GNU General Public License for more details. |
15 | GNU General Public License for more details. |
16 | 16 | ||
17 | You should have received a copy of the GNU General Public License |
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 |
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 |
19 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA |
20 | 02111-1307, USA. */ |
20 | 02111-1307, USA. */ |
21 | 21 | ||
22 | #include <elf.h> |
22 | #include <elf.h> |
23 | #include <link.h> /* get _DYNAMIC decl and ElfW and ELFW macros */ |
23 | #include <link.h> /* get _DYNAMIC decl and ElfW and ELFW macros */ |
24 | 24 | ||
25 | #undef NULL |
25 | #undef NULL |
26 | #define uint64_t efi_uint64_t |
26 | #define uint64_t efi_uint64_t |
27 | #define int64_t efi_int64_t |
27 | #define int64_t efi_int64_t |
28 | #define uint32_t efi_uint32_t |
28 | #define uint32_t efi_uint32_t |
29 | #define int32_t efi_int32_t |
29 | #define int32_t efi_int32_t |
30 | #define uint16_t efi_uint16_t |
30 | #define uint16_t efi_uint16_t |
31 | #define int16_t efi_int16_t |
31 | #define int16_t efi_int16_t |
32 | #define uint8_t efi_uint8_t |
32 | #define uint8_t efi_uint8_t |
33 | #define int8_t efi_int8_t |
33 | #define int8_t efi_int8_t |
34 | 34 | ||
35 | #undef NULL |
35 | #undef NULL |
36 | #define uint64_t efi_uint64_t |
36 | #define uint64_t efi_uint64_t |
37 | #define int64_t efi_int64_t |
37 | #define int64_t efi_int64_t |
38 | #define uint32_t efi_uint32_t |
38 | #define uint32_t efi_uint32_t |
39 | #define int32_t efi_int32_t |
39 | #define int32_t efi_int32_t |
40 | #define uint16_t efi_uint16_t |
40 | #define uint16_t efi_uint16_t |
41 | #define int16_t efi_int16_t |
41 | #define int16_t efi_int16_t |
42 | #define uint8_t efi_uint8_t |
42 | #define uint8_t efi_uint8_t |
43 | #define int8_t efi_int8_t |
43 | #define int8_t efi_int8_t |
44 | 44 | ||
45 | #include <efi.h> |
45 | #include <efi.h> |
46 | #include <efilib.h> |
46 | #include <efilib.h> |
47 | 47 | ||
48 | int |
48 | int |
49 | _relocate (long ldbase, ElfW(Dyn) *dyn, EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) |
49 | _relocate (long ldbase, ElfW(Dyn) *dyn, EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) |
50 | { |
50 | { |
51 | extern EFI_STATUS efi_main (EFI_HANDLE, EFI_SYSTEM_TABLE *); |
51 | extern EFI_STATUS efi_main (EFI_HANDLE, EFI_SYSTEM_TABLE *); |
52 | long relsz = 0, relent = 0; |
52 | long relsz = 0, relent = 0; |
53 | ElfW(Rel) *rel = 0; |
53 | ElfW(Rel) *rel = 0; |
54 | int i; |
54 | int i; |
55 | 55 | ||
56 | for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { |
56 | for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { |
57 | switch (dyn[i].d_tag) { |
57 | switch (dyn[i].d_tag) { |
58 | case DT_REL: |
58 | case DT_REL: |
59 | rel = (ElfW(Rel)*) ((long) dyn[i].d_un.d_ptr + ldbase); |
59 | rel = (ElfW(Rel)*) ((long) dyn[i].d_un.d_ptr + ldbase); |
60 | break; |
60 | break; |
61 | 61 | ||
62 | case DT_RELSZ: |
62 | case DT_RELSZ: |
63 | relsz = dyn[i].d_un.d_val; |
63 | relsz = dyn[i].d_un.d_val; |
64 | break; |
64 | break; |
65 | 65 | ||
66 | case DT_RELENT: |
66 | case DT_RELENT: |
67 | relent = dyn[i].d_un.d_val; |
67 | relent = dyn[i].d_un.d_val; |
68 | break; |
68 | break; |
69 | 69 | ||
70 | case DT_RELA: |
70 | case DT_RELA: |
71 | break; |
71 | break; |
72 | 72 | ||
73 | default: |
73 | default: |
74 | break; |
74 | break; |
75 | } |
75 | } |
76 | } |
76 | } |
77 | 77 | ||
78 | while (relsz > 0) { |
78 | while (relsz > 0) { |
79 | if (!rel || relent == 0) |
79 | if (!rel || relent == 0) |
80 | return EFI_LOAD_ERROR; |
80 | return EFI_LOAD_ERROR; |
81 | 81 | ||
82 | /* apply the relocs */ |
82 | /* apply the relocs */ |
83 | switch (ELF32_R_TYPE (rel->r_info)) { |
83 | switch (ELF32_R_TYPE (rel->r_info)) { |
84 | case R_386_NONE: |
84 | case R_386_NONE: |
85 | break; |
85 | break; |
86 | 86 | ||
87 | case R_386_RELATIVE: |
87 | case R_386_RELATIVE: |
88 | { |
88 | { |
89 | long *addr; |
89 | long *addr; |
90 | 90 | ||
91 | addr = (long *) (ldbase + rel->r_offset); |
91 | addr = (long *) (ldbase + rel->r_offset); |
92 | *addr += ldbase; |
92 | *addr += ldbase; |
93 | break; |
93 | break; |
94 | } |
94 | } |
95 | 95 | ||
96 | default: |
96 | default: |
97 | return EFI_LOAD_ERROR; |
97 | return EFI_LOAD_ERROR; |
98 | } |
98 | } |
99 | rel = (ElfW(Rel)*) ((char *) rel + relent); |
99 | rel = (ElfW(Rel)*) ((char *) rel + relent); |
100 | relsz -= relent; |
100 | relsz -= relent; |
101 | } |
101 | } |
102 | return EFI_SUCCESS; |
102 | return EFI_SUCCESS; |
103 | } |
103 | } |
104 | 104 |