]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: BSD-3-Clause |
3dcdd17b BS |
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. | |
3dcdd17b BS |
8 | */ |
9 | ||
10 | #include <common.h> | |
11 | #include <efi.h> | |
12 | #include <elf.h> | |
13 | #include <asm/elf.h> | |
14 | ||
15 | efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image, | |
16 | struct efi_system_table *systab) | |
17 | { | |
18 | long relsz = 0, relent = 0; | |
19 | Elf32_Rel *rel = 0; | |
20 | unsigned long *addr; | |
21 | int i; | |
22 | ||
23 | for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { | |
24 | switch (dyn[i].d_tag) { | |
25 | case DT_REL: | |
26 | rel = (Elf32_Rel *)((unsigned long)dyn[i].d_un.d_ptr + | |
27 | ldbase); | |
28 | break; | |
29 | ||
30 | case DT_RELSZ: | |
31 | relsz = dyn[i].d_un.d_val; | |
32 | break; | |
33 | ||
34 | case DT_RELENT: | |
35 | relent = dyn[i].d_un.d_val; | |
36 | break; | |
37 | ||
38 | case DT_RELA: | |
39 | break; | |
40 | ||
41 | default: | |
42 | break; | |
43 | } | |
44 | } | |
45 | ||
46 | if (!rel && relent == 0) | |
47 | return EFI_SUCCESS; | |
48 | ||
49 | if (!rel || relent == 0) | |
50 | return EFI_LOAD_ERROR; | |
51 | ||
52 | while (relsz > 0) { | |
53 | /* apply the relocs */ | |
54 | switch (ELF32_R_TYPE(rel->r_info)) { | |
55 | case R_386_NONE: | |
56 | break; | |
57 | ||
58 | case R_386_RELATIVE: | |
59 | addr = (unsigned long *)(ldbase + rel->r_offset); | |
60 | *addr += ldbase; | |
61 | break; | |
62 | ||
63 | default: | |
64 | break; | |
65 | } | |
66 | rel = (Elf32_Rel *)((char *)rel + relent); | |
67 | relsz -= relent; | |
68 | } | |
69 | ||
70 | return EFI_SUCCESS; | |
71 | } |