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 | } |