Rev 2726 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2726 | vana | 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>. |
||
4 | |||
5 | This file is part of GNU-EFI, the GNU EFI development environment. |
||
6 | |||
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) |
||
10 | any later version. |
||
11 | |||
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. |
||
16 | |||
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 |
||
20 | 02111-1307, USA. */ |
||
21 | |||
22 | #include <elf.h> |
||
23 | #include <link.h> /* get _DYNAMIC decl and ElfW and ELFW macros */ |
||
24 | |||
25 | #undef NULL |
||
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 |
||
34 | |||
35 | #undef NULL |
||
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 |
||
44 | |||
45 | #include <efi.h> |
||
46 | #include <efilib.h> |
||
47 | |||
48 | int |
||
49 | _relocate (long ldbase, ElfW(Dyn) *dyn, EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) |
||
50 | { |
||
51 | extern EFI_STATUS efi_main (EFI_HANDLE, EFI_SYSTEM_TABLE *); |
||
52 | long relsz = 0, relent = 0; |
||
53 | ElfW(Rel) *rel = 0; |
||
54 | int i; |
||
55 | |||
56 | for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { |
||
57 | switch (dyn[i].d_tag) { |
||
58 | case DT_REL: |
||
59 | rel = (ElfW(Rel)*) ((long) dyn[i].d_un.d_ptr + ldbase); |
||
60 | break; |
||
61 | |||
62 | case DT_RELSZ: |
||
63 | relsz = dyn[i].d_un.d_val; |
||
64 | break; |
||
65 | |||
66 | case DT_RELENT: |
||
67 | relent = dyn[i].d_un.d_val; |
||
68 | break; |
||
69 | |||
70 | case DT_RELA: |
||
71 | break; |
||
72 | |||
73 | default: |
||
74 | break; |
||
75 | } |
||
76 | } |
||
77 | |||
78 | while (relsz > 0) { |
||
79 | if (!rel || relent == 0) |
||
80 | return EFI_LOAD_ERROR; |
||
81 | |||
82 | /* apply the relocs */ |
||
83 | switch (ELF32_R_TYPE (rel->r_info)) { |
||
84 | case R_386_NONE: |
||
85 | break; |
||
86 | |||
87 | case R_386_RELATIVE: |
||
88 | { |
||
89 | long *addr; |
||
90 | |||
91 | addr = (long *) (ldbase + rel->r_offset); |
||
92 | *addr += ldbase; |
||
93 | break; |
||
94 | } |
||
95 | |||
96 | default: |
||
97 | return EFI_LOAD_ERROR; |
||
98 | } |
||
99 | rel = (ElfW(Rel)*) ((char *) rel + relent); |
||
100 | relsz -= relent; |
||
101 | } |
||
102 | return EFI_SUCCESS; |
||
103 | } |