Merge tag 'efi-2019-10-rc4-4' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi
[oweals/u-boot.git] / arch / x86 / lib / reloc_ia32_efi.c
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
14 efi_status_t EFIAPI _relocate(long ldbase, Elf32_Dyn *dyn)
15 {
16         long relsz = 0, relent = 0;
17         Elf32_Rel *rel = 0;
18         unsigned long *addr;
19         int i;
20
21         for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
22                 switch (dyn[i].d_tag) {
23                 case DT_REL:
24                         rel = (Elf32_Rel *)((unsigned long)dyn[i].d_un.d_ptr +
25                                                                 ldbase);
26                         break;
27
28                 case DT_RELSZ:
29                         relsz = dyn[i].d_un.d_val;
30                         break;
31
32                 case DT_RELENT:
33                         relent = dyn[i].d_un.d_val;
34                         break;
35
36                 case DT_RELA:
37                         break;
38
39                 default:
40                         break;
41                 }
42         }
43
44         if (!rel && relent == 0)
45                 return EFI_SUCCESS;
46
47         if (!rel || relent == 0)
48                 return EFI_LOAD_ERROR;
49
50         while (relsz > 0) {
51                 /* apply the relocs */
52                 switch (ELF32_R_TYPE(rel->r_info)) {
53                 case R_386_NONE:
54                         break;
55
56                 case R_386_RELATIVE:
57                         addr = (unsigned long *)(ldbase + rel->r_offset);
58                         *addr += ldbase;
59                         break;
60
61                 default:
62                         break;
63                 }
64                 rel = (Elf32_Rel *)((char *)rel + relent);
65                 relsz -= relent;
66         }
67
68         return EFI_SUCCESS;
69 }