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