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