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
_relocate(long ldbase,Elf64_Dyn * dyn,EFI_HANDLE image EFI_UNUSED,EFI_SYSTEM_TABLE * systab EFI_UNUSED)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