11.2Sjmcneill/* $NetBSD: reloc_aarch64.c,v 1.2 2018/08/20 09:50:18 jmcneill Exp $ */ 21.1Sjmcneill 31.1Sjmcneill/* reloc_aarch64.c - position independent x86 ELF shared object relocator 41.1Sjmcneill Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org> 51.1Sjmcneill Copyright (C) 1999 Hewlett-Packard Co. 61.1Sjmcneill Contributed by David Mosberger <davidm@hpl.hp.com>. 71.1Sjmcneill 81.1Sjmcneill All rights reserved. 91.1Sjmcneill 101.1Sjmcneill Redistribution and use in source and binary forms, with or without 111.1Sjmcneill modification, are permitted provided that the following conditions 121.1Sjmcneill are met: 131.1Sjmcneill 141.1Sjmcneill * Redistributions of source code must retain the above copyright 151.1Sjmcneill notice, this list of conditions and the following disclaimer. 161.1Sjmcneill * Redistributions in binary form must reproduce the above 171.1Sjmcneill copyright notice, this list of conditions and the following 181.1Sjmcneill disclaimer in the documentation and/or other materials 191.1Sjmcneill provided with the distribution. 201.1Sjmcneill * Neither the name of Hewlett-Packard Co. nor the names of its 211.1Sjmcneill contributors may be used to endorse or promote products derived 221.1Sjmcneill from this software without specific prior written permission. 231.1Sjmcneill 241.1Sjmcneill THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 251.1Sjmcneill CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 261.1Sjmcneill INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 271.1Sjmcneill MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 281.1Sjmcneill DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 291.1Sjmcneill BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 301.1Sjmcneill OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 311.1Sjmcneill PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 321.1Sjmcneill PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 331.1Sjmcneill THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 341.1Sjmcneill TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 351.1Sjmcneill THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 361.1Sjmcneill SUCH DAMAGE. 371.1Sjmcneill*/ 381.1Sjmcneill 391.1Sjmcneill#include <efi.h> 401.1Sjmcneill#include <efilib.h> 411.1Sjmcneill 421.2Sjmcneill#ifdef __NetBSD__ 431.2Sjmcneill#include <sys/types.h> 441.2Sjmcneill#include <sys/exec_elf.h> 451.2Sjmcneill#else 461.1Sjmcneill#include <elf.h> 471.2Sjmcneill#endif 481.2Sjmcneill 491.2SjmcneillEFI_STATUS _relocate (long, Elf64_Dyn *, EFI_HANDLE, EFI_SYSTEM_TABLE *); 501.1Sjmcneill 511.1SjmcneillEFI_STATUS _relocate (long ldbase, Elf64_Dyn *dyn, 521.1Sjmcneill EFI_HANDLE image EFI_UNUSED, 531.1Sjmcneill EFI_SYSTEM_TABLE *systab EFI_UNUSED) 541.1Sjmcneill{ 551.1Sjmcneill long relsz = 0, relent = 0; 561.1Sjmcneill Elf64_Rela *rel = 0; 571.1Sjmcneill unsigned long *addr; 581.1Sjmcneill int i; 591.1Sjmcneill 601.1Sjmcneill for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { 611.1Sjmcneill switch (dyn[i].d_tag) { 621.1Sjmcneill case DT_RELA: 631.1Sjmcneill rel = (Elf64_Rela*) 641.1Sjmcneill ((unsigned long)dyn[i].d_un.d_ptr 651.1Sjmcneill + ldbase); 661.1Sjmcneill break; 671.1Sjmcneill 681.1Sjmcneill case DT_RELASZ: 691.1Sjmcneill relsz = dyn[i].d_un.d_val; 701.1Sjmcneill break; 711.1Sjmcneill 721.1Sjmcneill case DT_RELAENT: 731.1Sjmcneill relent = dyn[i].d_un.d_val; 741.1Sjmcneill break; 751.1Sjmcneill 761.1Sjmcneill default: 771.1Sjmcneill break; 781.1Sjmcneill } 791.1Sjmcneill } 801.1Sjmcneill 811.1Sjmcneill if (!rel && relent == 0) 821.1Sjmcneill return EFI_SUCCESS; 831.1Sjmcneill 841.1Sjmcneill if (!rel || relent == 0) 851.1Sjmcneill return EFI_LOAD_ERROR; 861.1Sjmcneill 871.1Sjmcneill while (relsz > 0) { 881.1Sjmcneill /* apply the relocs */ 891.1Sjmcneill switch (ELF64_R_TYPE (rel->r_info)) { 901.1Sjmcneill case R_AARCH64_NONE: 911.1Sjmcneill break; 921.1Sjmcneill 931.1Sjmcneill case R_AARCH64_RELATIVE: 941.1Sjmcneill addr = (unsigned long *) 951.1Sjmcneill (ldbase + rel->r_offset); 961.1Sjmcneill *addr = ldbase + rel->r_addend; 971.1Sjmcneill break; 981.1Sjmcneill 991.1Sjmcneill default: 1001.1Sjmcneill break; 1011.1Sjmcneill } 1021.1Sjmcneill rel = (Elf64_Rela*) ((char *) rel + relent); 1031.1Sjmcneill relsz -= relent; 1041.1Sjmcneill } 1051.1Sjmcneill return EFI_SUCCESS; 1061.1Sjmcneill} 107