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