blob: 17ab54dc2469e992fde0cbe70dcbbd04301cb75e [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: BSD-3-Clause
Ben Stoltzab76a472015-08-04 12:33:46 -06002/*
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.
Ben Stoltzab76a472015-08-04 12:33:46 -06008 */
9
Ben Stoltzab76a472015-08-04 12:33:46 -060010#include <efi.h>
11#include <elf.h>
Ben Stoltzab76a472015-08-04 12:33:46 -060012
Ivan Gorinov28bad7d2018-06-28 14:49:46 -070013efi_status_t EFIAPI _relocate(long ldbase, Elf32_Dyn *dyn)
Ben Stoltzab76a472015-08-04 12:33:46 -060014{
15 long relsz = 0, relent = 0;
16 Elf32_Rel *rel = 0;
17 unsigned long *addr;
18 int i;
19
20 for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
21 switch (dyn[i].d_tag) {
22 case DT_REL:
23 rel = (Elf32_Rel *)((unsigned long)dyn[i].d_un.d_ptr +
24 ldbase);
25 break;
26
27 case DT_RELSZ:
28 relsz = dyn[i].d_un.d_val;
29 break;
30
31 case DT_RELENT:
32 relent = dyn[i].d_un.d_val;
33 break;
34
35 case DT_RELA:
36 break;
37
38 default:
39 break;
40 }
41 }
42
43 if (!rel && relent == 0)
44 return EFI_SUCCESS;
45
46 if (!rel || relent == 0)
47 return EFI_LOAD_ERROR;
48
49 while (relsz > 0) {
50 /* apply the relocs */
51 switch (ELF32_R_TYPE(rel->r_info)) {
52 case R_386_NONE:
53 break;
54
55 case R_386_RELATIVE:
56 addr = (unsigned long *)(ldbase + rel->r_offset);
57 *addr += ldbase;
58 break;
59
60 default:
61 break;
62 }
63 rel = (Elf32_Rel *)((char *)rel + relent);
64 relsz -= relent;
65 }
66
67 return EFI_SUCCESS;
68}