Branch data Line data Source code
1 : : /* Alpha specific symbolic name handling. 2 : : Copyright (C) 2002-2011 Red Hat, Inc. 3 : : This file is part of elfutils. 4 : : Written by Ulrich Drepper <drepper@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 : : #include <string.h> 37 : : 38 : : #define BACKEND alpha_ 39 : : #include "libebl_CPU.h" 40 : : 41 : : 42 : : const char * 43 : 0 : alpha_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)), 44 : : size_t len __attribute__ ((unused))) 45 : : { 46 [ # # ]: 0 : switch (tag) 47 : : { 48 : : case DT_ALPHA_PLTRO: 49 : : return "ALPHA_PLTRO"; 50 : : default: 51 : 0 : break; 52 : : } 53 : 0 : return NULL; 54 : : } 55 : : 56 : : bool 57 : 0 : alpha_dynamic_tag_check (int64_t tag) 58 : : { 59 : 0 : return tag == DT_ALPHA_PLTRO; 60 : : } 61 : : 62 : : /* Check for the simple reloc types. */ 63 : : Elf_Type 64 : 0 : alpha_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type, 65 : : int *addsub __attribute__ ((unused))) 66 : : { 67 [ # # # ]: 0 : switch (type) 68 : : { 69 : : case R_ALPHA_REFLONG: 70 : : return ELF_T_WORD; 71 : 0 : case R_ALPHA_REFQUAD: 72 : 0 : return ELF_T_XWORD; 73 : 0 : default: 74 : 0 : return ELF_T_NUM; 75 : : } 76 : : } 77 : : 78 : : 79 : : /* Check whether SHF_MASKPROC flags are valid. */ 80 : : bool 81 : 0 : alpha_machine_section_flag_check (GElf_Xword sh_flags) 82 : : { 83 : 0 : return (sh_flags &~ (SHF_ALPHA_GPREL)) == 0; 84 : : } 85 : : 86 : : bool 87 : 0 : alpha_check_special_section (Ebl *ebl, 88 : : int ndx __attribute__ ((unused)), 89 : : const GElf_Shdr *shdr, 90 : : const char *sname __attribute__ ((unused))) 91 : : { 92 : 0 : if ((shdr->sh_flags 93 [ # # ]: 0 : & (SHF_WRITE | SHF_EXECINSTR)) == (SHF_WRITE | SHF_EXECINSTR) 94 [ # # ]: 0 : && shdr->sh_addr != 0) 95 : : { 96 : : /* This is ordinarily flagged, but is valid for an old-style PLT. 97 : : 98 : : Look for the SHT_DYNAMIC section and the DT_PLTGOT tag in it. 99 : : Its d_ptr should match the .plt section's sh_addr. */ 100 : : 101 : : Elf_Scn *scn = NULL; 102 [ # # ]: 0 : while ((scn = elf_nextscn (ebl->elf, scn)) != NULL) 103 : : { 104 : 0 : GElf_Shdr scn_shdr; 105 [ # # ]: 0 : if (likely (gelf_getshdr (scn, &scn_shdr) != NULL) 106 [ # # ]: 0 : && scn_shdr.sh_type == SHT_DYNAMIC 107 [ # # ]: 0 : && scn_shdr.sh_entsize != 0) 108 : : { 109 : 0 : GElf_Addr pltgot = 0; 110 : 0 : Elf_Data *data = elf_getdata (scn, NULL); 111 [ # # ]: 0 : if (data != NULL) 112 [ # # ]: 0 : for (size_t i = 0; i < data->d_size / scn_shdr.sh_entsize; ++i) 113 : : { 114 : 0 : GElf_Dyn dyn; 115 [ # # ]: 0 : if (unlikely (gelf_getdyn (data, i, &dyn) == NULL)) 116 : : break; 117 [ # # ]: 0 : if (dyn.d_tag == DT_PLTGOT) 118 : 0 : pltgot = dyn.d_un.d_ptr; 119 [ # # # # ]: 0 : else if (dyn.d_tag == DT_ALPHA_PLTRO && dyn.d_un.d_val != 0) 120 : 0 : return false; /* This PLT should not be writable. */ 121 : : } 122 : 0 : return pltgot == shdr->sh_addr; 123 : : } 124 : : } 125 : : } 126 : : 127 : : return false; 128 : : } 129 : : 130 : : /* Check whether given symbol's st_value and st_size are OK despite failing 131 : : normal checks. */ 132 : : bool 133 : 0 : alpha_check_special_symbol (Elf *elf __attribute__ ((unused)), 134 : : const GElf_Sym *sym __attribute__ ((unused)), 135 : : const char *name, 136 : : const GElf_Shdr *destshdr __attribute__ ((unused))) 137 : : { 138 [ # # ]: 0 : if (name == NULL) 139 : : return false; 140 : : 141 [ # # ]: 0 : if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) 142 : : /* On Alpha any place in the section is valid. */ 143 : 0 : return true; 144 : : 145 : : return false; 146 : : } 147 : : 148 : : /* Check whether only valid bits are set on the st_other symbol flag. 149 : : Standard ST_VISIBILITY have already been masked off. */ 150 : : bool 151 : 0 : alpha_check_st_other_bits (unsigned char st_other) 152 : : { 153 : 0 : return ((((st_other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_NOPV) 154 : 0 : || ((st_other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_STD_GPLOAD)) 155 [ # # # # ]: 0 : && (st_other &~ STO_ALPHA_STD_GPLOAD) == 0); 156 : : }