1 /* 2 * reloc_ia32.c - position independent x86 ELF shared object relocator 3 * Copyright (C) 1999 Hewlett-Packard Co. 4 * Contributed by David Mosberger <davidm@hpl.hp.com>. 5 * 6 * All rights reserved. 7 * 8 * SPDX-License-Identifier: BSD-3-Clause 9 */ 10 11 #include <common.h> 12 #include <efi.h> 13 #include <elf.h> 14 #include <asm/elf.h> 15 16 efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image, 17 struct efi_system_table *systab) 18 { 19 long relsz = 0, relent = 0; 20 Elf32_Rel *rel = 0; 21 unsigned long *addr; 22 int i; 23 24 for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { 25 switch (dyn[i].d_tag) { 26 case DT_REL: 27 rel = (Elf32_Rel *)((unsigned long)dyn[i].d_un.d_ptr + 28 ldbase); 29 break; 30 31 case DT_RELSZ: 32 relsz = dyn[i].d_un.d_val; 33 break; 34 35 case DT_RELENT: 36 relent = dyn[i].d_un.d_val; 37 break; 38 39 case DT_RELA: 40 break; 41 42 default: 43 break; 44 } 45 } 46 47 if (!rel && relent == 0) 48 return EFI_SUCCESS; 49 50 if (!rel || relent == 0) 51 return EFI_LOAD_ERROR; 52 53 while (relsz > 0) { 54 /* apply the relocs */ 55 switch (ELF32_R_TYPE(rel->r_info)) { 56 case R_386_NONE: 57 break; 58 59 case R_386_RELATIVE: 60 addr = (unsigned long *)(ldbase + rel->r_offset); 61 *addr += ldbase; 62 break; 63 64 default: 65 break; 66 } 67 rel = (Elf32_Rel *)((char *)rel + relent); 68 relsz -= relent; 69 } 70 71 return EFI_SUCCESS; 72 } 73