xref: /rk3399_rockchip-uboot/arch/arm/lib/reloc_aarch64_efi.c (revision 2d221489df021393654805536be7effcb9d39702)
1*c65d76edSSimon Glass /* reloc_aarch64.c - position independent x86 ELF shared object relocator
2*c65d76edSSimon Glass    Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
3*c65d76edSSimon Glass    Copyright (C) 1999 Hewlett-Packard Co.
4*c65d76edSSimon Glass 	Contributed by David Mosberger <davidm@hpl.hp.com>.
5*c65d76edSSimon Glass 
6*c65d76edSSimon Glass     All rights reserved.
7*c65d76edSSimon Glass 
8*c65d76edSSimon Glass     Redistribution and use in source and binary forms, with or without
9*c65d76edSSimon Glass     modification, are permitted provided that the following conditions
10*c65d76edSSimon Glass     are met:
11*c65d76edSSimon Glass 
12*c65d76edSSimon Glass     * Redistributions of source code must retain the above copyright
13*c65d76edSSimon Glass       notice, this list of conditions and the following disclaimer.
14*c65d76edSSimon Glass     * Redistributions in binary form must reproduce the above
15*c65d76edSSimon Glass       copyright notice, this list of conditions and the following
16*c65d76edSSimon Glass       disclaimer in the documentation and/or other materials
17*c65d76edSSimon Glass       provided with the distribution.
18*c65d76edSSimon Glass     * Neither the name of Hewlett-Packard Co. nor the names of its
19*c65d76edSSimon Glass       contributors may be used to endorse or promote products derived
20*c65d76edSSimon Glass       from this software without specific prior written permission.
21*c65d76edSSimon Glass 
22*c65d76edSSimon Glass     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23*c65d76edSSimon Glass     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24*c65d76edSSimon Glass     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25*c65d76edSSimon Glass     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26*c65d76edSSimon Glass     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
27*c65d76edSSimon Glass     BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
28*c65d76edSSimon Glass     OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29*c65d76edSSimon Glass     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30*c65d76edSSimon Glass     PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31*c65d76edSSimon Glass     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
32*c65d76edSSimon Glass     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
33*c65d76edSSimon Glass     THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34*c65d76edSSimon Glass     SUCH DAMAGE.
35*c65d76edSSimon Glass */
36*c65d76edSSimon Glass 
37*c65d76edSSimon Glass #include <efi.h>
38*c65d76edSSimon Glass 
39*c65d76edSSimon Glass #include <elf.h>
40*c65d76edSSimon Glass 
_relocate(long ldbase,Elf64_Dyn * dyn,efi_handle_t image,struct efi_system_table * systab)41*c65d76edSSimon Glass efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
42*c65d76edSSimon Glass 		       struct efi_system_table *systab)
43*c65d76edSSimon Glass {
44*c65d76edSSimon Glass 	long relsz = 0, relent = 0;
45*c65d76edSSimon Glass 	Elf64_Rela *rel = 0;
46*c65d76edSSimon Glass 	unsigned long *addr;
47*c65d76edSSimon Glass 	int i;
48*c65d76edSSimon Glass 
49*c65d76edSSimon Glass 	for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
50*c65d76edSSimon Glass 		switch (dyn[i].d_tag) {
51*c65d76edSSimon Glass 		case DT_RELA:
52*c65d76edSSimon Glass 			rel = (Elf64_Rela *)((ulong)dyn[i].d_un.d_ptr + ldbase);
53*c65d76edSSimon Glass 			break;
54*c65d76edSSimon Glass 		case DT_RELASZ:
55*c65d76edSSimon Glass 			relsz = dyn[i].d_un.d_val;
56*c65d76edSSimon Glass 			break;
57*c65d76edSSimon Glass 		case DT_RELAENT:
58*c65d76edSSimon Glass 			relent = dyn[i].d_un.d_val;
59*c65d76edSSimon Glass 			break;
60*c65d76edSSimon Glass 		default:
61*c65d76edSSimon Glass 			break;
62*c65d76edSSimon Glass 		}
63*c65d76edSSimon Glass 	}
64*c65d76edSSimon Glass 
65*c65d76edSSimon Glass 	if (!rel && relent == 0)
66*c65d76edSSimon Glass 		return EFI_SUCCESS;
67*c65d76edSSimon Glass 
68*c65d76edSSimon Glass 	if (!rel || relent == 0)
69*c65d76edSSimon Glass 		return EFI_LOAD_ERROR;
70*c65d76edSSimon Glass 
71*c65d76edSSimon Glass 	while (relsz > 0) {
72*c65d76edSSimon Glass 		/* apply the relocs */
73*c65d76edSSimon Glass 		switch (ELF64_R_TYPE(rel->r_info)) {
74*c65d76edSSimon Glass 		case R_AARCH64_NONE:
75*c65d76edSSimon Glass 			break;
76*c65d76edSSimon Glass 		case R_AARCH64_RELATIVE:
77*c65d76edSSimon Glass 			addr = (ulong *)(ldbase + rel->r_offset);
78*c65d76edSSimon Glass 			*addr = ldbase + rel->r_addend;
79*c65d76edSSimon Glass 			break;
80*c65d76edSSimon Glass 		default:
81*c65d76edSSimon Glass 			break;
82*c65d76edSSimon Glass 		}
83*c65d76edSSimon Glass 		rel = (Elf64_Rela *)((char *)rel + relent);
84*c65d76edSSimon Glass 		relsz -= relent;
85*c65d76edSSimon Glass 	}
86*c65d76edSSimon Glass 	return EFI_SUCCESS;
87*c65d76edSSimon Glass }
88