Branch data Line data Source code
1 : : /* SPARC specific symbolic name handling. 2 : : Copyright (C) 2002, 2003, 2005, 2007, 2008 Red Hat, Inc. 3 : : This file is part of elfutils. 4 : : Written by Jakub Jelinek <jakub@redhat.com>, 2002. 5 : : 6 : : This file is free software; you can redistribute it and/or modify 7 : : it under the terms of either 8 : : 9 : : * the GNU Lesser General Public License as published by the Free 10 : : Software Foundation; either version 3 of the License, or (at 11 : : your option) any later version 12 : : 13 : : or 14 : : 15 : : * the GNU General Public License as published by the Free 16 : : Software Foundation; either version 2 of the License, or (at 17 : : your option) any later version 18 : : 19 : : or both in parallel, as here. 20 : : 21 : : elfutils is distributed in the hope that it will be useful, but 22 : : WITHOUT ANY WARRANTY; without even the implied warranty of 23 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 : : General Public License for more details. 25 : : 26 : : You should have received copies of the GNU General Public License and 27 : : the GNU Lesser General Public License along with this program. If 28 : : not, see <http://www.gnu.org/licenses/>. */ 29 : : 30 : : #ifdef HAVE_CONFIG_H 31 : : # include <config.h> 32 : : #endif 33 : : 34 : : #include <elf.h> 35 : : #include <stddef.h> 36 : : 37 : : #define BACKEND sparc_ 38 : : #include "libebl_CPU.h" 39 : : 40 : : /* Check for the simple reloc types. */ 41 : : Elf_Type 42 : 24 : sparc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, 43 : : int *addsub __attribute__ ((unused))) 44 : : { 45 [ - + ]: 24 : switch (type) 46 : : { 47 : : case R_SPARC_8: 48 : : return ELF_T_BYTE; 49 : : case R_SPARC_16: 50 : : case R_SPARC_UA16: 51 : : return ELF_T_HALF; 52 : : case R_SPARC_32: 53 : : case R_SPARC_UA32: 54 : : return ELF_T_WORD; 55 : : case R_SPARC_64: 56 : : case R_SPARC_UA64: 57 : : return ELF_T_XWORD; 58 : : default: 59 : : return ELF_T_NUM; 60 : : } 61 : : } 62 : : 63 : : /* Check whether machine flags are valid. */ 64 : : bool 65 : 2 : sparc_machine_flag_check (GElf_Word flags) 66 : : { 67 : 2 : return ((flags &~ (EF_SPARCV9_MM 68 : : | EF_SPARC_LEDATA 69 : : | EF_SPARC_32PLUS 70 : : | EF_SPARC_SUN_US1 71 : 2 : | EF_SPARC_SUN_US3)) == 0); 72 : : } 73 : : 74 : : bool 75 : 2 : sparc_check_special_section (Ebl *ebl, 76 : : int ndx __attribute__ ((unused)), 77 : : const GElf_Shdr *shdr, 78 : : const char *sname __attribute__ ((unused))) 79 : : { 80 [ + - ]: 2 : if ((shdr->sh_flags & (SHF_WRITE | SHF_EXECINSTR)) 81 : : == (SHF_WRITE | SHF_EXECINSTR)) 82 : : { 83 : : /* This is ordinarily flagged, but is valid for a PLT on SPARC. 84 : : 85 : : Look for the SHT_DYNAMIC section and the DT_PLTGOT tag in it. 86 : : Its d_ptr should match the .plt section's sh_addr. */ 87 : : 88 : : Elf_Scn *scn = NULL; 89 [ + - ]: 42 : while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 90 : : { 91 : 42 : GElf_Shdr scn_shdr; 92 [ + - ]: 42 : if (likely (gelf_getshdr (scn, &scn_shdr) != NULL) 93 [ + + ]: 42 : && scn_shdr.sh_type == SHT_DYNAMIC 94 [ + - ]: 2 : && scn_shdr.sh_entsize != 0) 95 : : { 96 : 2 : Elf_Data *data = elf_getdata (scn, NULL); 97 [ + - ]: 2 : if (data != NULL) 98 [ + - ]: 22 : for (size_t i = 0; i < data->d_size / scn_shdr.sh_entsize; ++i) 99 : : { 100 : 22 : GElf_Dyn dyn; 101 [ + - ]: 22 : if (unlikely (gelf_getdyn (data, i, &dyn) == NULL)) 102 : : break; 103 [ + + ]: 22 : if (dyn.d_tag == DT_PLTGOT) 104 : 2 : return dyn.d_un.d_ptr == shdr->sh_addr; 105 : : } 106 : 0 : break; 107 : : } 108 : : } 109 : : } 110 : : 111 : : return false; 112 : : } 113 : : 114 : : const char * 115 : 0 : sparc_symbol_type_name (int type, 116 : : char *buf __attribute__ ((unused)), 117 : : size_t len __attribute__ ((unused))) 118 : : { 119 [ # # ]: 0 : switch (type) 120 : : { 121 : : case STT_SPARC_REGISTER: 122 : : return "SPARC_REGISTER"; 123 : : } 124 : 0 : return NULL; 125 : : } 126 : : 127 : : const char * 128 : 0 : sparc_dynamic_tag_name (int64_t tag, 129 : : char *buf __attribute__ ((unused)), 130 : : size_t len __attribute__ ((unused))) 131 : : { 132 [ # # ]: 0 : switch (tag) 133 : : { 134 : : case DT_SPARC_REGISTER: 135 : : return "SPARC_REGISTER"; 136 : : } 137 : 0 : return NULL; 138 : : } 139 : : 140 : : bool 141 : 52 : sparc_dynamic_tag_check (int64_t tag) 142 : : { 143 [ + - ]: 52 : switch (tag) 144 : : { 145 : : case DT_SPARC_REGISTER: 146 : : return true; 147 : : } 148 : 52 : return false; 149 : : }