xref: /rk3399_rockchip-uboot/arch/x86/lib/reloc_ia32_efi.c (revision 2d221489df021393654805536be7effcb9d39702)
1*2dcd4e9eSSimon Glass /*
2*2dcd4e9eSSimon Glass  * reloc_ia32.c - position independent x86 ELF shared object relocator
3*2dcd4e9eSSimon Glass  * Copyright (C) 1999 Hewlett-Packard Co.
4*2dcd4e9eSSimon Glass  * Contributed by David Mosberger <davidm@hpl.hp.com>.
5*2dcd4e9eSSimon Glass  *
6*2dcd4e9eSSimon Glass  * All rights reserved.
7*2dcd4e9eSSimon Glass  *
8*2dcd4e9eSSimon Glass  * SPDX-License-Identifier:	BSD-3-Clause
9*2dcd4e9eSSimon Glass  */
10*2dcd4e9eSSimon Glass 
11*2dcd4e9eSSimon Glass #include <common.h>
12*2dcd4e9eSSimon Glass #include <efi.h>
13*2dcd4e9eSSimon Glass #include <elf.h>
14*2dcd4e9eSSimon Glass #include <asm/elf.h>
15*2dcd4e9eSSimon Glass 
_relocate(long ldbase,Elf32_Dyn * dyn,efi_handle_t image,struct efi_system_table * systab)16*2dcd4e9eSSimon Glass efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image,
17*2dcd4e9eSSimon Glass 		       struct efi_system_table *systab)
18*2dcd4e9eSSimon Glass {
19*2dcd4e9eSSimon Glass 	long relsz = 0, relent = 0;
20*2dcd4e9eSSimon Glass 	Elf32_Rel *rel = 0;
21*2dcd4e9eSSimon Glass 	unsigned long *addr;
22*2dcd4e9eSSimon Glass 	int i;
23*2dcd4e9eSSimon Glass 
24*2dcd4e9eSSimon Glass 	for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
25*2dcd4e9eSSimon Glass 		switch (dyn[i].d_tag) {
26*2dcd4e9eSSimon Glass 		case DT_REL:
27*2dcd4e9eSSimon Glass 			rel = (Elf32_Rel *)((unsigned long)dyn[i].d_un.d_ptr +
28*2dcd4e9eSSimon Glass 								ldbase);
29*2dcd4e9eSSimon Glass 			break;
30*2dcd4e9eSSimon Glass 
31*2dcd4e9eSSimon Glass 		case DT_RELSZ:
32*2dcd4e9eSSimon Glass 			relsz = dyn[i].d_un.d_val;
33*2dcd4e9eSSimon Glass 			break;
34*2dcd4e9eSSimon Glass 
35*2dcd4e9eSSimon Glass 		case DT_RELENT:
36*2dcd4e9eSSimon Glass 			relent = dyn[i].d_un.d_val;
37*2dcd4e9eSSimon Glass 			break;
38*2dcd4e9eSSimon Glass 
39*2dcd4e9eSSimon Glass 		case DT_RELA:
40*2dcd4e9eSSimon Glass 			break;
41*2dcd4e9eSSimon Glass 
42*2dcd4e9eSSimon Glass 		default:
43*2dcd4e9eSSimon Glass 			break;
44*2dcd4e9eSSimon Glass 		}
45*2dcd4e9eSSimon Glass 	}
46*2dcd4e9eSSimon Glass 
47*2dcd4e9eSSimon Glass 	if (!rel && relent == 0)
48*2dcd4e9eSSimon Glass 		return EFI_SUCCESS;
49*2dcd4e9eSSimon Glass 
50*2dcd4e9eSSimon Glass 	if (!rel || relent == 0)
51*2dcd4e9eSSimon Glass 		return EFI_LOAD_ERROR;
52*2dcd4e9eSSimon Glass 
53*2dcd4e9eSSimon Glass 	while (relsz > 0) {
54*2dcd4e9eSSimon Glass 		/* apply the relocs */
55*2dcd4e9eSSimon Glass 		switch (ELF32_R_TYPE(rel->r_info)) {
56*2dcd4e9eSSimon Glass 		case R_386_NONE:
57*2dcd4e9eSSimon Glass 			break;
58*2dcd4e9eSSimon Glass 
59*2dcd4e9eSSimon Glass 		case R_386_RELATIVE:
60*2dcd4e9eSSimon Glass 			addr = (unsigned long *)(ldbase + rel->r_offset);
61*2dcd4e9eSSimon Glass 			*addr += ldbase;
62*2dcd4e9eSSimon Glass 			break;
63*2dcd4e9eSSimon Glass 
64*2dcd4e9eSSimon Glass 		default:
65*2dcd4e9eSSimon Glass 			break;
66*2dcd4e9eSSimon Glass 		}
67*2dcd4e9eSSimon Glass 		rel = (Elf32_Rel *)((char *)rel + relent);
68*2dcd4e9eSSimon Glass 		relsz -= relent;
69*2dcd4e9eSSimon Glass 	}
70*2dcd4e9eSSimon Glass 
71*2dcd4e9eSSimon Glass 	return EFI_SUCCESS;
72*2dcd4e9eSSimon Glass }
73