Merge git://git.denx.de/u-boot-x86
[oweals/u-boot.git] / arch / x86 / lib / efi / reloc_ia32.c
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 }