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