]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: BSD-3-Clause |
465a67cf SG |
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. | |
465a67cf SG |
10 | */ |
11 | ||
d678a59d | 12 | #include <common.h> |
465a67cf SG |
13 | #include <efi.h> |
14 | #include <elf.h> | |
465a67cf | 15 | |
62500986 | 16 | efi_status_t EFIAPI _relocate(long ldbase, Elf64_Dyn *dyn) |
465a67cf SG |
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 | } |