Merge tag 'ti-v2020.07-next' of https://gitlab.denx.de/u-boot/custodians/u-boot-ti...
[oweals/u-boot.git] / arch / x86 / lib / reloc_x86_64_efi.c
1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * reloc_x86_64.c - position independent x86_64 ELF shared object relocator
4  * Copyright (C) 1999 Hewlett-Packard Co.
5  * Contributed by David Mosberger <davidm@hpl.hp.com>.
6  * Copyright (C) 2005 Intel Co.
7  * Contributed by Fenghua Yu <fenghua.yu@intel.com>.
8  *
9  * All rights reserved.
10  */
11
12 #include <common.h>
13 #include <efi.h>
14 #include <elf.h>
15
16 efi_status_t EFIAPI _relocate(long ldbase, Elf64_Dyn *dyn)
17 {
18         long relsz = 0, relent = 0;
19         Elf64_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_RELA:
26                         rel = (Elf64_Rel *)
27                                 ((unsigned long)dyn[i].d_un.d_ptr + ldbase);
28                         break;
29                 case DT_RELASZ:
30                         relsz = dyn[i].d_un.d_val;
31                         break;
32                 case DT_RELAENT:
33                         relent = dyn[i].d_un.d_val;
34                         break;
35                 default:
36                         break;
37                 }
38         }
39
40         if (!rel && relent == 0)
41                 return EFI_SUCCESS;
42
43         if (!rel || relent == 0)
44                 return EFI_LOAD_ERROR;
45
46         while (relsz > 0) {
47                 /* apply the relocs */
48                 switch (ELF64_R_TYPE(rel->r_info)) {
49                 case R_X86_64_NONE:
50                         break;
51                 case R_X86_64_RELATIVE:
52                         addr = (unsigned long *)(ldbase + rel->r_offset);
53                         *addr += ldbase;
54                         break;
55                 default:
56                         break;
57                 }
58                 rel = (Elf64_Rel *)((char *)rel + relent);
59                 relsz -= relent;
60         }
61
62         return EFI_SUCCESS;
63 }