1 /* Common code for ebl reloc functions. 2 Copyright (C) 2005, 2006 Red Hat, Inc. 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 #include "libebl_CPU.h" 30 #include <assert.h> 31 32 #define R_TYPE(name) PASTE (RELOC_PREFIX, name) 33 #define PASTE(a, b) PASTE_1 (a, b) 34 #define PASTE_1(a, b) a##b 35 #define R_NAME(name) R_NAME_1 (RELOC_PREFIX, name) 36 #define R_NAME_1(prefix, type) R_NAME_2 (prefix, type) 37 #define R_NAME_2(prefix, type) #prefix #type 38 39 #define RELOC_TYPES STRINGIFIED_PASTE (BACKEND, reloc.def) 40 #define STRINGIFIED_PASTE(a, b) STRINGIFY (PASTE (a, b)) 41 #define STRINGIFY(x) STRINGIFY_1 (x) 42 #define STRINGIFY_1(x) #x 43 44 /* Provide a table of reloc type names, in a PIC-friendly fashion. */ 45 46 static const struct EBLHOOK(reloc_nametable) 47 { 48 char zero; 49 #define RELOC_TYPE(type, uses) \ 50 char name_##type[sizeof R_NAME (type)]; 51 #include RELOC_TYPES 52 #undef RELOC_TYPE 53 } EBLHOOK(reloc_nametable) = 54 { 55 '\0', 56 #define RELOC_TYPE(type, uses) R_NAME (type), 57 #include RELOC_TYPES 58 #undef RELOC_TYPE 59 }; 60 #define reloc_namestr (&EBLHOOK(reloc_nametable).zero) 61 62 static const uint_fast16_t EBLHOOK(reloc_nameidx)[] = 63 { 64 #define RELOC_TYPE(type, uses) \ 65 [R_TYPE (type)] = offsetof (struct EBLHOOK(reloc_nametable), name_##type), 66 #include RELOC_TYPES 67 #undef RELOC_TYPE 68 }; 69 #define nreloc \ 70 ((int) (sizeof EBLHOOK(reloc_nameidx) / sizeof EBLHOOK(reloc_nameidx)[0])) 71 72 #define REL (1 << (ET_REL - 1)) 73 #define EXEC (1 << (ET_EXEC - 1)) 74 #define DYN (1 << (ET_DYN - 1)) 75 static const uint8_t EBLHOOK(reloc_valid)[] = 76 { 77 #define RELOC_TYPE(type, uses) [R_TYPE (type)] = uses, 78 #include RELOC_TYPES 79 #undef RELOC_TYPE 80 }; 81 #undef REL 82 #undef EXEC 83 #undef DYN 84 85 const char * 86 EBLHOOK(reloc_type_name) (int reloc, 87 char *buf __attribute__ ((unused)), 88 size_t len __attribute__ ((unused))) 89 { 90 #ifdef RELOC_TYPE_ID 91 reloc = RELOC_TYPE_ID (reloc); 92 #endif 93 94 if (reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0) 95 return &reloc_namestr[EBLHOOK(reloc_nameidx)[reloc]]; 96 return NULL; 97 } 98 99 bool 100 EBLHOOK(reloc_type_check) (int reloc) 101 { 102 #ifdef RELOC_TYPE_ID 103 reloc = RELOC_TYPE_ID (reloc); 104 #endif 105 106 return reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0; 107 } 108 109 bool 110 EBLHOOK(reloc_valid_use) (Elf *elf, int reloc) 111 { 112 uint8_t uses; 113 114 GElf_Ehdr ehdr_mem; 115 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 116 assert (ehdr != NULL); 117 uint8_t type = ehdr->e_type; 118 119 #ifdef RELOC_TYPE_ID 120 reloc = RELOC_TYPE_ID (reloc); 121 #endif 122 123 uses = EBLHOOK(reloc_valid)[reloc]; 124 return type > ET_NONE && type < ET_CORE && (uses & (1 << (type - 1))); 125 } 126 127 128 bool 129 EBLHOOK(copy_reloc_p) (int reloc) 130 { 131 return reloc == R_TYPE (COPY); 132 } 133 134 bool 135 EBLHOOK(none_reloc_p) (int reloc) 136 { 137 return reloc == R_TYPE (NONE); 138 } 139 140 #ifndef NO_RELATIVE_RELOC 141 bool 142 EBLHOOK(relative_reloc_p) (int reloc) 143 { 144 return reloc == R_TYPE (RELATIVE); 145 } 146 #endif 147 148 static void 149 EBLHOOK(init_reloc) (Ebl *ebl) 150 { 151 ebl->reloc_type_name = EBLHOOK(reloc_type_name); 152 ebl->reloc_type_check = EBLHOOK(reloc_type_check); 153 ebl->reloc_valid_use = EBLHOOK(reloc_valid_use); 154 ebl->copy_reloc_p = EBLHOOK(copy_reloc_p); 155 ebl->none_reloc_p = EBLHOOK(none_reloc_p); 156 #ifndef NO_RELATIVE_RELOC 157 ebl->relative_reloc_p = EBLHOOK(relative_reloc_p); 158 #endif 159 } 160