Branch data Line data Source code
1 : : /* LoongArch specific symbolic name handling. 2 : : Copyright (C) 2022 Hengqi Chen 3 : : This file is part of elfutils. 4 : : 5 : : This file is free software; you can redistribute it and/or modify 6 : : it under the terms of either 7 : : 8 : : * the GNU Lesser General Public License as published by the Free 9 : : Software Foundation; either version 3 of the License, or (at 10 : : your option) any later version 11 : : 12 : : or 13 : : 14 : : * the GNU General Public License as published by the Free 15 : : Software Foundation; either version 2 of the License, or (at 16 : : your option) any later version 17 : : 18 : : or both in parallel, as here. 19 : : 20 : : elfutils is distributed in the hope that it will be useful, but 21 : : WITHOUT ANY WARRANTY; without even the implied warranty of 22 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 : : General Public License for more details. 24 : : 25 : : You should have received copies of the GNU General Public License and 26 : : the GNU Lesser General Public License along with this program. If 27 : : not, see <http://www.gnu.org/licenses/>. */ 28 : : 29 : : #ifdef HAVE_CONFIG_H 30 : : # include <config.h> 31 : : #endif 32 : : 33 : : #include <assert.h> 34 : : #include <elf.h> 35 : : #include <stddef.h> 36 : : #include <string.h> 37 : : 38 : : #define BACKEND loongarch_ 39 : : #include "libebl_CPU.h" 40 : : 41 : : 42 : : /* Check for the simple reloc types. */ 43 : : Elf_Type 44 : 0 : loongarch_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, 45 : : int *addsub) 46 : : { 47 [ # # # # : 0 : switch (type) # # # # # ] 48 : : { 49 : : case R_LARCH_32: 50 : : return ELF_T_WORD; 51 : 0 : case R_LARCH_64: 52 : 0 : return ELF_T_XWORD; 53 : 0 : case R_LARCH_ADD16: 54 : 0 : *addsub = 1; 55 : 0 : return ELF_T_HALF; 56 : 0 : case R_LARCH_ADD32: 57 : 0 : *addsub = 1; 58 : 0 : return ELF_T_WORD; 59 : 0 : case R_LARCH_ADD64: 60 : 0 : *addsub = 1; 61 : 0 : return ELF_T_XWORD; 62 : 0 : case R_LARCH_SUB16: 63 : 0 : *addsub = -1; 64 : 0 : return ELF_T_HALF; 65 : 0 : case R_LARCH_SUB32: 66 : 0 : *addsub = -1; 67 : 0 : return ELF_T_WORD; 68 : 0 : case R_LARCH_SUB64: 69 : 0 : *addsub = -1; 70 : 0 : return ELF_T_XWORD; 71 : 0 : default: 72 : 0 : return ELF_T_NUM; 73 : : } 74 : : } 75 : : 76 : : bool 77 : 0 : loongarch_machine_flag_check (GElf_Word flags) 78 : : { 79 : 0 : return ((flags &~ (EF_LARCH_ABI_MODIFIER_MASK 80 : 0 : | EF_LARCH_OBJABI_V1)) == 0); 81 : : } 82 : : 83 : : /* Check whether given symbol's st_value and st_size are OK despite failing 84 : : normal checks. */ 85 : : bool 86 : 0 : loongarch_check_special_symbol (Elf *elf, const GElf_Sym *sym, 87 : : const char *name, const GElf_Shdr *destshdr) 88 : : { 89 [ # # ]: 0 : if (name != NULL 90 [ # # ]: 0 : && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) 91 : : { 92 : 0 : size_t shstrndx; 93 [ # # ]: 0 : if (elf_getshdrstrndx (elf, &shstrndx) != 0) 94 : 0 : return false; 95 : 0 : const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name); 96 [ # # ]: 0 : if (sname != NULL 97 [ # # # # ]: 0 : && (strcmp (sname, ".got") == 0 || strcmp (sname, ".got.plt") == 0)) 98 : : { 99 : : Elf_Scn *scn = NULL; 100 [ # # ]: 0 : while ((scn = elf_nextscn (elf, scn)) != NULL) 101 : : { 102 : 0 : GElf_Shdr shdr_mem; 103 : 0 : GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 104 [ # # ]: 0 : if (shdr != NULL) 105 : : { 106 : 0 : sname = elf_strptr (elf, shstrndx, shdr->sh_name); 107 [ # # # # ]: 0 : if (sname != NULL && strcmp (sname, ".got") == 0) 108 : 0 : return (sym->st_value >= shdr->sh_addr 109 [ # # # # ]: 0 : && sym->st_value < shdr->sh_addr + shdr->sh_size); 110 : : } 111 : : } 112 : : } 113 : : } 114 : : 115 : : return false; 116 : : }