blob: d56cd50bd937a1268949bf1b153b41bfdfb996b7 [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
10#include <common.h>
11#include <efi.h>
12#include <elf.h>
Ben Stoltzab76a472015-08-04 12:33:46 -060013
Ivan Gorinov28bad7d2018-06-28 14:49:46 -070014efi_status_t EFIAPI _relocate(long ldbase, Elf32_Dyn *dyn)
Ben Stoltzab76a472015-08-04 12:33:46 -060015{
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}