1 1.1 skrll /* 32-bit ELF support for S+core. 2 1.1.1.12 christos Copyright (C) 2006-2026 Free Software Foundation, Inc. 3 1.1 skrll Contributed by 4 1.1.1.2 christos Brain.lin (brain.lin (at) sunplusct.com) 5 1.1 skrll Mei Ligang (ligang (at) sunnorth.com.cn) 6 1.1 skrll Pei-Lin Tsai (pltsai (at) sunplus.com) 7 1.1 skrll 8 1.1 skrll This file is part of BFD, the Binary File Descriptor library. 9 1.1 skrll 10 1.1 skrll This program is free software; you can redistribute it and/or modify 11 1.1 skrll it under the terms of the GNU General Public License as published by 12 1.1 skrll the Free Software Foundation; either version 3 of the License, or 13 1.1 skrll (at your option) any later version. 14 1.1 skrll 15 1.1 skrll This program is distributed in the hope that it will be useful, 16 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of 17 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 1.1 skrll GNU General Public License for more details. 19 1.1 skrll 20 1.1 skrll You should have received a copy of the GNU General Public License 21 1.1 skrll along with this program; if not, write to the Free Software 22 1.1 skrll Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 23 1.1 skrll MA 02110-1301, USA. */ 24 1.1 skrll 25 1.1 skrll #include "sysdep.h" 26 1.1 skrll #include "bfd.h" 27 1.1 skrll #include "libbfd.h" 28 1.1 skrll #include "libiberty.h" 29 1.1 skrll #include "elf-bfd.h" 30 1.1 skrll #include "elf/score.h" 31 1.1 skrll #include "elf/common.h" 32 1.1 skrll #include "elf/internal.h" 33 1.1 skrll #include "hashtab.h" 34 1.1.1.2 christos #include "elf32-score.h" 35 1.1 skrll 36 1.1 skrll 37 1.1.1.2 christos int score3 = 0; 38 1.1.1.2 christos int score7 = 1; 39 1.1 skrll 40 1.1 skrll /* The SCORE ELF linker needs additional information for each symbol in 41 1.1 skrll the global hash table. */ 42 1.1 skrll struct score_elf_link_hash_entry 43 1.1 skrll { 44 1.1 skrll struct elf_link_hash_entry root; 45 1.1 skrll 46 1.1 skrll /* Number of R_SCORE_ABS32, R_SCORE_REL32 relocs against this symbol. */ 47 1.1 skrll unsigned int possibly_dynamic_relocs; 48 1.1 skrll 49 1.1 skrll /* If the R_SCORE_ABS32, R_SCORE_REL32 reloc is against a readonly section. */ 50 1.1.1.9 christos bool readonly_reloc; 51 1.1 skrll 52 1.1 skrll /* We must not create a stub for a symbol that has relocations related to 53 1.1 skrll taking the function's address, i.e. any but R_SCORE_CALL15 ones. */ 54 1.1.1.9 christos bool no_fn_stub; 55 1.1 skrll 56 1.1 skrll /* Are we forced local? This will only be set if we have converted 57 1.1 skrll the initial global GOT entry to a local GOT entry. */ 58 1.1.1.9 christos bool forced_local; 59 1.1 skrll }; 60 1.1 skrll 61 1.1 skrll /* Traverse a score ELF linker hash table. */ 62 1.1 skrll #define score_elf_link_hash_traverse(table, func, info) \ 63 1.1.1.9 christos (elf_link_hash_traverse \ 64 1.1.1.9 christos ((table), \ 65 1.1.1.9 christos (bool (*) (struct elf_link_hash_entry *, void *)) (func), \ 66 1.1 skrll (info))) 67 1.1 skrll 68 1.1 skrll /* This structure is used to hold .got entries while estimating got sizes. */ 69 1.1 skrll struct score_got_entry 70 1.1 skrll { 71 1.1 skrll /* The input bfd in which the symbol is defined. */ 72 1.1 skrll bfd *abfd; 73 1.1 skrll /* The index of the symbol, as stored in the relocation r_info, if 74 1.1 skrll we have a local symbol; -1 otherwise. */ 75 1.1 skrll long symndx; 76 1.1 skrll union 77 1.1 skrll { 78 1.1 skrll /* If abfd == NULL, an address that must be stored in the got. */ 79 1.1 skrll bfd_vma address; 80 1.1 skrll /* If abfd != NULL && symndx != -1, the addend of the relocation 81 1.1 skrll that should be added to the symbol value. */ 82 1.1 skrll bfd_vma addend; 83 1.1 skrll /* If abfd != NULL && symndx == -1, the hash table entry 84 1.1 skrll corresponding to a global symbol in the got (or, local, if 85 1.1 skrll h->forced_local). */ 86 1.1 skrll struct score_elf_link_hash_entry *h; 87 1.1 skrll } d; 88 1.1 skrll 89 1.1 skrll /* The offset from the beginning of the .got section to the entry 90 1.1 skrll corresponding to this symbol+addend. If it's a global symbol 91 1.1 skrll whose offset is yet to be decided, it's going to be -1. */ 92 1.1 skrll long gotidx; 93 1.1 skrll }; 94 1.1 skrll 95 1.1 skrll /* This structure is passed to score_elf_sort_hash_table_f when sorting 96 1.1 skrll the dynamic symbols. */ 97 1.1 skrll 98 1.1 skrll struct score_elf_hash_sort_data 99 1.1 skrll { 100 1.1 skrll /* The symbol in the global GOT with the lowest dynamic symbol table index. */ 101 1.1 skrll struct elf_link_hash_entry *low; 102 1.1 skrll /* The least dynamic symbol table index corresponding to a symbol with a GOT entry. */ 103 1.1 skrll long min_got_dynindx; 104 1.1 skrll /* The greatest dynamic symbol table index corresponding to a symbol 105 1.1 skrll with a GOT entry that is not referenced (e.g., a dynamic symbol 106 1.1 skrll with dynamic relocations pointing to it from non-primary GOTs). */ 107 1.1 skrll long max_unref_got_dynindx; 108 1.1 skrll /* The greatest dynamic symbol table index not corresponding to a 109 1.1 skrll symbol without a GOT entry. */ 110 1.1 skrll long max_non_got_dynindx; 111 1.1 skrll }; 112 1.1 skrll 113 1.1 skrll struct score_got_info 114 1.1 skrll { 115 1.1 skrll /* The global symbol in the GOT with the lowest index in the dynamic 116 1.1 skrll symbol table. */ 117 1.1 skrll struct elf_link_hash_entry *global_gotsym; 118 1.1 skrll /* The number of global .got entries. */ 119 1.1 skrll unsigned int global_gotno; 120 1.1 skrll /* The number of local .got entries. */ 121 1.1 skrll unsigned int local_gotno; 122 1.1 skrll /* The number of local .got entries we have used. */ 123 1.1 skrll unsigned int assigned_gotno; 124 1.1 skrll /* A hash table holding members of the got. */ 125 1.1 skrll struct htab *got_entries; 126 1.1 skrll /* In multi-got links, a pointer to the next got (err, rather, most 127 1.1 skrll of the time, it points to the previous got). */ 128 1.1 skrll struct score_got_info *next; 129 1.1 skrll }; 130 1.1 skrll 131 1.1 skrll /* A structure used to count GOT entries, for GOT entry or ELF symbol table traversal. */ 132 1.1 skrll struct _score_elf_section_data 133 1.1 skrll { 134 1.1 skrll struct bfd_elf_section_data elf; 135 1.1 skrll union 136 1.1 skrll { 137 1.1 skrll struct score_got_info *got_info; 138 1.1 skrll bfd_byte *tdata; 139 1.1.1.12 christos } u; 140 1.1.1.12 christos bfd_byte *hi16_rel_addr; 141 1.1 skrll }; 142 1.1 skrll 143 1.1 skrll #define score_elf_section_data(sec) \ 144 1.1 skrll ((struct _score_elf_section_data *) elf_section_data (sec)) 145 1.1 skrll 146 1.1 skrll /* The size of a symbol-table entry. */ 147 1.1 skrll #define SCORE_ELF_SYM_SIZE(abfd) \ 148 1.1 skrll (get_elf_backend_data (abfd)->s->sizeof_sym) 149 1.1 skrll 150 1.1 skrll /* In case we're on a 32-bit machine, construct a 64-bit "-1" value 151 1.1 skrll from smaller values. Start with zero, widen, *then* decrement. */ 152 1.1 skrll #define MINUS_ONE (((bfd_vma)0) - 1) 153 1.1 skrll #define MINUS_TWO (((bfd_vma)0) - 2) 154 1.1 skrll 155 1.1 skrll #define PDR_SIZE 32 156 1.1 skrll 157 1.1 skrll 158 1.1 skrll /* The number of local .got entries we reserve. */ 159 1.1 skrll #define SCORE_RESERVED_GOTNO (2) 160 1.1 skrll #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" 161 1.1 skrll 162 1.1 skrll /* The offset of $gp from the beginning of the .got section. */ 163 1.1 skrll #define ELF_SCORE_GP_OFFSET(abfd) (0x3ff0) 164 1.1 skrll /* The maximum size of the GOT for it to be addressable using 15-bit offsets from $gp. */ 165 1.1 skrll #define SCORE_ELF_GOT_MAX_SIZE(abfd) (ELF_SCORE_GP_OFFSET(abfd) + 0x3fff) 166 1.1 skrll 167 1.1 skrll #define SCORE_ELF_STUB_SECTION_NAME (".SCORE.stub") 168 1.1 skrll #define SCORE_FUNCTION_STUB_SIZE (16) 169 1.1 skrll 170 1.1.1.2 christos #define STUB_LW 0xc3bcc010 /* lw r29, [r28, -0x3ff0] */ 171 1.1 skrll #define STUB_MOVE 0x8363bc56 /* mv r27, r3 */ 172 1.1 skrll #define STUB_LI16 0x87548000 /* ori r26, .dynsym_index */ 173 1.1 skrll #define STUB_BRL 0x801dbc09 /* brl r29 */ 174 1.1 skrll 175 1.1 skrll #define SCORE_ELF_GOT_SIZE(abfd) \ 176 1.1 skrll (get_elf_backend_data (abfd)->s->arch_size / 8) 177 1.1 skrll 178 1.1 skrll #define SCORE_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \ 179 1.1.1.6 christos (_bfd_elf_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val)) 180 1.1 skrll 181 1.1 skrll /* The size of an external dynamic table entry. */ 182 1.1 skrll #define SCORE_ELF_DYN_SIZE(abfd) \ 183 1.1 skrll (get_elf_backend_data (abfd)->s->sizeof_dyn) 184 1.1 skrll 185 1.1 skrll /* The size of an external REL relocation. */ 186 1.1 skrll #define SCORE_ELF_REL_SIZE(abfd) \ 187 1.1 skrll (get_elf_backend_data (abfd)->s->sizeof_rel) 188 1.1 skrll 189 1.1 skrll /* The default alignment for sections, as a power of two. */ 190 1.1 skrll #define SCORE_ELF_LOG_FILE_ALIGN(abfd)\ 191 1.1 skrll (get_elf_backend_data (abfd)->s->log_file_align) 192 1.1 skrll 193 1.1 skrll /* This will be used when we sort the dynamic relocation records. */ 194 1.1 skrll static bfd *reldyn_sorting_bfd; 195 1.1 skrll 196 1.1 skrll /* SCORE ELF uses two common sections. One is the usual one, and the 197 1.1 skrll other is for small objects. All the small objects are kept 198 1.1 skrll together, and then referenced via the gp pointer, which yields 199 1.1 skrll faster assembler code. This is what we use for the small common 200 1.1 skrll section. This approach is copied from ecoff.c. */ 201 1.1 skrll static asection score_elf_scom_section; 202 1.1.1.9 christos static const asymbol score_elf_scom_symbol = 203 1.1.1.9 christos GLOBAL_SYM_INIT (".scommon", &score_elf_scom_section); 204 1.1.1.9 christos static asection score_elf_scom_section = 205 1.1.1.9 christos BFD_FAKE_SECTION (score_elf_scom_section, &score_elf_scom_symbol, 206 1.1.1.9 christos ".scommon", 0, SEC_IS_COMMON | SEC_SMALL_DATA); 207 1.1 skrll 208 1.1.1.2 christos static bfd_vma 209 1.1.1.2 christos score_bfd_get_16 (bfd *abfd, const void *data) 210 1.1.1.2 christos { 211 1.1.1.2 christos return bfd_get_16 (abfd, data); 212 1.1.1.2 christos } 213 1.1.1.2 christos 214 1.1.1.2 christos static bfd_vma 215 1.1.1.2 christos score3_bfd_getl32 (const void *p) 216 1.1.1.2 christos { 217 1.1.1.2 christos const bfd_byte *addr = p; 218 1.1.1.2 christos unsigned long v; 219 1.1.1.2 christos 220 1.1.1.2 christos v = (unsigned long) addr[2]; 221 1.1.1.2 christos v |= (unsigned long) addr[3] << 8; 222 1.1.1.2 christos v |= (unsigned long) addr[0] << 16; 223 1.1.1.2 christos v |= (unsigned long) addr[1] << 24; 224 1.1.1.2 christos return v; 225 1.1.1.2 christos } 226 1.1.1.2 christos 227 1.1.1.2 christos static bfd_vma 228 1.1.1.2 christos score3_bfd_getl48 (const void *p) 229 1.1.1.2 christos { 230 1.1.1.2 christos const bfd_byte *addr = p; 231 1.1.1.9 christos uint64_t v; 232 1.1.1.2 christos 233 1.1.1.9 christos v = (uint64_t) addr[4]; 234 1.1.1.9 christos v |= (uint64_t) addr[5] << 8; 235 1.1.1.9 christos v |= (uint64_t) addr[2] << 16; 236 1.1.1.9 christos v |= (uint64_t) addr[3] << 24; 237 1.1.1.9 christos v |= (uint64_t) addr[0] << 32; 238 1.1.1.9 christos v |= (uint64_t) addr[1] << 40; 239 1.1.1.2 christos return v; 240 1.1.1.2 christos } 241 1.1.1.2 christos 242 1.1.1.2 christos static bfd_vma 243 1.1.1.2 christos score_bfd_get_32 (bfd *abfd, const void *data) 244 1.1.1.2 christos { 245 1.1.1.2 christos if (/* score3 && */ abfd->xvec->byteorder == BFD_ENDIAN_LITTLE) 246 1.1.1.2 christos return score3_bfd_getl32 (data); 247 1.1.1.2 christos else 248 1.1.1.2 christos return bfd_get_32 (abfd, data); 249 1.1.1.2 christos } 250 1.1.1.2 christos 251 1.1.1.2 christos static bfd_vma 252 1.1.1.2 christos score_bfd_get_48 (bfd *abfd, const void *p) 253 1.1.1.2 christos { 254 1.1.1.2 christos if (/* score3 && */ abfd->xvec->byteorder == BFD_ENDIAN_LITTLE) 255 1.1.1.2 christos return score3_bfd_getl48 (p); 256 1.1.1.2 christos else 257 1.1.1.2 christos return bfd_get_bits (p, 48, 1); 258 1.1.1.2 christos } 259 1.1.1.2 christos 260 1.1.1.2 christos static void 261 1.1.1.2 christos score_bfd_put_16 (bfd *abfd, bfd_vma addr, void *data) 262 1.1.1.2 christos { 263 1.1.1.2 christos return bfd_put_16 (abfd, addr, data); 264 1.1.1.2 christos } 265 1.1.1.2 christos 266 1.1.1.2 christos static void 267 1.1.1.2 christos score3_bfd_putl32 (bfd_vma data, void *p) 268 1.1.1.2 christos { 269 1.1.1.2 christos bfd_byte *addr = p; 270 1.1.1.2 christos addr[0] = (data >> 16) & 0xff; 271 1.1.1.2 christos addr[1] = (data >> 24) & 0xff; 272 1.1.1.2 christos addr[2] = data & 0xff; 273 1.1.1.2 christos addr[3] = (data >> 8) & 0xff; 274 1.1.1.2 christos } 275 1.1.1.2 christos 276 1.1.1.2 christos static void 277 1.1.1.2 christos score3_bfd_putl48 (bfd_vma data, void *p) 278 1.1.1.2 christos { 279 1.1.1.2 christos bfd_byte *addr = p; 280 1.1.1.2 christos addr[0] = (data >> 32) & 0xff; 281 1.1.1.2 christos addr[1] = (data >> 40) & 0xff; 282 1.1.1.2 christos addr[2] = (data >> 16) & 0xff; 283 1.1.1.2 christos addr[3] = (data >> 24) & 0xff; 284 1.1.1.2 christos addr[4] = data & 0xff; 285 1.1.1.2 christos addr[5] = (data >> 8) & 0xff; 286 1.1.1.2 christos } 287 1.1.1.2 christos 288 1.1.1.2 christos static void 289 1.1.1.2 christos score_bfd_put_32 (bfd *abfd, bfd_vma addr, void *data) 290 1.1.1.2 christos { 291 1.1.1.2 christos if (/* score3 && */ abfd->xvec->byteorder == BFD_ENDIAN_LITTLE) 292 1.1.1.2 christos return score3_bfd_putl32 (addr, data); 293 1.1.1.2 christos else 294 1.1.1.2 christos return bfd_put_32 (abfd, addr, data); 295 1.1.1.2 christos } 296 1.1.1.2 christos 297 1.1.1.2 christos static void 298 1.1.1.2 christos score_bfd_put_48 (bfd *abfd, bfd_vma val, void *p) 299 1.1.1.2 christos { 300 1.1.1.2 christos if (/* score3 && */ abfd->xvec->byteorder == BFD_ENDIAN_LITTLE) 301 1.1.1.2 christos return score3_bfd_putl48 (val, p); 302 1.1.1.2 christos else 303 1.1.1.2 christos return bfd_put_bits (val, p, 48, 1); 304 1.1.1.2 christos } 305 1.1.1.2 christos 306 1.1 skrll static bfd_reloc_status_type 307 1.1 skrll score_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, 308 1.1.1.6 christos arelent *reloc_entry, 309 1.1.1.6 christos asymbol *symbol ATTRIBUTE_UNUSED, 310 1.1.1.12 christos void *data, 311 1.1.1.12 christos asection *input_section, 312 1.1.1.6 christos bfd *output_bfd ATTRIBUTE_UNUSED, 313 1.1.1.6 christos char **error_message ATTRIBUTE_UNUSED) 314 1.1 skrll { 315 1.1.1.12 christos score_elf_section_data (input_section)->hi16_rel_addr 316 1.1.1.12 christos = (bfd_byte *) data + reloc_entry->address; 317 1.1 skrll return bfd_reloc_ok; 318 1.1 skrll } 319 1.1 skrll 320 1.1 skrll static bfd_reloc_status_type 321 1.1 skrll score_elf_lo16_reloc (bfd *abfd, 322 1.1.1.6 christos arelent *reloc_entry, 323 1.1.1.6 christos asymbol *symbol ATTRIBUTE_UNUSED, 324 1.1.1.6 christos void * data, 325 1.1.1.6 christos asection *input_section, 326 1.1.1.6 christos bfd *output_bfd ATTRIBUTE_UNUSED, 327 1.1.1.6 christos char **error_message ATTRIBUTE_UNUSED) 328 1.1 skrll { 329 1.1 skrll bfd_vma addend = 0, offset = 0; 330 1.1 skrll unsigned long val; 331 1.1 skrll unsigned long hi16_offset, hi16_value, uvalue; 332 1.1.1.12 christos bfd_byte *hi16_rel_addr; 333 1.1 skrll 334 1.1.1.12 christos hi16_rel_addr = score_elf_section_data (input_section)->hi16_rel_addr; 335 1.1.1.12 christos hi16_value = hi16_rel_addr ? score_bfd_get_32 (abfd, hi16_rel_addr) : 0; 336 1.1 skrll hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1; 337 1.1.1.2 christos addend = score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); 338 1.1 skrll offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1; 339 1.1 skrll val = reloc_entry->addend; 340 1.1 skrll if (reloc_entry->address > input_section->size) 341 1.1 skrll return bfd_reloc_outofrange; 342 1.1 skrll uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val; 343 1.1.1.12 christos if (hi16_rel_addr) 344 1.1.1.12 christos { 345 1.1.1.12 christos hi16_offset = (uvalue >> 16) << 1; 346 1.1.1.12 christos hi16_value = ((hi16_value & ~0x37fff) 347 1.1.1.12 christos | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000)); 348 1.1.1.12 christos score_bfd_put_32 (abfd, hi16_value, hi16_rel_addr); 349 1.1.1.12 christos } 350 1.1 skrll offset = (uvalue & 0xffff) << 1; 351 1.1 skrll addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000); 352 1.1.1.2 christos score_bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address); 353 1.1 skrll return bfd_reloc_ok; 354 1.1 skrll } 355 1.1 skrll 356 1.1 skrll /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a 357 1.1 skrll dangerous relocation. */ 358 1.1 skrll 359 1.1.1.9 christos static bool 360 1.1 skrll score_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp) 361 1.1 skrll { 362 1.1 skrll unsigned int count; 363 1.1 skrll asymbol **sym; 364 1.1 skrll unsigned int i; 365 1.1 skrll 366 1.1 skrll /* If we've already figured out what GP will be, just return it. */ 367 1.1 skrll *pgp = _bfd_get_gp_value (output_bfd); 368 1.1 skrll if (*pgp) 369 1.1.1.9 christos return true; 370 1.1 skrll 371 1.1 skrll count = bfd_get_symcount (output_bfd); 372 1.1 skrll sym = bfd_get_outsymbols (output_bfd); 373 1.1 skrll 374 1.1 skrll /* The linker script will have created a symbol named `_gp' with the 375 1.1 skrll appropriate value. */ 376 1.1 skrll if (sym == NULL) 377 1.1 skrll i = count; 378 1.1 skrll else 379 1.1 skrll { 380 1.1 skrll for (i = 0; i < count; i++, sym++) 381 1.1.1.6 christos { 382 1.1.1.6 christos const char *name; 383 1.1 skrll 384 1.1.1.6 christos name = bfd_asymbol_name (*sym); 385 1.1.1.6 christos if (*name == '_' && strcmp (name, "_gp") == 0) 386 1.1.1.6 christos { 387 1.1.1.6 christos *pgp = bfd_asymbol_value (*sym); 388 1.1.1.6 christos _bfd_set_gp_value (output_bfd, *pgp); 389 1.1.1.6 christos break; 390 1.1.1.6 christos } 391 1.1.1.6 christos } 392 1.1 skrll } 393 1.1 skrll 394 1.1 skrll if (i >= count) 395 1.1 skrll { 396 1.1 skrll /* Only get the error once. */ 397 1.1 skrll *pgp = 4; 398 1.1 skrll _bfd_set_gp_value (output_bfd, *pgp); 399 1.1.1.9 christos return false; 400 1.1 skrll } 401 1.1 skrll 402 1.1.1.9 christos return true; 403 1.1 skrll } 404 1.1 skrll 405 1.1 skrll /* We have to figure out the gp value, so that we can adjust the 406 1.1 skrll symbol value correctly. We look up the symbol _gp in the output 407 1.1 skrll BFD. If we can't find it, we're stuck. We cache it in the ELF 408 1.1 skrll target data. We don't need to adjust the symbol value for an 409 1.1 skrll external symbol if we are producing relocatable output. */ 410 1.1 skrll static bfd_reloc_status_type 411 1.1 skrll score_elf_final_gp (bfd *output_bfd, 412 1.1.1.6 christos asymbol *symbol, 413 1.1.1.9 christos bool relocatable, 414 1.1.1.6 christos char **error_message, 415 1.1.1.6 christos bfd_vma *pgp) 416 1.1 skrll { 417 1.1 skrll if (bfd_is_und_section (symbol->section) 418 1.1 skrll && ! relocatable) 419 1.1 skrll { 420 1.1 skrll *pgp = 0; 421 1.1 skrll return bfd_reloc_undefined; 422 1.1 skrll } 423 1.1 skrll 424 1.1 skrll *pgp = _bfd_get_gp_value (output_bfd); 425 1.1 skrll if (*pgp == 0 426 1.1 skrll && (! relocatable 427 1.1.1.6 christos || (symbol->flags & BSF_SECTION_SYM) != 0)) 428 1.1 skrll { 429 1.1 skrll if (relocatable) 430 1.1.1.6 christos { 431 1.1.1.6 christos /* Make up a value. */ 432 1.1.1.6 christos *pgp = symbol->section->output_section->vma + 0x4000; 433 1.1.1.6 christos _bfd_set_gp_value (output_bfd, *pgp); 434 1.1.1.6 christos } 435 1.1 skrll else if (!score_elf_assign_gp (output_bfd, pgp)) 436 1.1.1.6 christos { 437 1.1.1.6 christos *error_message = 438 1.1.1.6 christos (char *) _("GP relative relocation when _gp not defined"); 439 1.1.1.6 christos return bfd_reloc_dangerous; 440 1.1.1.6 christos } 441 1.1 skrll } 442 1.1 skrll 443 1.1 skrll return bfd_reloc_ok; 444 1.1 skrll } 445 1.1 skrll 446 1.1 skrll static bfd_reloc_status_type 447 1.1 skrll score_elf_gprel15_with_gp (bfd *abfd, 448 1.1.1.6 christos arelent *reloc_entry, 449 1.1.1.6 christos asection *input_section, 450 1.1.1.9 christos bool relocateable, 451 1.1.1.6 christos void * data, 452 1.1.1.6 christos bfd_vma gp ATTRIBUTE_UNUSED) 453 1.1 skrll { 454 1.1 skrll unsigned long insn; 455 1.1 skrll 456 1.1 skrll if (reloc_entry->address > input_section->size) 457 1.1 skrll return bfd_reloc_outofrange; 458 1.1 skrll 459 1.1.1.2 christos insn = score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); 460 1.1 skrll if (((reloc_entry->addend & 0xffffc000) != 0) 461 1.1 skrll && ((reloc_entry->addend & 0xffffc000) != 0xffffc000)) 462 1.1 skrll return bfd_reloc_overflow; 463 1.1 skrll 464 1.1 skrll insn = (insn & ~0x7fff) | (reloc_entry->addend & 0x7fff); 465 1.1.1.2 christos score_bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address); 466 1.1 skrll if (relocateable) 467 1.1 skrll reloc_entry->address += input_section->output_offset; 468 1.1 skrll 469 1.1 skrll return bfd_reloc_ok; 470 1.1 skrll } 471 1.1 skrll 472 1.1 skrll static bfd_reloc_status_type 473 1.1 skrll gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry, 474 1.1.1.9 christos asection *input_section, bool relocatable, 475 1.1.1.6 christos void *data, bfd_vma gp) 476 1.1 skrll { 477 1.1 skrll bfd_vma relocation; 478 1.1 skrll bfd_vma val; 479 1.1 skrll 480 1.1 skrll if (bfd_is_com_section (symbol->section)) 481 1.1 skrll relocation = 0; 482 1.1 skrll else 483 1.1 skrll relocation = symbol->value; 484 1.1 skrll 485 1.1 skrll relocation += symbol->section->output_section->vma; 486 1.1 skrll relocation += symbol->section->output_offset; 487 1.1 skrll 488 1.1 skrll if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) 489 1.1 skrll return bfd_reloc_outofrange; 490 1.1 skrll 491 1.1 skrll /* Set val to the offset into the section or symbol. */ 492 1.1 skrll val = reloc_entry->addend; 493 1.1 skrll 494 1.1 skrll if (reloc_entry->howto->partial_inplace) 495 1.1.1.2 christos val += score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); 496 1.1 skrll 497 1.1 skrll /* Adjust val for the final section location and GP value. If we 498 1.1 skrll are producing relocatable output, we don't want to do this for 499 1.1 skrll an external symbol. */ 500 1.1 skrll if (! relocatable 501 1.1 skrll || (symbol->flags & BSF_SECTION_SYM) != 0) 502 1.1 skrll val += relocation - gp; 503 1.1 skrll 504 1.1 skrll if (reloc_entry->howto->partial_inplace) 505 1.1.1.2 christos score_bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address); 506 1.1 skrll else 507 1.1 skrll reloc_entry->addend = val; 508 1.1 skrll 509 1.1 skrll if (relocatable) 510 1.1 skrll reloc_entry->address += input_section->output_offset; 511 1.1 skrll 512 1.1 skrll return bfd_reloc_ok; 513 1.1 skrll } 514 1.1 skrll 515 1.1 skrll static bfd_reloc_status_type 516 1.1 skrll score_elf_gprel15_reloc (bfd *abfd, 517 1.1.1.6 christos arelent *reloc_entry, 518 1.1.1.6 christos asymbol *symbol, 519 1.1.1.6 christos void * data, 520 1.1.1.6 christos asection *input_section, 521 1.1.1.6 christos bfd *output_bfd, 522 1.1.1.6 christos char **error_message) 523 1.1 skrll { 524 1.1.1.9 christos bool relocateable; 525 1.1 skrll bfd_reloc_status_type ret; 526 1.1 skrll bfd_vma gp; 527 1.1 skrll 528 1.1.1.2 christos if (output_bfd != NULL 529 1.1 skrll && (symbol->flags & BSF_SECTION_SYM) == 0 && reloc_entry->addend == 0) 530 1.1 skrll { 531 1.1 skrll reloc_entry->address += input_section->output_offset; 532 1.1 skrll return bfd_reloc_ok; 533 1.1 skrll } 534 1.1.1.2 christos if (output_bfd != NULL) 535 1.1.1.9 christos relocateable = true; 536 1.1 skrll else 537 1.1 skrll { 538 1.1.1.9 christos relocateable = false; 539 1.1 skrll output_bfd = symbol->section->output_section->owner; 540 1.1 skrll } 541 1.1 skrll 542 1.1 skrll ret = score_elf_final_gp (output_bfd, symbol, relocateable, error_message, &gp); 543 1.1 skrll if (ret != bfd_reloc_ok) 544 1.1 skrll return ret; 545 1.1 skrll 546 1.1.1.9 christos return score_elf_gprel15_with_gp (abfd, reloc_entry, 547 1.1.1.9 christos input_section, relocateable, data, gp); 548 1.1 skrll } 549 1.1 skrll 550 1.1 skrll /* Do a R_SCORE_GPREL32 relocation. This is a 32 bit value which must 551 1.1 skrll become the offset from the gp register. */ 552 1.1 skrll 553 1.1 skrll static bfd_reloc_status_type 554 1.1 skrll score_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, 555 1.1.1.6 christos void *data, asection *input_section, bfd *output_bfd, 556 1.1.1.6 christos char **error_message) 557 1.1 skrll { 558 1.1.1.9 christos bool relocatable; 559 1.1 skrll bfd_reloc_status_type ret; 560 1.1 skrll bfd_vma gp; 561 1.1 skrll 562 1.1 skrll /* R_SCORE_GPREL32 relocations are defined for local symbols only. */ 563 1.1 skrll if (output_bfd != NULL 564 1.1 skrll && (symbol->flags & BSF_SECTION_SYM) == 0 565 1.1 skrll && (symbol->flags & BSF_LOCAL) != 0) 566 1.1 skrll { 567 1.1 skrll *error_message = (char *) 568 1.1.1.6 christos _("32bits gp relative relocation occurs for an external symbol"); 569 1.1 skrll return bfd_reloc_outofrange; 570 1.1 skrll } 571 1.1 skrll 572 1.1 skrll if (output_bfd != NULL) 573 1.1.1.9 christos relocatable = true; 574 1.1 skrll else 575 1.1 skrll { 576 1.1.1.9 christos relocatable = false; 577 1.1 skrll output_bfd = symbol->section->output_section->owner; 578 1.1 skrll } 579 1.1 skrll 580 1.1 skrll ret = score_elf_final_gp (output_bfd, symbol, relocatable, error_message, &gp); 581 1.1 skrll if (ret != bfd_reloc_ok) 582 1.1 skrll return ret; 583 1.1 skrll 584 1.1.1.2 christos gp = 0; 585 1.1 skrll return gprel32_with_gp (abfd, symbol, reloc_entry, input_section, 586 1.1.1.6 christos relocatable, data, gp); 587 1.1 skrll } 588 1.1 skrll 589 1.1 skrll /* A howto special_function for R_SCORE_GOT15 relocations. This is just 590 1.1 skrll like any other 16-bit relocation when applied to global symbols, but is 591 1.1 skrll treated in the same as R_SCORE_HI16 when applied to local symbols. */ 592 1.1 skrll static bfd_reloc_status_type 593 1.1 skrll score_elf_got15_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, 594 1.1.1.6 christos void *data, asection *input_section, 595 1.1.1.6 christos bfd *output_bfd, char **error_message) 596 1.1 skrll { 597 1.1 skrll if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0 598 1.1.1.8 christos || bfd_is_und_section (bfd_asymbol_section (symbol)) 599 1.1.1.8 christos || bfd_is_com_section (bfd_asymbol_section (symbol))) 600 1.1 skrll /* The relocation is against a global symbol. */ 601 1.1 skrll return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, 602 1.1.1.6 christos input_section, output_bfd, 603 1.1.1.6 christos error_message); 604 1.1 skrll 605 1.1 skrll return score_elf_hi16_reloc (abfd, reloc_entry, symbol, data, 606 1.1.1.6 christos input_section, output_bfd, error_message); 607 1.1 skrll } 608 1.1 skrll 609 1.1 skrll static bfd_reloc_status_type 610 1.1 skrll score_elf_got_lo16_reloc (bfd *abfd, 611 1.1.1.6 christos arelent *reloc_entry, 612 1.1.1.6 christos asymbol *symbol ATTRIBUTE_UNUSED, 613 1.1.1.6 christos void * data, 614 1.1.1.6 christos asection *input_section, 615 1.1.1.6 christos bfd *output_bfd ATTRIBUTE_UNUSED, 616 1.1.1.6 christos char **error_message ATTRIBUTE_UNUSED) 617 1.1 skrll { 618 1.1 skrll bfd_vma addend = 0, offset = 0; 619 1.1 skrll signed long val; 620 1.1 skrll signed long hi16_offset, hi16_value, uvalue; 621 1.1.1.12 christos bfd_byte *hi16_rel_addr; 622 1.1 skrll 623 1.1.1.12 christos hi16_rel_addr = score_elf_section_data (input_section)->hi16_rel_addr; 624 1.1.1.12 christos hi16_value = hi16_rel_addr ? score_bfd_get_32 (abfd, hi16_rel_addr) : 0; 625 1.1 skrll hi16_offset = ((((hi16_value >> 16) & 0x3) << 15) | (hi16_value & 0x7fff)) >> 1; 626 1.1.1.2 christos addend = score_bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); 627 1.1 skrll offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1; 628 1.1 skrll val = reloc_entry->addend; 629 1.1 skrll if (reloc_entry->address > input_section->size) 630 1.1 skrll return bfd_reloc_outofrange; 631 1.1 skrll uvalue = ((hi16_offset << 16) | (offset & 0xffff)) + val; 632 1.1.1.12 christos if (hi16_rel_addr) 633 1.1.1.12 christos { 634 1.1.1.12 christos if ((uvalue > -0x8000) && (uvalue < 0x7fff)) 635 1.1.1.12 christos hi16_offset = 0; 636 1.1.1.12 christos else 637 1.1.1.12 christos hi16_offset = (uvalue >> 16) & 0x7fff; 638 1.1.1.12 christos hi16_value = ((hi16_value & ~0x37fff) 639 1.1.1.12 christos | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000)); 640 1.1.1.12 christos score_bfd_put_32 (abfd, hi16_value, hi16_rel_addr); 641 1.1.1.12 christos } 642 1.1 skrll offset = (uvalue & 0xffff) << 1; 643 1.1 skrll addend = (addend & ~0x37fff) | (offset & 0x7fff) | ((offset << 1) & 0x30000); 644 1.1.1.2 christos score_bfd_put_32 (abfd, addend, (bfd_byte *) data + reloc_entry->address); 645 1.1 skrll return bfd_reloc_ok; 646 1.1 skrll } 647 1.1 skrll 648 1.1 skrll static reloc_howto_type elf32_score_howto_table[] = 649 1.1 skrll { 650 1.1 skrll /* No relocation. */ 651 1.1.1.6 christos HOWTO (R_SCORE_NONE, /* type */ 652 1.1.1.6 christos 0, /* rightshift */ 653 1.1.1.9 christos 0, /* size */ 654 1.1.1.6 christos 0, /* bitsize */ 655 1.1.1.9 christos false, /* pc_relative */ 656 1.1.1.6 christos 0, /* bitpos */ 657 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 658 1.1.1.6 christos bfd_elf_generic_reloc, /* special_function */ 659 1.1.1.6 christos "R_SCORE_NONE", /* name */ 660 1.1.1.9 christos false, /* partial_inplace */ 661 1.1.1.6 christos 0, /* src_mask */ 662 1.1.1.6 christos 0, /* dst_mask */ 663 1.1.1.9 christos false), /* pcrel_offset */ 664 1.1 skrll 665 1.1 skrll /* R_SCORE_HI16 */ 666 1.1.1.6 christos HOWTO (R_SCORE_HI16, /* type */ 667 1.1.1.6 christos 0, /* rightshift */ 668 1.1.1.9 christos 4, /* size */ 669 1.1.1.6 christos 16, /* bitsize */ 670 1.1.1.9 christos false, /* pc_relative */ 671 1.1.1.6 christos 1, /* bitpos */ 672 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 673 1.1.1.6 christos score_elf_hi16_reloc, /* special_function */ 674 1.1.1.6 christos "R_SCORE_HI16", /* name */ 675 1.1.1.9 christos true, /* partial_inplace */ 676 1.1.1.6 christos 0x37fff, /* src_mask */ 677 1.1.1.6 christos 0x37fff, /* dst_mask */ 678 1.1.1.9 christos false), /* pcrel_offset */ 679 1.1 skrll 680 1.1 skrll /* R_SCORE_LO16 */ 681 1.1.1.6 christos HOWTO (R_SCORE_LO16, /* type */ 682 1.1.1.6 christos 0, /* rightshift */ 683 1.1.1.9 christos 4, /* size */ 684 1.1.1.6 christos 16, /* bitsize */ 685 1.1.1.9 christos false, /* pc_relative */ 686 1.1.1.6 christos 1, /* bitpos */ 687 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 688 1.1.1.6 christos score_elf_lo16_reloc, /* special_function */ 689 1.1.1.6 christos "R_SCORE_LO16", /* name */ 690 1.1.1.9 christos true, /* partial_inplace */ 691 1.1.1.6 christos 0x37fff, /* src_mask */ 692 1.1.1.6 christos 0x37fff, /* dst_mask */ 693 1.1.1.9 christos false), /* pcrel_offset */ 694 1.1 skrll 695 1.1.1.2 christos /* R_SCORE_BCMP */ 696 1.1.1.6 christos HOWTO (R_SCORE_BCMP, /* type */ 697 1.1.1.6 christos 1, /* rightshift */ 698 1.1.1.9 christos 4, /* size */ 699 1.1.1.6 christos 16, /* bitsize */ 700 1.1.1.9 christos true, /* pc_relative */ 701 1.1.1.6 christos 1, /* bitpos */ 702 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 703 1.1.1.6 christos bfd_elf_generic_reloc, /* special_function */ 704 1.1.1.6 christos "R_SCORE_BCMP", /* name */ 705 1.1.1.9 christos false, /* partial_inplace */ 706 1.1.1.6 christos 0x03e00381, /* src_mask */ 707 1.1.1.6 christos 0x03e00381, /* dst_mask */ 708 1.1.1.9 christos false), /* pcrel_offset */ 709 1.1 skrll 710 1.1 skrll /*R_SCORE_24 */ 711 1.1.1.6 christos HOWTO (R_SCORE_24, /* type */ 712 1.1.1.6 christos 1, /* rightshift */ 713 1.1.1.9 christos 4, /* size */ 714 1.1.1.6 christos 24, /* bitsize */ 715 1.1.1.9 christos false, /* pc_relative */ 716 1.1.1.6 christos 1, /* bitpos */ 717 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 718 1.1.1.6 christos bfd_elf_generic_reloc, /* special_function */ 719 1.1.1.6 christos "R_SCORE_24", /* name */ 720 1.1.1.9 christos false, /* partial_inplace */ 721 1.1.1.6 christos 0x3ff7fff, /* src_mask */ 722 1.1.1.6 christos 0x3ff7fff, /* dst_mask */ 723 1.1.1.9 christos false), /* pcrel_offset */ 724 1.1 skrll 725 1.1 skrll /*R_SCORE_PC19 */ 726 1.1.1.6 christos HOWTO (R_SCORE_PC19, /* type */ 727 1.1.1.6 christos 1, /* rightshift */ 728 1.1.1.9 christos 4, /* size */ 729 1.1.1.6 christos 19, /* bitsize */ 730 1.1.1.9 christos true, /* pc_relative */ 731 1.1.1.6 christos 1, /* bitpos */ 732 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 733 1.1.1.6 christos bfd_elf_generic_reloc, /* special_function */ 734 1.1.1.6 christos "R_SCORE_PC19", /* name */ 735 1.1.1.9 christos false, /* partial_inplace */ 736 1.1.1.6 christos 0x3ff03fe, /* src_mask */ 737 1.1.1.6 christos 0x3ff03fe, /* dst_mask */ 738 1.1.1.9 christos false), /* pcrel_offset */ 739 1.1 skrll 740 1.1 skrll /*R_SCORE16_11 */ 741 1.1.1.6 christos HOWTO (R_SCORE16_11, /* type */ 742 1.1.1.6 christos 1, /* rightshift */ 743 1.1.1.9 christos 2, /* size */ 744 1.1.1.6 christos 11, /* bitsize */ 745 1.1.1.9 christos false, /* pc_relative */ 746 1.1.1.6 christos 1, /* bitpos */ 747 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 748 1.1.1.6 christos bfd_elf_generic_reloc, /* special_function */ 749 1.1.1.6 christos "R_SCORE16_11", /* name */ 750 1.1.1.9 christos false, /* partial_inplace */ 751 1.1.1.6 christos 0x000000ffe, /* src_mask */ 752 1.1.1.6 christos 0x000000ffe, /* dst_mask */ 753 1.1.1.9 christos false), /* pcrel_offset */ 754 1.1 skrll 755 1.1 skrll /* R_SCORE16_PC8 */ 756 1.1.1.6 christos HOWTO (R_SCORE16_PC8, /* type */ 757 1.1.1.6 christos 1, /* rightshift */ 758 1.1.1.9 christos 2, /* size */ 759 1.1.1.6 christos 9, /* bitsize */ 760 1.1.1.9 christos true, /* pc_relative */ 761 1.1.1.6 christos 0, /* bitpos */ 762 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 763 1.1.1.6 christos bfd_elf_generic_reloc, /* special_function */ 764 1.1.1.6 christos "R_SCORE16_PC8", /* name */ 765 1.1.1.9 christos false, /* partial_inplace */ 766 1.1.1.6 christos 0x000001ff, /* src_mask */ 767 1.1.1.6 christos 0x000001ff, /* dst_mask */ 768 1.1.1.9 christos false), /* pcrel_offset */ 769 1.1 skrll 770 1.1 skrll /* 32 bit absolute */ 771 1.1.1.6 christos HOWTO (R_SCORE_ABS32, /* type 8 */ 772 1.1.1.6 christos 0, /* rightshift */ 773 1.1.1.9 christos 4, /* size */ 774 1.1.1.6 christos 32, /* bitsize */ 775 1.1.1.9 christos false, /* pc_relative */ 776 1.1.1.6 christos 0, /* bitpos */ 777 1.1.1.6 christos complain_overflow_bitfield, /* complain_on_overflow */ 778 1.1.1.6 christos bfd_elf_generic_reloc, /* special_function */ 779 1.1.1.6 christos "R_SCORE_ABS32", /* name */ 780 1.1.1.9 christos false, /* partial_inplace */ 781 1.1.1.6 christos 0xffffffff, /* src_mask */ 782 1.1.1.6 christos 0xffffffff, /* dst_mask */ 783 1.1.1.9 christos false), /* pcrel_offset */ 784 1.1 skrll 785 1.1 skrll /* 16 bit absolute */ 786 1.1.1.6 christos HOWTO (R_SCORE_ABS16, /* type 11 */ 787 1.1.1.6 christos 0, /* rightshift */ 788 1.1.1.9 christos 2, /* size */ 789 1.1.1.6 christos 16, /* bitsize */ 790 1.1.1.9 christos false, /* pc_relative */ 791 1.1.1.6 christos 0, /* bitpos */ 792 1.1.1.6 christos complain_overflow_bitfield, /* complain_on_overflow */ 793 1.1.1.6 christos bfd_elf_generic_reloc, /* special_function */ 794 1.1.1.6 christos "R_SCORE_ABS16", /* name */ 795 1.1.1.9 christos false, /* partial_inplace */ 796 1.1.1.6 christos 0x0000ffff, /* src_mask */ 797 1.1.1.6 christos 0x0000ffff, /* dst_mask */ 798 1.1.1.9 christos false), /* pcrel_offset */ 799 1.1 skrll 800 1.1 skrll /* R_SCORE_DUMMY2 */ 801 1.1.1.6 christos HOWTO (R_SCORE_DUMMY2, /* type */ 802 1.1.1.6 christos 0, /* rightshift */ 803 1.1.1.9 christos 4, /* size */ 804 1.1.1.6 christos 16, /* bitsize */ 805 1.1.1.9 christos false, /* pc_relative */ 806 1.1.1.6 christos 0, /* bitpos */ 807 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 808 1.1.1.6 christos bfd_elf_generic_reloc, /* special_function */ 809 1.1.1.6 christos "R_SCORE_DUMMY2", /* name */ 810 1.1.1.9 christos true, /* partial_inplace */ 811 1.1.1.6 christos 0x00007fff, /* src_mask */ 812 1.1.1.6 christos 0x00007fff, /* dst_mask */ 813 1.1.1.9 christos false), /* pcrel_offset */ 814 1.1 skrll 815 1.1 skrll /* R_SCORE_GP15 */ 816 1.1.1.6 christos HOWTO (R_SCORE_GP15, /* type */ 817 1.1.1.6 christos 0, /* rightshift */ 818 1.1.1.9 christos 4, /* size */ 819 1.1.1.6 christos 16, /* bitsize */ 820 1.1.1.9 christos false, /* pc_relative */ 821 1.1.1.6 christos 0, /* bitpos */ 822 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 823 1.1.1.6 christos score_elf_gprel15_reloc,/* special_function */ 824 1.1.1.6 christos "R_SCORE_GP15", /* name */ 825 1.1.1.9 christos true, /* partial_inplace */ 826 1.1.1.6 christos 0x00007fff, /* src_mask */ 827 1.1.1.6 christos 0x00007fff, /* dst_mask */ 828 1.1.1.9 christos false), /* pcrel_offset */ 829 1.1 skrll 830 1.1 skrll /* GNU extension to record C++ vtable hierarchy. */ 831 1.1 skrll HOWTO (R_SCORE_GNU_VTINHERIT, /* type */ 832 1.1.1.6 christos 0, /* rightshift */ 833 1.1.1.9 christos 4, /* size */ 834 1.1.1.6 christos 0, /* bitsize */ 835 1.1.1.9 christos false, /* pc_relative */ 836 1.1.1.6 christos 0, /* bitpos */ 837 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 838 1.1.1.6 christos NULL, /* special_function */ 839 1.1.1.6 christos "R_SCORE_GNU_VTINHERIT", /* name */ 840 1.1.1.9 christos false, /* partial_inplace */ 841 1.1.1.6 christos 0, /* src_mask */ 842 1.1.1.6 christos 0, /* dst_mask */ 843 1.1.1.9 christos false), /* pcrel_offset */ 844 1.1 skrll 845 1.1 skrll /* GNU extension to record C++ vtable member usage */ 846 1.1.1.6 christos HOWTO (R_SCORE_GNU_VTENTRY, /* type */ 847 1.1.1.6 christos 0, /* rightshift */ 848 1.1.1.9 christos 4, /* size */ 849 1.1.1.6 christos 0, /* bitsize */ 850 1.1.1.9 christos false, /* pc_relative */ 851 1.1.1.6 christos 0, /* bitpos */ 852 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 853 1.1.1.6 christos _bfd_elf_rel_vtable_reloc_fn, /* special_function */ 854 1.1.1.6 christos "R_SCORE_GNU_VTENTRY", /* name */ 855 1.1.1.9 christos false, /* partial_inplace */ 856 1.1.1.6 christos 0, /* src_mask */ 857 1.1.1.6 christos 0, /* dst_mask */ 858 1.1.1.9 christos false), /* pcrel_offset */ 859 1.1 skrll 860 1.1 skrll /* Reference to global offset table. */ 861 1.1.1.6 christos HOWTO (R_SCORE_GOT15, /* type */ 862 1.1.1.6 christos 0, /* rightshift */ 863 1.1.1.9 christos 4, /* size */ 864 1.1.1.6 christos 16, /* bitsize */ 865 1.1.1.9 christos false, /* pc_relative */ 866 1.1.1.6 christos 0, /* bitpos */ 867 1.1.1.6 christos complain_overflow_signed, /* complain_on_overflow */ 868 1.1.1.6 christos score_elf_got15_reloc, /* special_function */ 869 1.1.1.6 christos "R_SCORE_GOT15", /* name */ 870 1.1.1.9 christos true, /* partial_inplace */ 871 1.1.1.6 christos 0x00007fff, /* src_mask */ 872 1.1.1.6 christos 0x00007fff, /* dst_mask */ 873 1.1.1.9 christos false), /* pcrel_offset */ 874 1.1 skrll 875 1.1 skrll /* Low 16 bits of displacement in global offset table. */ 876 1.1.1.6 christos HOWTO (R_SCORE_GOT_LO16, /* type */ 877 1.1.1.6 christos 0, /* rightshift */ 878 1.1.1.9 christos 4, /* size */ 879 1.1.1.6 christos 16, /* bitsize */ 880 1.1.1.9 christos false, /* pc_relative */ 881 1.1.1.6 christos 1, /* bitpos */ 882 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 883 1.1.1.6 christos score_elf_got_lo16_reloc, /* special_function */ 884 1.1.1.6 christos "R_SCORE_GOT_LO16", /* name */ 885 1.1.1.9 christos true, /* partial_inplace */ 886 1.1.1.6 christos 0x37ffe, /* src_mask */ 887 1.1.1.6 christos 0x37ffe, /* dst_mask */ 888 1.1.1.9 christos false), /* pcrel_offset */ 889 1.1 skrll 890 1.1 skrll /* 15 bit call through global offset table. */ 891 1.1.1.6 christos HOWTO (R_SCORE_CALL15, /* type */ 892 1.1.1.6 christos 0, /* rightshift */ 893 1.1.1.9 christos 4, /* size */ 894 1.1.1.6 christos 16, /* bitsize */ 895 1.1.1.9 christos false, /* pc_relative */ 896 1.1.1.6 christos 0, /* bitpos */ 897 1.1.1.6 christos complain_overflow_signed, /* complain_on_overflow */ 898 1.1.1.6 christos bfd_elf_generic_reloc, /* special_function */ 899 1.1.1.6 christos "R_SCORE_CALL15", /* name */ 900 1.1.1.9 christos true, /* partial_inplace */ 901 1.1.1.6 christos 0x0000ffff, /* src_mask */ 902 1.1.1.6 christos 0x0000ffff, /* dst_mask */ 903 1.1.1.9 christos false), /* pcrel_offset */ 904 1.1 skrll 905 1.1 skrll /* 32 bit GP relative reference. */ 906 1.1.1.6 christos HOWTO (R_SCORE_GPREL32, /* type */ 907 1.1.1.6 christos 0, /* rightshift */ 908 1.1.1.9 christos 4, /* size */ 909 1.1.1.6 christos 32, /* bitsize */ 910 1.1.1.9 christos false, /* pc_relative */ 911 1.1.1.6 christos 0, /* bitpos */ 912 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 913 1.1.1.6 christos score_elf_gprel32_reloc, /* special_function */ 914 1.1.1.6 christos "R_SCORE_GPREL32", /* name */ 915 1.1.1.9 christos true, /* partial_inplace */ 916 1.1.1.6 christos 0xffffffff, /* src_mask */ 917 1.1.1.6 christos 0xffffffff, /* dst_mask */ 918 1.1.1.9 christos false), /* pcrel_offset */ 919 1.1 skrll 920 1.1 skrll /* 32 bit symbol relative relocation. */ 921 1.1.1.6 christos HOWTO (R_SCORE_REL32, /* type */ 922 1.1.1.6 christos 0, /* rightshift */ 923 1.1.1.9 christos 4, /* size */ 924 1.1.1.6 christos 32, /* bitsize */ 925 1.1.1.9 christos false, /* pc_relative */ 926 1.1.1.6 christos 0, /* bitpos */ 927 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 928 1.1.1.6 christos bfd_elf_generic_reloc, /* special_function */ 929 1.1.1.6 christos "R_SCORE_REL32", /* name */ 930 1.1.1.9 christos true, /* partial_inplace */ 931 1.1.1.6 christos 0xffffffff, /* src_mask */ 932 1.1.1.6 christos 0xffffffff, /* dst_mask */ 933 1.1.1.9 christos false), /* pcrel_offset */ 934 1.1 skrll 935 1.1 skrll /* R_SCORE_DUMMY_HI16 */ 936 1.1.1.6 christos HOWTO (R_SCORE_DUMMY_HI16, /* type */ 937 1.1.1.6 christos 0, /* rightshift */ 938 1.1.1.9 christos 4, /* size */ 939 1.1.1.6 christos 16, /* bitsize */ 940 1.1.1.9 christos false, /* pc_relative */ 941 1.1.1.6 christos 1, /* bitpos */ 942 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 943 1.1.1.6 christos score_elf_hi16_reloc, /* special_function */ 944 1.1.1.6 christos "R_SCORE_DUMMY_HI16", /* name */ 945 1.1.1.9 christos true, /* partial_inplace */ 946 1.1.1.6 christos 0x37fff, /* src_mask */ 947 1.1.1.6 christos 0x37fff, /* dst_mask */ 948 1.1.1.9 christos false), /* pcrel_offset */ 949 1.1.1.2 christos 950 1.1.1.2 christos /* R_SCORE_IMM30 */ 951 1.1.1.6 christos HOWTO (R_SCORE_IMM30, /* type */ 952 1.1.1.6 christos 2, /* rightshift */ 953 1.1.1.9 christos 4, /* size */ 954 1.1.1.6 christos 30, /* bitsize */ 955 1.1.1.9 christos false, /* pc_relative */ 956 1.1.1.6 christos 7, /* bitpos */ 957 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 958 1.1.1.6 christos bfd_elf_generic_reloc, /* special_function */ 959 1.1.1.6 christos "R_SCORE_IMM30", /* name */ 960 1.1.1.9 christos false, /* partial_inplace */ 961 1.1.1.6 christos 0x7f7fff7f80LL, /* src_mask */ 962 1.1.1.6 christos 0x7f7fff7f80LL, /* dst_mask */ 963 1.1.1.9 christos false), /* pcrel_offset */ 964 1.1.1.2 christos 965 1.1.1.2 christos /* R_SCORE_IMM32 */ 966 1.1.1.6 christos HOWTO (R_SCORE_IMM32, /* type */ 967 1.1.1.6 christos 0, /* rightshift */ 968 1.1.1.9 christos 4, /* size */ 969 1.1.1.6 christos 32, /* bitsize */ 970 1.1.1.9 christos false, /* pc_relative */ 971 1.1.1.6 christos 5, /* bitpos */ 972 1.1.1.6 christos complain_overflow_dont,/* complain_on_overflow */ 973 1.1.1.6 christos bfd_elf_generic_reloc, /* special_function */ 974 1.1.1.6 christos "R_SCORE_IMM32", /* name */ 975 1.1.1.9 christos false, /* partial_inplace */ 976 1.1.1.6 christos 0x7f7fff7fe0LL, /* src_mask */ 977 1.1.1.6 christos 0x7f7fff7fe0LL, /* dst_mask */ 978 1.1.1.9 christos false), /* pcrel_offset */ 979 1.1 skrll }; 980 1.1 skrll 981 1.1 skrll struct score_reloc_map 982 1.1 skrll { 983 1.1 skrll bfd_reloc_code_real_type bfd_reloc_val; 984 1.1 skrll unsigned char elf_reloc_val; 985 1.1 skrll }; 986 1.1 skrll 987 1.1 skrll static const struct score_reloc_map elf32_score_reloc_map[] = 988 1.1 skrll { 989 1.1.1.6 christos {BFD_RELOC_NONE, R_SCORE_NONE}, 990 1.1.1.6 christos {BFD_RELOC_HI16_S, R_SCORE_HI16}, 991 1.1.1.6 christos {BFD_RELOC_LO16, R_SCORE_LO16}, 992 1.1.1.6 christos {BFD_RELOC_SCORE_BCMP, R_SCORE_BCMP}, 993 1.1.1.6 christos {BFD_RELOC_SCORE_JMP, R_SCORE_24}, 994 1.1.1.6 christos {BFD_RELOC_SCORE_BRANCH, R_SCORE_PC19}, 995 1.1.1.6 christos {BFD_RELOC_SCORE16_JMP, R_SCORE16_11}, 996 1.1.1.6 christos {BFD_RELOC_SCORE16_BRANCH, R_SCORE16_PC8}, 997 1.1.1.6 christos {BFD_RELOC_32, R_SCORE_ABS32}, 998 1.1.1.6 christos {BFD_RELOC_16, R_SCORE_ABS16}, 999 1.1.1.6 christos {BFD_RELOC_SCORE_DUMMY2, R_SCORE_DUMMY2}, 1000 1.1.1.6 christos {BFD_RELOC_SCORE_GPREL15, R_SCORE_GP15}, 1001 1.1.1.6 christos {BFD_RELOC_VTABLE_INHERIT, R_SCORE_GNU_VTINHERIT}, 1002 1.1.1.6 christos {BFD_RELOC_VTABLE_ENTRY, R_SCORE_GNU_VTENTRY}, 1003 1.1.1.6 christos {BFD_RELOC_SCORE_GOT15, R_SCORE_GOT15}, 1004 1.1.1.6 christos {BFD_RELOC_SCORE_GOT_LO16, R_SCORE_GOT_LO16}, 1005 1.1.1.6 christos {BFD_RELOC_SCORE_CALL15, R_SCORE_CALL15}, 1006 1.1.1.6 christos {BFD_RELOC_GPREL32, R_SCORE_GPREL32}, 1007 1.1.1.6 christos {BFD_RELOC_32_PCREL, R_SCORE_REL32}, 1008 1.1.1.6 christos {BFD_RELOC_SCORE_DUMMY_HI16, R_SCORE_DUMMY_HI16}, 1009 1.1.1.6 christos {BFD_RELOC_SCORE_IMM30, R_SCORE_IMM30}, 1010 1.1.1.6 christos {BFD_RELOC_SCORE_IMM32, R_SCORE_IMM32}, 1011 1.1 skrll }; 1012 1.1 skrll 1013 1.1 skrll /* got_entries only match if they're identical, except for gotidx, so 1014 1.1 skrll use all fields to compute the hash, and compare the appropriate 1015 1.1 skrll union members. */ 1016 1.1 skrll static hashval_t 1017 1.1 skrll score_elf_got_entry_hash (const void *entry_) 1018 1.1 skrll { 1019 1.1 skrll const struct score_got_entry *entry = (struct score_got_entry *)entry_; 1020 1.1 skrll 1021 1.1 skrll return entry->symndx 1022 1.1 skrll + (!entry->abfd ? entry->d.address : entry->abfd->id); 1023 1.1 skrll } 1024 1.1 skrll 1025 1.1 skrll static int 1026 1.1 skrll score_elf_got_entry_eq (const void *entry1, const void *entry2) 1027 1.1 skrll { 1028 1.1 skrll const struct score_got_entry *e1 = (struct score_got_entry *)entry1; 1029 1.1 skrll const struct score_got_entry *e2 = (struct score_got_entry *)entry2; 1030 1.1 skrll 1031 1.1 skrll return e1->abfd == e2->abfd && e1->symndx == e2->symndx 1032 1.1 skrll && (! e1->abfd ? e1->d.address == e2->d.address 1033 1.1.1.6 christos : e1->symndx >= 0 ? e1->d.addend == e2->d.addend 1034 1.1.1.6 christos : e1->d.h == e2->d.h); 1035 1.1 skrll } 1036 1.1 skrll 1037 1.1 skrll /* If H needs a GOT entry, assign it the highest available dynamic 1038 1.1 skrll index. Otherwise, assign it the lowest available dynamic 1039 1.1 skrll index. */ 1040 1.1.1.9 christos static bool 1041 1.1 skrll score_elf_sort_hash_table_f (struct score_elf_link_hash_entry *h, void *data) 1042 1.1 skrll { 1043 1.1 skrll struct score_elf_hash_sort_data *hsd = data; 1044 1.1 skrll 1045 1.1 skrll /* Symbols without dynamic symbol table entries aren't interesting at all. */ 1046 1.1 skrll if (h->root.dynindx == -1) 1047 1.1.1.9 christos return true; 1048 1.1 skrll 1049 1.1 skrll /* Global symbols that need GOT entries that are not explicitly 1050 1.1 skrll referenced are marked with got offset 2. Those that are 1051 1.1 skrll referenced get a 1, and those that don't need GOT entries get 1052 1.1 skrll -1. */ 1053 1.1 skrll if (h->root.got.offset == 2) 1054 1.1 skrll { 1055 1.1 skrll if (hsd->max_unref_got_dynindx == hsd->min_got_dynindx) 1056 1.1.1.6 christos hsd->low = (struct elf_link_hash_entry *) h; 1057 1.1 skrll h->root.dynindx = hsd->max_unref_got_dynindx++; 1058 1.1 skrll } 1059 1.1 skrll else if (h->root.got.offset != 1) 1060 1.1 skrll h->root.dynindx = hsd->max_non_got_dynindx++; 1061 1.1 skrll else 1062 1.1 skrll { 1063 1.1 skrll h->root.dynindx = --hsd->min_got_dynindx; 1064 1.1 skrll hsd->low = (struct elf_link_hash_entry *) h; 1065 1.1 skrll } 1066 1.1 skrll 1067 1.1.1.9 christos return true; 1068 1.1 skrll } 1069 1.1 skrll 1070 1.1 skrll static asection * 1071 1.1.1.9 christos score_elf_got_section (bfd *abfd, bool maybe_excluded) 1072 1.1 skrll { 1073 1.1.1.3 christos asection *sgot = bfd_get_linker_section (abfd, ".got"); 1074 1.1 skrll 1075 1.1 skrll if (sgot == NULL || (! maybe_excluded && (sgot->flags & SEC_EXCLUDE) != 0)) 1076 1.1 skrll return NULL; 1077 1.1 skrll return sgot; 1078 1.1 skrll } 1079 1.1 skrll 1080 1.1 skrll /* Returns the GOT information associated with the link indicated by 1081 1.1 skrll INFO. If SGOTP is non-NULL, it is filled in with the GOT section. */ 1082 1.1 skrll static struct score_got_info * 1083 1.1 skrll score_elf_got_info (bfd *abfd, asection **sgotp) 1084 1.1 skrll { 1085 1.1 skrll asection *sgot; 1086 1.1 skrll struct score_got_info *g; 1087 1.1 skrll 1088 1.1.1.9 christos sgot = score_elf_got_section (abfd, true); 1089 1.1 skrll BFD_ASSERT (sgot != NULL); 1090 1.1 skrll BFD_ASSERT (elf_section_data (sgot) != NULL); 1091 1.1 skrll g = score_elf_section_data (sgot)->u.got_info; 1092 1.1 skrll BFD_ASSERT (g != NULL); 1093 1.1 skrll 1094 1.1 skrll if (sgotp) 1095 1.1 skrll *sgotp = sgot; 1096 1.1 skrll return g; 1097 1.1 skrll } 1098 1.1 skrll 1099 1.1 skrll /* Sort the dynamic symbol table so that symbols that need GOT entries 1100 1.1 skrll appear towards the end. This reduces the amount of GOT space 1101 1.1 skrll required. MAX_LOCAL is used to set the number of local symbols 1102 1.1 skrll known to be in the dynamic symbol table. During 1103 1.1.1.11 christos s3_bfd_score_elf_late_size_sections, this value is 1. Afterward, the 1104 1.1 skrll section symbols are added and the count is higher. */ 1105 1.1.1.9 christos static bool 1106 1.1 skrll score_elf_sort_hash_table (struct bfd_link_info *info, 1107 1.1.1.6 christos unsigned long max_local) 1108 1.1 skrll { 1109 1.1 skrll struct score_elf_hash_sort_data hsd; 1110 1.1 skrll struct score_got_info *g; 1111 1.1 skrll bfd *dynobj; 1112 1.1 skrll 1113 1.1 skrll dynobj = elf_hash_table (info)->dynobj; 1114 1.1 skrll 1115 1.1 skrll g = score_elf_got_info (dynobj, NULL); 1116 1.1 skrll 1117 1.1 skrll hsd.low = NULL; 1118 1.1 skrll hsd.max_unref_got_dynindx = 1119 1.1 skrll hsd.min_got_dynindx = elf_hash_table (info)->dynsymcount 1120 1.1 skrll /* In the multi-got case, assigned_gotno of the master got_info 1121 1.1 skrll indicate the number of entries that aren't referenced in the 1122 1.1 skrll primary GOT, but that must have entries because there are 1123 1.1 skrll dynamic relocations that reference it. Since they aren't 1124 1.1 skrll referenced, we move them to the end of the GOT, so that they 1125 1.1 skrll don't prevent other entries that are referenced from getting 1126 1.1 skrll too large offsets. */ 1127 1.1 skrll - (g->next ? g->assigned_gotno : 0); 1128 1.1 skrll hsd.max_non_got_dynindx = max_local; 1129 1.1.1.2 christos score_elf_link_hash_traverse (elf_hash_table (info), 1130 1.1.1.2 christos score_elf_sort_hash_table_f, 1131 1.1.1.2 christos &hsd); 1132 1.1 skrll 1133 1.1 skrll /* There should have been enough room in the symbol table to 1134 1.1 skrll accommodate both the GOT and non-GOT symbols. */ 1135 1.1 skrll BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx); 1136 1.1 skrll BFD_ASSERT ((unsigned long)hsd.max_unref_got_dynindx 1137 1.1.1.6 christos <= elf_hash_table (info)->dynsymcount); 1138 1.1 skrll 1139 1.1 skrll /* Now we know which dynamic symbol has the lowest dynamic symbol 1140 1.1 skrll table index in the GOT. */ 1141 1.1 skrll g->global_gotsym = hsd.low; 1142 1.1 skrll 1143 1.1.1.9 christos return true; 1144 1.1 skrll } 1145 1.1 skrll 1146 1.1 skrll /* Create an entry in an score ELF linker hash table. */ 1147 1.1 skrll 1148 1.1 skrll static struct bfd_hash_entry * 1149 1.1 skrll score_elf_link_hash_newfunc (struct bfd_hash_entry *entry, 1150 1.1.1.6 christos struct bfd_hash_table *table, 1151 1.1.1.6 christos const char *string) 1152 1.1 skrll { 1153 1.1.1.2 christos struct score_elf_link_hash_entry *ret = (struct score_elf_link_hash_entry *) entry; 1154 1.1 skrll 1155 1.1 skrll /* Allocate the structure if it has not already been allocated by a subclass. */ 1156 1.1 skrll if (ret == NULL) 1157 1.1 skrll ret = bfd_hash_allocate (table, sizeof (struct score_elf_link_hash_entry)); 1158 1.1 skrll if (ret == NULL) 1159 1.1.1.2 christos return (struct bfd_hash_entry *) ret; 1160 1.1 skrll 1161 1.1 skrll /* Call the allocation method of the superclass. */ 1162 1.1 skrll ret = ((struct score_elf_link_hash_entry *) 1163 1.1.1.6 christos _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); 1164 1.1 skrll 1165 1.1 skrll if (ret != NULL) 1166 1.1 skrll { 1167 1.1 skrll ret->possibly_dynamic_relocs = 0; 1168 1.1.1.9 christos ret->readonly_reloc = false; 1169 1.1.1.9 christos ret->no_fn_stub = false; 1170 1.1.1.9 christos ret->forced_local = false; 1171 1.1 skrll } 1172 1.1 skrll 1173 1.1.1.2 christos return (struct bfd_hash_entry *) ret; 1174 1.1 skrll } 1175 1.1 skrll 1176 1.1 skrll /* Returns the first relocation of type r_type found, beginning with 1177 1.1 skrll RELOCATION. RELEND is one-past-the-end of the relocation table. */ 1178 1.1 skrll static const Elf_Internal_Rela * 1179 1.1 skrll score_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type, 1180 1.1.1.6 christos const Elf_Internal_Rela *relocation, 1181 1.1.1.6 christos const Elf_Internal_Rela *relend) 1182 1.1 skrll { 1183 1.1 skrll while (relocation < relend) 1184 1.1 skrll { 1185 1.1 skrll if (ELF32_R_TYPE (relocation->r_info) == r_type) 1186 1.1.1.6 christos return relocation; 1187 1.1 skrll 1188 1.1 skrll ++relocation; 1189 1.1 skrll } 1190 1.1 skrll 1191 1.1 skrll /* We didn't find it. */ 1192 1.1 skrll bfd_set_error (bfd_error_bad_value); 1193 1.1 skrll return NULL; 1194 1.1 skrll } 1195 1.1 skrll 1196 1.1 skrll /* This function is called via qsort() to sort the dynamic relocation 1197 1.1 skrll entries by increasing r_symndx value. */ 1198 1.1 skrll static int 1199 1.1 skrll score_elf_sort_dynamic_relocs (const void *arg1, const void *arg2) 1200 1.1 skrll { 1201 1.1 skrll Elf_Internal_Rela int_reloc1; 1202 1.1 skrll Elf_Internal_Rela int_reloc2; 1203 1.1 skrll 1204 1.1 skrll bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg1, &int_reloc1); 1205 1.1 skrll bfd_elf32_swap_reloc_in (reldyn_sorting_bfd, arg2, &int_reloc2); 1206 1.1 skrll 1207 1.1 skrll return (ELF32_R_SYM (int_reloc1.r_info) - ELF32_R_SYM (int_reloc2.r_info)); 1208 1.1 skrll } 1209 1.1 skrll 1210 1.1 skrll /* Return whether a relocation is against a local symbol. */ 1211 1.1.1.9 christos static bool 1212 1.1 skrll score_elf_local_relocation_p (bfd *input_bfd, 1213 1.1.1.6 christos const Elf_Internal_Rela *relocation, 1214 1.1.1.6 christos asection **local_sections, 1215 1.1.1.9 christos bool check_forced) 1216 1.1 skrll { 1217 1.1 skrll unsigned long r_symndx; 1218 1.1 skrll Elf_Internal_Shdr *symtab_hdr; 1219 1.1 skrll struct score_elf_link_hash_entry *h; 1220 1.1 skrll size_t extsymoff; 1221 1.1 skrll 1222 1.1 skrll r_symndx = ELF32_R_SYM (relocation->r_info); 1223 1.1 skrll symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 1224 1.1.1.2 christos extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info; 1225 1.1 skrll 1226 1.1 skrll if (r_symndx < extsymoff) 1227 1.1.1.9 christos return true; 1228 1.1.1.2 christos if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL) 1229 1.1.1.9 christos return true; 1230 1.1 skrll 1231 1.1 skrll if (check_forced) 1232 1.1 skrll { 1233 1.1 skrll /* Look up the hash table to check whether the symbol was forced local. */ 1234 1.1 skrll h = (struct score_elf_link_hash_entry *) 1235 1.1.1.6 christos elf_sym_hashes (input_bfd) [r_symndx - extsymoff]; 1236 1.1 skrll /* Find the real hash-table entry for this symbol. */ 1237 1.1 skrll while (h->root.root.type == bfd_link_hash_indirect 1238 1.1.1.6 christos || h->root.root.type == bfd_link_hash_warning) 1239 1.1.1.6 christos h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link; 1240 1.1 skrll if (h->root.forced_local) 1241 1.1.1.9 christos return true; 1242 1.1 skrll } 1243 1.1 skrll 1244 1.1.1.9 christos return false; 1245 1.1 skrll } 1246 1.1 skrll 1247 1.1 skrll /* Returns the dynamic relocation section for DYNOBJ. */ 1248 1.1 skrll static asection * 1249 1.1.1.9 christos score_elf_rel_dyn_section (bfd *dynobj, bool create_p) 1250 1.1 skrll { 1251 1.1 skrll static const char dname[] = ".rel.dyn"; 1252 1.1 skrll asection *sreloc; 1253 1.1 skrll 1254 1.1.1.3 christos sreloc = bfd_get_linker_section (dynobj, dname); 1255 1.1 skrll if (sreloc == NULL && create_p) 1256 1.1 skrll { 1257 1.1.1.3 christos sreloc = bfd_make_section_anyway_with_flags (dynobj, dname, 1258 1.1.1.3 christos (SEC_ALLOC 1259 1.1.1.3 christos | SEC_LOAD 1260 1.1.1.3 christos | SEC_HAS_CONTENTS 1261 1.1.1.3 christos | SEC_IN_MEMORY 1262 1.1.1.3 christos | SEC_LINKER_CREATED 1263 1.1.1.3 christos | SEC_READONLY)); 1264 1.1 skrll if (sreloc == NULL 1265 1.1.1.8 christos || !bfd_set_section_alignment (sreloc, 1266 1.1.1.8 christos SCORE_ELF_LOG_FILE_ALIGN (dynobj))) 1267 1.1.1.6 christos return NULL; 1268 1.1 skrll } 1269 1.1.1.2 christos return sreloc; 1270 1.1 skrll } 1271 1.1 skrll 1272 1.1 skrll static void 1273 1.1 skrll score_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n) 1274 1.1 skrll { 1275 1.1 skrll asection *s; 1276 1.1 skrll 1277 1.1.1.9 christos s = score_elf_rel_dyn_section (abfd, false); 1278 1.1 skrll BFD_ASSERT (s != NULL); 1279 1.1 skrll 1280 1.1 skrll if (s->size == 0) 1281 1.1 skrll { 1282 1.1 skrll /* Make room for a null element. */ 1283 1.1 skrll s->size += SCORE_ELF_REL_SIZE (abfd); 1284 1.1 skrll ++s->reloc_count; 1285 1.1 skrll } 1286 1.1 skrll s->size += n * SCORE_ELF_REL_SIZE (abfd); 1287 1.1 skrll } 1288 1.1 skrll 1289 1.1 skrll /* Create a rel.dyn relocation for the dynamic linker to resolve. REL 1290 1.1 skrll is the original relocation, which is now being transformed into a 1291 1.1 skrll dynamic relocation. The ADDENDP is adjusted if necessary; the 1292 1.1 skrll caller should store the result in place of the original addend. */ 1293 1.1.1.9 christos static bool 1294 1.1 skrll score_elf_create_dynamic_relocation (bfd *output_bfd, 1295 1.1.1.6 christos struct bfd_link_info *info, 1296 1.1.1.6 christos const Elf_Internal_Rela *rel, 1297 1.1.1.6 christos struct score_elf_link_hash_entry *h, 1298 1.1.1.6 christos bfd_vma symbol, 1299 1.1.1.6 christos bfd_vma *addendp, asection *input_section) 1300 1.1 skrll { 1301 1.1.1.11 christos Elf_Internal_Rela outrel; 1302 1.1 skrll asection *sreloc; 1303 1.1 skrll bfd *dynobj; 1304 1.1 skrll int r_type; 1305 1.1 skrll long indx; 1306 1.1.1.9 christos bool defined_p; 1307 1.1 skrll 1308 1.1 skrll r_type = ELF32_R_TYPE (rel->r_info); 1309 1.1 skrll dynobj = elf_hash_table (info)->dynobj; 1310 1.1.1.9 christos sreloc = score_elf_rel_dyn_section (dynobj, false); 1311 1.1 skrll BFD_ASSERT (sreloc != NULL); 1312 1.1 skrll BFD_ASSERT (sreloc->contents != NULL); 1313 1.1 skrll BFD_ASSERT (sreloc->reloc_count * SCORE_ELF_REL_SIZE (output_bfd) < sreloc->size); 1314 1.1 skrll 1315 1.1.1.11 christos outrel.r_offset = 1316 1.1.1.11 christos _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); 1317 1.1 skrll 1318 1.1.1.11 christos if (outrel.r_offset == MINUS_ONE) 1319 1.1 skrll /* The relocation field has been deleted. */ 1320 1.1.1.9 christos return true; 1321 1.1 skrll 1322 1.1.1.11 christos if (outrel.r_offset == MINUS_TWO) 1323 1.1 skrll { 1324 1.1 skrll /* The relocation field has been converted into a relative value of 1325 1.1.1.6 christos some sort. Functions like _bfd_elf_write_section_eh_frame expect 1326 1.1.1.6 christos the field to be fully relocated, so add in the symbol's value. */ 1327 1.1 skrll *addendp += symbol; 1328 1.1.1.9 christos return true; 1329 1.1 skrll } 1330 1.1 skrll 1331 1.1 skrll /* We must now calculate the dynamic symbol table index to use 1332 1.1 skrll in the relocation. */ 1333 1.1 skrll if (h != NULL 1334 1.1 skrll && (! info->symbolic || !h->root.def_regular) 1335 1.1 skrll /* h->root.dynindx may be -1 if this symbol was marked to 1336 1.1.1.6 christos become local. */ 1337 1.1 skrll && h->root.dynindx != -1) 1338 1.1 skrll { 1339 1.1 skrll indx = h->root.dynindx; 1340 1.1.1.6 christos /* ??? glibc's ld.so just adds the final GOT entry to the 1341 1.1.1.6 christos relocation field. It therefore treats relocs against 1342 1.1.1.6 christos defined symbols in the same way as relocs against 1343 1.1.1.6 christos undefined symbols. */ 1344 1.1.1.9 christos defined_p = false; 1345 1.1 skrll } 1346 1.1 skrll else 1347 1.1 skrll { 1348 1.1 skrll indx = 0; 1349 1.1.1.9 christos defined_p = true; 1350 1.1 skrll } 1351 1.1 skrll 1352 1.1 skrll /* If the relocation was previously an absolute relocation and 1353 1.1 skrll this symbol will not be referred to by the relocation, we must 1354 1.1 skrll adjust it by the value we give it in the dynamic symbol table. 1355 1.1 skrll Otherwise leave the job up to the dynamic linker. */ 1356 1.1 skrll if (defined_p && r_type != R_SCORE_REL32) 1357 1.1 skrll *addendp += symbol; 1358 1.1 skrll 1359 1.1 skrll /* The relocation is always an REL32 relocation because we don't 1360 1.1 skrll know where the shared library will wind up at load-time. */ 1361 1.1.1.11 christos outrel.r_info = ELF32_R_INFO ((unsigned long) indx, R_SCORE_REL32); 1362 1.1 skrll 1363 1.1 skrll /* For strict adherence to the ABI specification, we should 1364 1.1 skrll generate a R_SCORE_64 relocation record by itself before the 1365 1.1 skrll _REL32/_64 record as well, such that the addend is read in as 1366 1.1 skrll a 64-bit value (REL32 is a 32-bit relocation, after all). 1367 1.1 skrll However, since none of the existing ELF64 SCORE dynamic 1368 1.1 skrll loaders seems to care, we don't waste space with these 1369 1.1 skrll artificial relocations. If this turns out to not be true, 1370 1.1 skrll score_elf_allocate_dynamic_relocations() should be tweaked so 1371 1.1 skrll as to make room for a pair of dynamic relocations per 1372 1.1 skrll invocation if ABI_64_P, and here we should generate an 1373 1.1 skrll additional relocation record with R_SCORE_64 by itself for a 1374 1.1 skrll NULL symbol before this relocation record. */ 1375 1.1 skrll 1376 1.1 skrll /* Adjust the output offset of the relocation to reference the 1377 1.1 skrll correct location in the output file. */ 1378 1.1.1.11 christos outrel.r_offset += (input_section->output_section->vma 1379 1.1.1.11 christos + input_section->output_offset); 1380 1.1 skrll 1381 1.1 skrll /* Put the relocation back out. We have to use the special 1382 1.1 skrll relocation outputter in the 64-bit case since the 64-bit 1383 1.1 skrll relocation format is non-standard. */ 1384 1.1 skrll bfd_elf32_swap_reloc_out 1385 1.1.1.11 christos (output_bfd, &outrel, 1386 1.1.1.11 christos sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)); 1387 1.1 skrll 1388 1.1 skrll /* We've now added another relocation. */ 1389 1.1 skrll ++sreloc->reloc_count; 1390 1.1 skrll 1391 1.1 skrll /* Make sure the output section is writable. The dynamic linker 1392 1.1 skrll will be writing to it. */ 1393 1.1 skrll elf_section_data (input_section->output_section)->this_hdr.sh_flags |= SHF_WRITE; 1394 1.1 skrll 1395 1.1.1.9 christos return true; 1396 1.1 skrll } 1397 1.1 skrll 1398 1.1.1.9 christos static bool 1399 1.1 skrll score_elf_create_got_section (bfd *abfd, 1400 1.1.1.6 christos struct bfd_link_info *info, 1401 1.1.1.9 christos bool maybe_exclude) 1402 1.1 skrll { 1403 1.1 skrll flagword flags; 1404 1.1 skrll asection *s; 1405 1.1 skrll struct elf_link_hash_entry *h; 1406 1.1 skrll struct bfd_link_hash_entry *bh; 1407 1.1 skrll struct score_got_info *g; 1408 1.1.1.9 christos size_t amt; 1409 1.1 skrll 1410 1.1 skrll /* This function may be called more than once. */ 1411 1.1.1.9 christos s = score_elf_got_section (abfd, true); 1412 1.1 skrll if (s) 1413 1.1 skrll { 1414 1.1 skrll if (! maybe_exclude) 1415 1.1.1.6 christos s->flags &= ~SEC_EXCLUDE; 1416 1.1.1.9 christos return true; 1417 1.1 skrll } 1418 1.1 skrll 1419 1.1 skrll flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED); 1420 1.1 skrll 1421 1.1 skrll if (maybe_exclude) 1422 1.1 skrll flags |= SEC_EXCLUDE; 1423 1.1 skrll 1424 1.1 skrll /* We have to use an alignment of 2**4 here because this is hardcoded 1425 1.1 skrll in the function stub generation and in the linker script. */ 1426 1.1.1.3 christos s = bfd_make_section_anyway_with_flags (abfd, ".got", flags); 1427 1.1.1.6 christos elf_hash_table (info)->sgot = s; 1428 1.1.1.6 christos if (s == NULL 1429 1.1.1.8 christos || !bfd_set_section_alignment (s, 4)) 1430 1.1.1.9 christos return false; 1431 1.1 skrll 1432 1.1 skrll /* Define the symbol _GLOBAL_OFFSET_TABLE_. We don't do this in the 1433 1.1 skrll linker script because we don't want to define the symbol if we 1434 1.1 skrll are not creating a global offset table. */ 1435 1.1 skrll bh = NULL; 1436 1.1 skrll if (! (_bfd_generic_link_add_one_symbol 1437 1.1.1.6 christos (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s, 1438 1.1.1.9 christos 0, NULL, false, get_elf_backend_data (abfd)->collect, &bh))) 1439 1.1.1.9 christos return false; 1440 1.1 skrll 1441 1.1 skrll h = (struct elf_link_hash_entry *) bh; 1442 1.1 skrll h->non_elf = 0; 1443 1.1 skrll h->def_regular = 1; 1444 1.1 skrll h->type = STT_OBJECT; 1445 1.1.1.6 christos elf_hash_table (info)->hgot = h; 1446 1.1 skrll 1447 1.1.1.4 christos if (bfd_link_pic (info) && ! bfd_elf_link_record_dynamic_symbol (info, h)) 1448 1.1.1.9 christos return false; 1449 1.1 skrll 1450 1.1 skrll amt = sizeof (struct score_got_info); 1451 1.1 skrll g = bfd_alloc (abfd, amt); 1452 1.1 skrll if (g == NULL) 1453 1.1.1.9 christos return false; 1454 1.1 skrll 1455 1.1 skrll g->global_gotsym = NULL; 1456 1.1 skrll g->global_gotno = 0; 1457 1.1 skrll 1458 1.1 skrll g->local_gotno = SCORE_RESERVED_GOTNO; 1459 1.1 skrll g->assigned_gotno = SCORE_RESERVED_GOTNO; 1460 1.1 skrll g->next = NULL; 1461 1.1 skrll 1462 1.1 skrll g->got_entries = htab_try_create (1, score_elf_got_entry_hash, 1463 1.1.1.6 christos score_elf_got_entry_eq, NULL); 1464 1.1 skrll if (g->got_entries == NULL) 1465 1.1.1.9 christos return false; 1466 1.1 skrll score_elf_section_data (s)->u.got_info = g; 1467 1.1 skrll score_elf_section_data (s)->elf.this_hdr.sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL; 1468 1.1 skrll 1469 1.1.1.9 christos return true; 1470 1.1 skrll } 1471 1.1 skrll 1472 1.1 skrll /* Calculate the %high function. */ 1473 1.1 skrll static bfd_vma 1474 1.1 skrll score_elf_high (bfd_vma value) 1475 1.1 skrll { 1476 1.1 skrll return ((value + (bfd_vma) 0x8000) >> 16) & 0xffff; 1477 1.1 skrll } 1478 1.1 skrll 1479 1.1 skrll /* Create a local GOT entry for VALUE. Return the index of the entry, 1480 1.1 skrll or -1 if it could not be created. */ 1481 1.1 skrll static struct score_got_entry * 1482 1.1 skrll score_elf_create_local_got_entry (bfd *abfd, 1483 1.1.1.6 christos bfd *ibfd ATTRIBUTE_UNUSED, 1484 1.1.1.6 christos struct score_got_info *gg, 1485 1.1.1.6 christos asection *sgot, bfd_vma value, 1486 1.1.1.6 christos unsigned long r_symndx ATTRIBUTE_UNUSED, 1487 1.1.1.6 christos struct score_elf_link_hash_entry *h ATTRIBUTE_UNUSED, 1488 1.1.1.6 christos int r_type ATTRIBUTE_UNUSED) 1489 1.1 skrll { 1490 1.1 skrll struct score_got_entry entry, **loc; 1491 1.1 skrll struct score_got_info *g; 1492 1.1 skrll 1493 1.1 skrll entry.abfd = NULL; 1494 1.1 skrll entry.symndx = -1; 1495 1.1 skrll entry.d.address = value; 1496 1.1 skrll 1497 1.1 skrll g = gg; 1498 1.1 skrll loc = (struct score_got_entry **) htab_find_slot (g->got_entries, &entry, INSERT); 1499 1.1 skrll if (*loc) 1500 1.1 skrll return *loc; 1501 1.1 skrll 1502 1.1 skrll entry.gotidx = SCORE_ELF_GOT_SIZE (abfd) * g->assigned_gotno++; 1503 1.1 skrll 1504 1.1 skrll *loc = bfd_alloc (abfd, sizeof entry); 1505 1.1 skrll 1506 1.1 skrll if (! *loc) 1507 1.1 skrll return NULL; 1508 1.1 skrll 1509 1.1 skrll memcpy (*loc, &entry, sizeof entry); 1510 1.1 skrll 1511 1.1 skrll if (g->assigned_gotno >= g->local_gotno) 1512 1.1 skrll { 1513 1.1 skrll (*loc)->gotidx = -1; 1514 1.1 skrll /* We didn't allocate enough space in the GOT. */ 1515 1.1.1.6 christos _bfd_error_handler 1516 1.1.1.6 christos (_("not enough GOT space for local GOT entries")); 1517 1.1 skrll bfd_set_error (bfd_error_bad_value); 1518 1.1 skrll return NULL; 1519 1.1 skrll } 1520 1.1 skrll 1521 1.1.1.2 christos score_bfd_put_32 (abfd, value, (sgot->contents + entry.gotidx)); 1522 1.1 skrll 1523 1.1 skrll return *loc; 1524 1.1 skrll } 1525 1.1 skrll 1526 1.1 skrll /* Find a GOT entry whose higher-order 16 bits are the same as those 1527 1.1 skrll for value. Return the index into the GOT for this entry. */ 1528 1.1 skrll static bfd_vma 1529 1.1 skrll score_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info, 1530 1.1.1.9 christos bfd_vma value, bool external) 1531 1.1 skrll { 1532 1.1 skrll asection *sgot; 1533 1.1 skrll struct score_got_info *g; 1534 1.1 skrll struct score_got_entry *entry; 1535 1.1 skrll 1536 1.1 skrll if (!external) 1537 1.1 skrll { 1538 1.1 skrll /* Although the ABI says that it is "the high-order 16 bits" that we 1539 1.1.1.6 christos want, it is really the %high value. The complete value is 1540 1.1.1.6 christos calculated with a `addiu' of a LO16 relocation, just as with a 1541 1.1.1.6 christos HI16/LO16 pair. */ 1542 1.1 skrll value = score_elf_high (value) << 16; 1543 1.1 skrll } 1544 1.1 skrll 1545 1.1 skrll g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot); 1546 1.1 skrll 1547 1.1 skrll entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value, 0, NULL, 1548 1.1.1.6 christos R_SCORE_GOT15); 1549 1.1 skrll if (entry) 1550 1.1 skrll return entry->gotidx; 1551 1.1 skrll else 1552 1.1 skrll return MINUS_ONE; 1553 1.1 skrll } 1554 1.1 skrll 1555 1.1 skrll static void 1556 1.1.1.2 christos s3_bfd_score_elf_hide_symbol (struct bfd_link_info *info, 1557 1.1.1.6 christos struct elf_link_hash_entry *entry, 1558 1.1.1.9 christos bool force_local) 1559 1.1 skrll { 1560 1.1 skrll bfd *dynobj; 1561 1.1 skrll asection *got; 1562 1.1 skrll struct score_got_info *g; 1563 1.1 skrll struct score_elf_link_hash_entry *h; 1564 1.1 skrll 1565 1.1 skrll h = (struct score_elf_link_hash_entry *) entry; 1566 1.1 skrll if (h->forced_local) 1567 1.1 skrll return; 1568 1.1.1.9 christos h->forced_local = true; 1569 1.1 skrll 1570 1.1 skrll dynobj = elf_hash_table (info)->dynobj; 1571 1.1 skrll if (dynobj != NULL && force_local) 1572 1.1 skrll { 1573 1.1.1.9 christos got = score_elf_got_section (dynobj, false); 1574 1.1 skrll if (got == NULL) 1575 1.1.1.6 christos return; 1576 1.1 skrll g = score_elf_section_data (got)->u.got_info; 1577 1.1 skrll 1578 1.1 skrll if (g->next) 1579 1.1.1.6 christos { 1580 1.1.1.6 christos struct score_got_entry e; 1581 1.1.1.6 christos struct score_got_info *gg = g; 1582 1.1.1.6 christos 1583 1.1.1.6 christos /* Since we're turning what used to be a global symbol into a 1584 1.1.1.6 christos local one, bump up the number of local entries of each GOT 1585 1.1.1.6 christos that had an entry for it. This will automatically decrease 1586 1.1.1.6 christos the number of global entries, since global_gotno is actually 1587 1.1.1.6 christos the upper limit of global entries. */ 1588 1.1.1.6 christos e.abfd = dynobj; 1589 1.1.1.6 christos e.symndx = -1; 1590 1.1.1.6 christos e.d.h = h; 1591 1.1.1.6 christos 1592 1.1.1.6 christos for (g = g->next; g != gg; g = g->next) 1593 1.1.1.6 christos if (htab_find (g->got_entries, &e)) 1594 1.1.1.6 christos { 1595 1.1.1.6 christos BFD_ASSERT (g->global_gotno > 0); 1596 1.1.1.6 christos g->local_gotno++; 1597 1.1.1.6 christos g->global_gotno--; 1598 1.1.1.6 christos } 1599 1.1.1.6 christos 1600 1.1.1.6 christos /* If this was a global symbol forced into the primary GOT, we 1601 1.1.1.6 christos no longer need an entry for it. We can't release the entry 1602 1.1.1.6 christos at this point, but we must at least stop counting it as one 1603 1.1.1.6 christos of the symbols that required a forced got entry. */ 1604 1.1.1.6 christos if (h->root.got.offset == 2) 1605 1.1.1.6 christos { 1606 1.1.1.6 christos BFD_ASSERT (gg->assigned_gotno > 0); 1607 1.1.1.6 christos gg->assigned_gotno--; 1608 1.1.1.6 christos } 1609 1.1.1.6 christos } 1610 1.1 skrll else if (g->global_gotno == 0 && g->global_gotsym == NULL) 1611 1.1.1.6 christos /* If we haven't got through GOT allocation yet, just bump up the 1612 1.1.1.6 christos number of local entries, as this symbol won't be counted as 1613 1.1.1.6 christos global. */ 1614 1.1.1.6 christos g->local_gotno++; 1615 1.1 skrll else if (h->root.got.offset == 1) 1616 1.1.1.6 christos { 1617 1.1.1.6 christos /* If we're past non-multi-GOT allocation and this symbol had 1618 1.1.1.6 christos been marked for a global got entry, give it a local entry 1619 1.1.1.6 christos instead. */ 1620 1.1.1.6 christos BFD_ASSERT (g->global_gotno > 0); 1621 1.1.1.6 christos g->local_gotno++; 1622 1.1.1.6 christos g->global_gotno--; 1623 1.1.1.6 christos } 1624 1.1 skrll } 1625 1.1 skrll 1626 1.1 skrll _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local); 1627 1.1 skrll } 1628 1.1 skrll 1629 1.1 skrll /* If H is a symbol that needs a global GOT entry, but has a dynamic 1630 1.1 skrll symbol table index lower than any we've seen to date, record it for 1631 1.1 skrll posterity. */ 1632 1.1.1.9 christos static bool 1633 1.1 skrll score_elf_record_global_got_symbol (struct elf_link_hash_entry *h, 1634 1.1.1.6 christos bfd *abfd, 1635 1.1.1.6 christos struct bfd_link_info *info, 1636 1.1.1.6 christos struct score_got_info *g) 1637 1.1 skrll { 1638 1.1 skrll struct score_got_entry entry, **loc; 1639 1.1 skrll 1640 1.1 skrll /* A global symbol in the GOT must also be in the dynamic symbol table. */ 1641 1.1 skrll if (h->dynindx == -1) 1642 1.1 skrll { 1643 1.1 skrll switch (ELF_ST_VISIBILITY (h->other)) 1644 1.1.1.6 christos { 1645 1.1.1.6 christos case STV_INTERNAL: 1646 1.1.1.6 christos case STV_HIDDEN: 1647 1.1.1.9 christos s3_bfd_score_elf_hide_symbol (info, h, true); 1648 1.1.1.6 christos break; 1649 1.1.1.6 christos } 1650 1.1 skrll if (!bfd_elf_link_record_dynamic_symbol (info, h)) 1651 1.1.1.9 christos return false; 1652 1.1 skrll } 1653 1.1 skrll 1654 1.1 skrll entry.abfd = abfd; 1655 1.1 skrll entry.symndx = -1; 1656 1.1 skrll entry.d.h = (struct score_elf_link_hash_entry *)h; 1657 1.1 skrll 1658 1.1 skrll loc = (struct score_got_entry **)htab_find_slot (g->got_entries, &entry, INSERT); 1659 1.1 skrll 1660 1.1 skrll /* If we've already marked this entry as needing GOT space, we don't 1661 1.1 skrll need to do it again. */ 1662 1.1 skrll if (*loc) 1663 1.1.1.9 christos return true; 1664 1.1 skrll 1665 1.1 skrll *loc = bfd_alloc (abfd, sizeof entry); 1666 1.1 skrll if (! *loc) 1667 1.1.1.9 christos return false; 1668 1.1 skrll 1669 1.1 skrll entry.gotidx = -1; 1670 1.1 skrll 1671 1.1 skrll memcpy (*loc, &entry, sizeof (entry)); 1672 1.1 skrll 1673 1.1 skrll if (h->got.offset != MINUS_ONE) 1674 1.1.1.9 christos return true; 1675 1.1 skrll 1676 1.1 skrll /* By setting this to a value other than -1, we are indicating that 1677 1.1 skrll there needs to be a GOT entry for H. Avoid using zero, as the 1678 1.1 skrll generic ELF copy_indirect_symbol tests for <= 0. */ 1679 1.1 skrll h->got.offset = 1; 1680 1.1 skrll 1681 1.1.1.9 christos return true; 1682 1.1 skrll } 1683 1.1 skrll 1684 1.1 skrll /* Reserve space in G for a GOT entry containing the value of symbol 1685 1.1 skrll SYMNDX in input bfd ABDF, plus ADDEND. */ 1686 1.1.1.9 christos static bool 1687 1.1 skrll score_elf_record_local_got_symbol (bfd *abfd, 1688 1.1.1.6 christos long symndx, 1689 1.1.1.6 christos bfd_vma addend, 1690 1.1.1.6 christos struct score_got_info *g) 1691 1.1 skrll { 1692 1.1 skrll struct score_got_entry entry, **loc; 1693 1.1 skrll 1694 1.1 skrll entry.abfd = abfd; 1695 1.1 skrll entry.symndx = symndx; 1696 1.1 skrll entry.d.addend = addend; 1697 1.1 skrll loc = (struct score_got_entry **)htab_find_slot (g->got_entries, &entry, INSERT); 1698 1.1 skrll 1699 1.1 skrll if (*loc) 1700 1.1.1.9 christos return true; 1701 1.1 skrll 1702 1.1 skrll entry.gotidx = g->local_gotno++; 1703 1.1 skrll 1704 1.1 skrll *loc = bfd_alloc (abfd, sizeof(entry)); 1705 1.1 skrll if (! *loc) 1706 1.1.1.9 christos return false; 1707 1.1 skrll 1708 1.1 skrll memcpy (*loc, &entry, sizeof (entry)); 1709 1.1 skrll 1710 1.1.1.9 christos return true; 1711 1.1 skrll } 1712 1.1 skrll 1713 1.1 skrll /* Returns the GOT offset at which the indicated address can be found. 1714 1.1 skrll If there is not yet a GOT entry for this value, create one. 1715 1.1 skrll Returns -1 if no satisfactory GOT offset can be found. */ 1716 1.1 skrll static bfd_vma 1717 1.1 skrll score_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info, 1718 1.1.1.6 christos bfd_vma value, unsigned long r_symndx, 1719 1.1.1.6 christos struct score_elf_link_hash_entry *h, int r_type) 1720 1.1 skrll { 1721 1.1 skrll asection *sgot; 1722 1.1 skrll struct score_got_info *g; 1723 1.1 skrll struct score_got_entry *entry; 1724 1.1 skrll 1725 1.1 skrll g = score_elf_got_info (elf_hash_table (info)->dynobj, &sgot); 1726 1.1 skrll 1727 1.1 skrll entry = score_elf_create_local_got_entry (abfd, ibfd, g, sgot, value, 1728 1.1.1.6 christos r_symndx, h, r_type); 1729 1.1 skrll if (!entry) 1730 1.1 skrll return MINUS_ONE; 1731 1.1 skrll 1732 1.1 skrll else 1733 1.1 skrll return entry->gotidx; 1734 1.1 skrll } 1735 1.1 skrll 1736 1.1 skrll /* Returns the GOT index for the global symbol indicated by H. */ 1737 1.1 skrll 1738 1.1 skrll static bfd_vma 1739 1.1 skrll score_elf_global_got_index (bfd *abfd, struct elf_link_hash_entry *h) 1740 1.1 skrll { 1741 1.1.1.2 christos bfd_vma got_index; 1742 1.1 skrll asection *sgot; 1743 1.1 skrll struct score_got_info *g; 1744 1.1 skrll long global_got_dynindx = 0; 1745 1.1 skrll 1746 1.1 skrll g = score_elf_got_info (abfd, &sgot); 1747 1.1 skrll if (g->global_gotsym != NULL) 1748 1.1 skrll global_got_dynindx = g->global_gotsym->dynindx; 1749 1.1 skrll 1750 1.1 skrll /* Once we determine the global GOT entry with the lowest dynamic 1751 1.1 skrll symbol table index, we must put all dynamic symbols with greater 1752 1.1 skrll indices into the GOT. That makes it easy to calculate the GOT 1753 1.1 skrll offset. */ 1754 1.1 skrll BFD_ASSERT (h->dynindx >= global_got_dynindx); 1755 1.1.1.2 christos got_index = ((h->dynindx - global_got_dynindx + g->local_gotno) * SCORE_ELF_GOT_SIZE (abfd)); 1756 1.1.1.2 christos BFD_ASSERT (got_index < sgot->size); 1757 1.1 skrll 1758 1.1.1.2 christos return got_index; 1759 1.1 skrll } 1760 1.1 skrll 1761 1.1 skrll /* Returns the offset for the entry at the INDEXth position in the GOT. */ 1762 1.1 skrll 1763 1.1 skrll static bfd_vma 1764 1.1.1.2 christos score_elf_got_offset_from_index (bfd *dynobj, 1765 1.1.1.2 christos bfd *output_bfd, 1766 1.1.1.6 christos bfd *input_bfd ATTRIBUTE_UNUSED, 1767 1.1.1.2 christos bfd_vma got_index) 1768 1.1 skrll { 1769 1.1 skrll asection *sgot; 1770 1.1 skrll bfd_vma gp; 1771 1.1 skrll 1772 1.1.1.2 christos score_elf_got_info (dynobj, &sgot); 1773 1.1 skrll gp = _bfd_get_gp_value (output_bfd); 1774 1.1 skrll 1775 1.1.1.2 christos return sgot->output_section->vma + sgot->output_offset + got_index - gp; 1776 1.1 skrll } 1777 1.1 skrll 1778 1.1 skrll /* Follow indirect and warning hash entries so that each got entry 1779 1.1 skrll points to the final symbol definition. P must point to a pointer 1780 1.1 skrll to the hash table we're traversing. Since this traversal may 1781 1.1 skrll modify the hash table, we set this pointer to NULL to indicate 1782 1.1 skrll we've made a potentially-destructive change to the hash table, so 1783 1.1 skrll the traversal must be restarted. */ 1784 1.1 skrll static int 1785 1.1 skrll score_elf_resolve_final_got_entry (void **entryp, void *p) 1786 1.1 skrll { 1787 1.1 skrll struct score_got_entry *entry = (struct score_got_entry *)*entryp; 1788 1.1 skrll htab_t got_entries = *(htab_t *)p; 1789 1.1 skrll 1790 1.1 skrll if (entry->abfd != NULL && entry->symndx == -1) 1791 1.1 skrll { 1792 1.1 skrll struct score_elf_link_hash_entry *h = entry->d.h; 1793 1.1 skrll 1794 1.1 skrll while (h->root.root.type == bfd_link_hash_indirect 1795 1.1.1.6 christos || h->root.root.type == bfd_link_hash_warning) 1796 1.1.1.6 christos h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link; 1797 1.1 skrll 1798 1.1 skrll if (entry->d.h == h) 1799 1.1.1.6 christos return 1; 1800 1.1 skrll 1801 1.1 skrll entry->d.h = h; 1802 1.1 skrll 1803 1.1 skrll /* If we can't find this entry with the new bfd hash, re-insert 1804 1.1.1.6 christos it, and get the traversal restarted. */ 1805 1.1 skrll if (! htab_find (got_entries, entry)) 1806 1.1.1.6 christos { 1807 1.1.1.6 christos htab_clear_slot (got_entries, entryp); 1808 1.1.1.6 christos entryp = htab_find_slot (got_entries, entry, INSERT); 1809 1.1.1.6 christos if (! *entryp) 1810 1.1.1.6 christos *entryp = entry; 1811 1.1.1.6 christos /* Abort the traversal, since the whole table may have 1812 1.1.1.6 christos moved, and leave it up to the parent to restart the 1813 1.1.1.6 christos process. */ 1814 1.1.1.6 christos *(htab_t *)p = NULL; 1815 1.1.1.6 christos return 0; 1816 1.1.1.6 christos } 1817 1.1 skrll /* We might want to decrement the global_gotno count, but it's 1818 1.1.1.6 christos either too early or too late for that at this point. */ 1819 1.1 skrll } 1820 1.1 skrll 1821 1.1 skrll return 1; 1822 1.1 skrll } 1823 1.1 skrll 1824 1.1 skrll /* Turn indirect got entries in a got_entries table into their final locations. */ 1825 1.1 skrll static void 1826 1.1 skrll score_elf_resolve_final_got_entries (struct score_got_info *g) 1827 1.1 skrll { 1828 1.1 skrll htab_t got_entries; 1829 1.1 skrll 1830 1.1 skrll do 1831 1.1 skrll { 1832 1.1 skrll got_entries = g->got_entries; 1833 1.1 skrll 1834 1.1 skrll htab_traverse (got_entries, 1835 1.1.1.6 christos score_elf_resolve_final_got_entry, 1836 1.1.1.6 christos &got_entries); 1837 1.1 skrll } 1838 1.1 skrll while (got_entries == NULL); 1839 1.1 skrll } 1840 1.1 skrll 1841 1.1 skrll /* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. for -r */ 1842 1.1 skrll static void 1843 1.1 skrll score_elf_add_to_rel (bfd *abfd, 1844 1.1.1.6 christos bfd_byte *address, 1845 1.1.1.6 christos reloc_howto_type *howto, 1846 1.1.1.6 christos bfd_signed_vma increment) 1847 1.1 skrll { 1848 1.1 skrll bfd_signed_vma addend; 1849 1.1 skrll bfd_vma contents; 1850 1.1 skrll unsigned long offset; 1851 1.1 skrll unsigned long r_type = howto->type; 1852 1.1 skrll unsigned long hi16_addend, hi16_offset, hi16_value, uvalue; 1853 1.1 skrll 1854 1.1.1.2 christos contents = score_bfd_get_32 (abfd, address); 1855 1.1 skrll /* Get the (signed) value from the instruction. */ 1856 1.1 skrll addend = contents & howto->src_mask; 1857 1.1 skrll if (addend & ((howto->src_mask + 1) >> 1)) 1858 1.1 skrll { 1859 1.1 skrll bfd_signed_vma mask; 1860 1.1 skrll 1861 1.1 skrll mask = -1; 1862 1.1 skrll mask &= ~howto->src_mask; 1863 1.1 skrll addend |= mask; 1864 1.1 skrll } 1865 1.1 skrll /* Add in the increment, (which is a byte value). */ 1866 1.1 skrll switch (r_type) 1867 1.1 skrll { 1868 1.1 skrll case R_SCORE_PC19: 1869 1.1 skrll offset = 1870 1.1.1.6 christos (((contents & howto->src_mask) & 0x3ff0000) >> 6) | ((contents & howto->src_mask) & 0x3ff); 1871 1.1 skrll offset += increment; 1872 1.1 skrll contents = 1873 1.1.1.6 christos (contents & ~howto-> 1874 1.1.1.6 christos src_mask) | (((offset << 6) & howto->src_mask) & 0x3ff0000) | (offset & 0x3ff); 1875 1.1.1.2 christos score_bfd_put_32 (abfd, contents, address); 1876 1.1 skrll break; 1877 1.1 skrll case R_SCORE_HI16: 1878 1.1 skrll break; 1879 1.1 skrll case R_SCORE_LO16: 1880 1.1.1.2 christos hi16_addend = score_bfd_get_32 (abfd, address - 4); 1881 1.1 skrll hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1; 1882 1.1 skrll offset = ((((contents >> 16) & 0x3) << 15) | (contents & 0x7fff)) >> 1; 1883 1.1 skrll offset = (hi16_offset << 16) | (offset & 0xffff); 1884 1.1 skrll uvalue = increment + offset; 1885 1.1 skrll hi16_offset = (uvalue >> 16) << 1; 1886 1.1 skrll hi16_value = (hi16_addend & (~(howto->dst_mask))) 1887 1.1.1.6 christos | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000); 1888 1.1.1.2 christos score_bfd_put_32 (abfd, hi16_value, address - 4); 1889 1.1 skrll offset = (uvalue & 0xffff) << 1; 1890 1.1 skrll contents = (contents & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000); 1891 1.1.1.2 christos score_bfd_put_32 (abfd, contents, address); 1892 1.1 skrll break; 1893 1.1 skrll case R_SCORE_24: 1894 1.1 skrll offset = 1895 1.1.1.6 christos (((contents & howto->src_mask) >> 1) & 0x1ff8000) | ((contents & howto->src_mask) & 0x7fff); 1896 1.1 skrll offset += increment; 1897 1.1 skrll contents = 1898 1.1.1.6 christos (contents & ~howto-> 1899 1.1.1.6 christos src_mask) | (((offset << 1) & howto->src_mask) & 0x3ff0000) | (offset & 0x7fff); 1900 1.1.1.2 christos score_bfd_put_32 (abfd, contents, address); 1901 1.1 skrll break; 1902 1.1.1.2 christos 1903 1.1 skrll case R_SCORE16_11: 1904 1.1 skrll 1905 1.1.1.2 christos contents = score_bfd_get_16 (abfd, address); 1906 1.1 skrll offset = contents & howto->src_mask; 1907 1.1 skrll offset += increment; 1908 1.1 skrll contents = (contents & ~howto->src_mask) | (offset & howto->src_mask); 1909 1.1.1.2 christos score_bfd_put_16 (abfd, contents, address); 1910 1.1 skrll 1911 1.1 skrll break; 1912 1.1 skrll case R_SCORE16_PC8: 1913 1.1 skrll 1914 1.1.1.2 christos contents = score_bfd_get_16 (abfd, address); 1915 1.1.1.2 christos offset = (contents & howto->src_mask) + ((increment >> 1) & 0x1ff); 1916 1.1.1.2 christos contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask); 1917 1.1.1.2 christos score_bfd_put_16 (abfd, contents, address); 1918 1.1.1.2 christos 1919 1.1.1.2 christos break; 1920 1.1.1.2 christos 1921 1.1.1.2 christos case R_SCORE_BCMP: 1922 1.1.1.2 christos contents = score_bfd_get_32 (abfd, address); 1923 1.1.1.2 christos offset = (contents & howto->src_mask); 1924 1.1.1.2 christos offset <<= howto->rightshift; 1925 1.1.1.2 christos offset += increment; 1926 1.1.1.2 christos offset >>= howto->rightshift; 1927 1.1.1.2 christos contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask); 1928 1.1.1.2 christos score_bfd_put_32 (abfd, contents, address); 1929 1.1.1.2 christos break; 1930 1.1.1.2 christos 1931 1.1.1.2 christos case R_SCORE_IMM30: 1932 1.1.1.2 christos contents = score_bfd_get_48 (abfd, address); 1933 1.1.1.2 christos offset = (contents & howto->src_mask); 1934 1.1.1.2 christos offset <<= howto->rightshift; 1935 1.1.1.2 christos offset += increment; 1936 1.1.1.2 christos offset >>= howto->rightshift; 1937 1.1 skrll contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask); 1938 1.1.1.2 christos score_bfd_put_48 (abfd, contents, address); 1939 1.1.1.2 christos break; 1940 1.1 skrll 1941 1.1.1.2 christos case R_SCORE_IMM32: 1942 1.1.1.2 christos contents = score_bfd_get_48 (abfd, address); 1943 1.1.1.2 christos offset = (contents & howto->src_mask); 1944 1.1.1.2 christos offset += increment; 1945 1.1.1.2 christos contents = (contents & (~howto->src_mask)) | (offset & howto->src_mask); 1946 1.1.1.2 christos score_bfd_put_48 (abfd, contents, address); 1947 1.1 skrll break; 1948 1.1.1.2 christos 1949 1.1 skrll default: 1950 1.1 skrll addend += increment; 1951 1.1 skrll contents = (contents & ~howto->dst_mask) | (addend & howto->dst_mask); 1952 1.1.1.2 christos score_bfd_put_32 (abfd, contents, address); 1953 1.1 skrll break; 1954 1.1 skrll } 1955 1.1 skrll } 1956 1.1 skrll 1957 1.1 skrll /* Perform a relocation as part of a final link. */ 1958 1.1 skrll static bfd_reloc_status_type 1959 1.1 skrll score_elf_final_link_relocate (reloc_howto_type *howto, 1960 1.1.1.6 christos bfd *input_bfd, 1961 1.1.1.6 christos bfd *output_bfd, 1962 1.1.1.6 christos asection *input_section, 1963 1.1.1.6 christos bfd_byte *contents, 1964 1.1.1.6 christos Elf_Internal_Rela *rel, 1965 1.1.1.6 christos Elf_Internal_Rela *relocs, 1966 1.1.1.6 christos bfd_vma symbol, 1967 1.1.1.6 christos struct bfd_link_info *info, 1968 1.1.1.6 christos const char *sym_name ATTRIBUTE_UNUSED, 1969 1.1.1.6 christos int sym_flags ATTRIBUTE_UNUSED, 1970 1.1.1.6 christos struct score_elf_link_hash_entry *h, 1971 1.1.1.6 christos asection **local_sections, 1972 1.1.1.9 christos bool gp_disp_p) 1973 1.1 skrll { 1974 1.1 skrll unsigned long r_type; 1975 1.1 skrll unsigned long r_symndx; 1976 1.1 skrll bfd_byte *hit_data = contents + rel->r_offset; 1977 1.1 skrll bfd_vma addend; 1978 1.1 skrll /* The final GP value to be used for the relocatable, executable, or 1979 1.1 skrll shared object file being produced. */ 1980 1.1 skrll bfd_vma gp = MINUS_ONE; 1981 1.1 skrll /* The place (section offset or address) of the storage unit being relocated. */ 1982 1.1 skrll bfd_vma rel_addr; 1983 1.1 skrll /* The offset into the global offset table at which the address of the relocation entry 1984 1.1 skrll symbol, adjusted by the addend, resides during execution. */ 1985 1.1 skrll bfd_vma g = MINUS_ONE; 1986 1.1 skrll /* TRUE if the symbol referred to by this relocation is a local symbol. */ 1987 1.1.1.9 christos bool local_p; 1988 1.1 skrll /* The eventual value we will relocate. */ 1989 1.1 skrll bfd_vma value = symbol; 1990 1.1 skrll unsigned long hi16_addend, hi16_offset, hi16_value, uvalue, offset, abs_value = 0; 1991 1.1 skrll 1992 1.1.1.2 christos 1993 1.1 skrll if (elf_gp (output_bfd) == 0) 1994 1.1 skrll { 1995 1.1 skrll struct bfd_link_hash_entry *bh; 1996 1.1 skrll asection *o; 1997 1.1 skrll 1998 1.1 skrll bh = bfd_link_hash_lookup (info->hash, "_gp", 0, 0, 1); 1999 1.1.1.2 christos if (bh != NULL && bh->type == bfd_link_hash_defined) 2000 1.1.1.6 christos elf_gp (output_bfd) = (bh->u.def.value 2001 1.1.1.6 christos + bh->u.def.section->output_section->vma 2002 1.1.1.6 christos + bh->u.def.section->output_offset); 2003 1.1.1.4 christos else if (bfd_link_relocatable (info)) 2004 1.1.1.6 christos { 2005 1.1.1.6 christos bfd_vma lo = -1; 2006 1.1 skrll 2007 1.1.1.6 christos /* Find the GP-relative section with the lowest offset. */ 2008 1.1.1.6 christos for (o = output_bfd->sections; o != NULL; o = o->next) 2009 1.1.1.6 christos if (o->vma < lo) 2010 1.1.1.6 christos lo = o->vma; 2011 1.1.1.6 christos /* And calculate GP relative to that. */ 2012 1.1.1.6 christos elf_gp (output_bfd) = lo + ELF_SCORE_GP_OFFSET (input_bfd); 2013 1.1.1.6 christos } 2014 1.1 skrll else 2015 1.1.1.6 christos { 2016 1.1.1.6 christos /* If the relocate_section function needs to do a reloc 2017 1.1.1.6 christos involving the GP value, it should make a reloc_dangerous 2018 1.1.1.6 christos callback to warn that GP is not defined. */ 2019 1.1.1.6 christos } 2020 1.1 skrll } 2021 1.1 skrll 2022 1.1 skrll /* Parse the relocation. */ 2023 1.1 skrll r_symndx = ELF32_R_SYM (rel->r_info); 2024 1.1 skrll r_type = ELF32_R_TYPE (rel->r_info); 2025 1.1 skrll rel_addr = (input_section->output_section->vma + input_section->output_offset + rel->r_offset); 2026 1.1.1.9 christos local_p = score_elf_local_relocation_p (input_bfd, rel, local_sections, true); 2027 1.1 skrll 2028 1.1 skrll if (r_type == R_SCORE_GOT15) 2029 1.1 skrll { 2030 1.1 skrll const Elf_Internal_Rela *relend; 2031 1.1 skrll const Elf_Internal_Rela *lo16_rel; 2032 1.1 skrll bfd_vma lo_value = 0; 2033 1.1 skrll 2034 1.1.1.6 christos relend = relocs + input_section->reloc_count; 2035 1.1 skrll lo16_rel = score_elf_next_relocation (input_bfd, R_SCORE_GOT_LO16, rel, relend); 2036 1.1 skrll if ((local_p) && (lo16_rel != NULL)) 2037 1.1.1.6 christos { 2038 1.1.1.6 christos bfd_vma tmp = 0; 2039 1.1.1.6 christos tmp = score_bfd_get_32 (input_bfd, contents + lo16_rel->r_offset); 2040 1.1.1.6 christos lo_value = (((tmp >> 16) & 0x3) << 14) | ((tmp & 0x7fff) >> 1); 2041 1.1.1.6 christos } 2042 1.1 skrll addend = lo_value; 2043 1.1 skrll } 2044 1.1.1.2 christos /* For score3 R_SCORE_ABS32. */ 2045 1.1.1.2 christos else if (r_type == R_SCORE_ABS32 || r_type == R_SCORE_REL32) 2046 1.1 skrll { 2047 1.1 skrll addend = (bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask; 2048 1.1 skrll } 2049 1.1.1.2 christos else 2050 1.1.1.2 christos { 2051 1.1.1.2 christos addend = (score_bfd_get_32 (input_bfd, hit_data) >> howto->bitpos) & howto->src_mask; 2052 1.1.1.2 christos } 2053 1.1 skrll 2054 1.1 skrll /* If we haven't already determined the GOT offset, or the GP value, 2055 1.1 skrll and we're going to need it, get it now. */ 2056 1.1 skrll switch (r_type) 2057 1.1 skrll { 2058 1.1 skrll case R_SCORE_CALL15: 2059 1.1 skrll case R_SCORE_GOT15: 2060 1.1 skrll if (!local_p) 2061 1.1.1.6 christos { 2062 1.1.1.6 christos g = score_elf_global_got_index (elf_hash_table (info)->dynobj, 2063 1.1.1.6 christos (struct elf_link_hash_entry *) h); 2064 1.1.1.6 christos if ((! elf_hash_table (info)->dynamic_sections_created 2065 1.1.1.6 christos || (bfd_link_pic (info) 2066 1.1.1.6 christos && (info->symbolic || h->root.dynindx == -1) 2067 1.1.1.6 christos && h->root.def_regular))) 2068 1.1.1.6 christos { 2069 1.1.1.6 christos /* This is a static link or a -Bsymbolic link. The 2070 1.1.1.6 christos symbol is defined locally, or was forced to be local. 2071 1.1.1.6 christos We must initialize this entry in the GOT. */ 2072 1.1.1.6 christos bfd *tmpbfd = elf_hash_table (info)->dynobj; 2073 1.1.1.9 christos asection *sgot = score_elf_got_section (tmpbfd, false); 2074 1.1.1.6 christos score_bfd_put_32 (tmpbfd, value, sgot->contents + g); 2075 1.1.1.6 christos } 2076 1.1.1.6 christos } 2077 1.1 skrll else if (r_type == R_SCORE_GOT15 || r_type == R_SCORE_CALL15) 2078 1.1.1.6 christos { 2079 1.1.1.6 christos /* There's no need to create a local GOT entry here; the 2080 1.1.1.6 christos calculation for a local GOT15 entry does not involve G. */ 2081 1.1.1.6 christos ; 2082 1.1.1.6 christos } 2083 1.1 skrll else 2084 1.1.1.6 christos { 2085 1.1.1.6 christos g = score_elf_local_got_index (output_bfd, input_bfd, info, 2086 1.1.1.6 christos symbol + addend, r_symndx, h, r_type); 2087 1.1.1.6 christos if (g == MINUS_ONE) 2088 1.1.1.6 christos return bfd_reloc_outofrange; 2089 1.1.1.6 christos } 2090 1.1 skrll 2091 1.1 skrll /* Convert GOT indices to actual offsets. */ 2092 1.1 skrll g = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj, 2093 1.1.1.6 christos output_bfd, input_bfd, g); 2094 1.1 skrll break; 2095 1.1 skrll 2096 1.1 skrll case R_SCORE_HI16: 2097 1.1 skrll case R_SCORE_LO16: 2098 1.1 skrll case R_SCORE_GPREL32: 2099 1.1 skrll gp = _bfd_get_gp_value (output_bfd); 2100 1.1 skrll break; 2101 1.1 skrll 2102 1.1 skrll case R_SCORE_GP15: 2103 1.1 skrll gp = _bfd_get_gp_value (output_bfd); 2104 1.1 skrll 2105 1.1 skrll default: 2106 1.1 skrll break; 2107 1.1 skrll } 2108 1.1 skrll 2109 1.1 skrll switch (r_type) 2110 1.1 skrll { 2111 1.1 skrll case R_SCORE_NONE: 2112 1.1 skrll return bfd_reloc_ok; 2113 1.1 skrll 2114 1.1 skrll case R_SCORE_ABS32: 2115 1.1 skrll case R_SCORE_REL32: 2116 1.1.1.4 christos if ((bfd_link_pic (info) 2117 1.1.1.6 christos || (elf_hash_table (info)->dynamic_sections_created 2118 1.1.1.6 christos && h != NULL 2119 1.1.1.6 christos && h->root.def_dynamic 2120 1.1.1.6 christos && !h->root.def_regular)) 2121 1.1.1.6 christos && r_symndx != STN_UNDEF 2122 1.1.1.6 christos && (input_section->flags & SEC_ALLOC) != 0) 2123 1.1.1.6 christos { 2124 1.1.1.6 christos /* If we're creating a shared library, or this relocation is against a symbol 2125 1.1.1.6 christos in a shared library, then we can't know where the symbol will end up. 2126 1.1.1.6 christos So, we create a relocation record in the output, and leave the job up 2127 1.1.1.6 christos to the dynamic linker. */ 2128 1.1.1.6 christos value = addend; 2129 1.1.1.6 christos if (!score_elf_create_dynamic_relocation (output_bfd, info, rel, h, 2130 1.1.1.6 christos symbol, &value, 2131 1.1.1.6 christos input_section)) 2132 1.1.1.6 christos return bfd_reloc_undefined; 2133 1.1.1.6 christos } 2134 1.1.1.2 christos else if (r_symndx == STN_UNDEF) 2135 1.1.1.6 christos /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols 2136 1.1.1.6 christos from removed linkonce sections, or sections discarded by 2137 1.1.1.6 christos a linker script. */ 2138 1.1.1.6 christos value = 0; 2139 1.1 skrll else 2140 1.1.1.6 christos { 2141 1.1.1.6 christos if (r_type != R_SCORE_REL32) 2142 1.1.1.6 christos value = symbol + addend; 2143 1.1.1.6 christos else 2144 1.1.1.6 christos value = addend; 2145 1.1.1.6 christos } 2146 1.1 skrll value &= howto->dst_mask; 2147 1.1 skrll bfd_put_32 (input_bfd, value, hit_data); 2148 1.1 skrll return bfd_reloc_ok; 2149 1.1 skrll 2150 1.1 skrll case R_SCORE_ABS16: 2151 1.1 skrll value += addend; 2152 1.1 skrll if ((long)value > 0x7fff || (long)value < -0x8000) 2153 1.1.1.6 christos return bfd_reloc_overflow; 2154 1.1.1.2 christos score_bfd_put_16 (input_bfd, value, hit_data); 2155 1.1 skrll return bfd_reloc_ok; 2156 1.1 skrll 2157 1.1 skrll case R_SCORE_24: 2158 1.1.1.2 christos addend = score_bfd_get_32 (input_bfd, hit_data); 2159 1.1 skrll offset = (((addend & howto->src_mask) >> 1) & 0x1ff8000) | ((addend & howto->src_mask) & 0x7fff); 2160 1.1 skrll if ((offset & 0x1000000) != 0) 2161 1.1.1.6 christos offset |= 0xfe000000; 2162 1.1 skrll value += offset; 2163 1.1.1.4 christos abs_value = value - rel_addr; 2164 1.1.1.2 christos if ((abs_value & 0xfe000000) != 0) 2165 1.1.1.6 christos return bfd_reloc_overflow; 2166 1.1 skrll addend = (addend & ~howto->src_mask) 2167 1.1.1.6 christos | (((value << 1) & howto->src_mask) & 0x3ff0000) | (value & 0x7fff); 2168 1.1.1.2 christos score_bfd_put_32 (input_bfd, addend, hit_data); 2169 1.1 skrll return bfd_reloc_ok; 2170 1.1 skrll 2171 1.1.1.2 christos /* signed imm32. */ 2172 1.1.1.2 christos case R_SCORE_IMM30: 2173 1.1.1.2 christos { 2174 1.1.1.6 christos int not_word_align_p = 0; 2175 1.1.1.6 christos bfd_vma imm_offset = 0; 2176 1.1.1.6 christos addend = score_bfd_get_48 (input_bfd, hit_data); 2177 1.1.1.6 christos imm_offset = ((addend >> 7) & 0xff) 2178 1.1.1.6 christos | (((addend >> 16) & 0x7fff) << 8) 2179 1.1.1.6 christos | (((addend >> 32) & 0x7f) << 23); 2180 1.1.1.6 christos imm_offset <<= howto->rightshift; 2181 1.1.1.6 christos value += imm_offset; 2182 1.1.1.6 christos value &= 0xffffffff; 2183 1.1.1.6 christos 2184 1.1.1.6 christos /* Check lw48/sw48 rd, value/label word align. */ 2185 1.1.1.6 christos if ((value & 0x3) != 0) 2186 1.1.1.6 christos not_word_align_p = 1; 2187 1.1.1.6 christos 2188 1.1.1.6 christos value >>= howto->rightshift; 2189 1.1.1.6 christos addend = (addend & ~howto->src_mask) 2190 1.1.1.6 christos | (((value & 0xff) >> 0) << 7) 2191 1.1.1.6 christos | (((value & 0x7fff00) >> 8) << 16) 2192 1.1.1.6 christos | (((value & 0x3f800000) >> 23) << 32); 2193 1.1.1.6 christos score_bfd_put_48 (input_bfd, addend, hit_data); 2194 1.1.1.6 christos if (not_word_align_p) 2195 1.1.1.6 christos return bfd_reloc_other; 2196 1.1.1.6 christos else 2197 1.1.1.6 christos return bfd_reloc_ok; 2198 1.1.1.2 christos } 2199 1.1.1.2 christos 2200 1.1.1.2 christos case R_SCORE_IMM32: 2201 1.1.1.2 christos { 2202 1.1.1.6 christos bfd_vma imm_offset = 0; 2203 1.1.1.6 christos addend = score_bfd_get_48 (input_bfd, hit_data); 2204 1.1.1.6 christos imm_offset = ((addend >> 5) & 0x3ff) 2205 1.1.1.6 christos | (((addend >> 16) & 0x7fff) << 10) 2206 1.1.1.6 christos | (((addend >> 32) & 0x7f) << 25); 2207 1.1.1.6 christos value += imm_offset; 2208 1.1.1.6 christos value &= 0xffffffff; 2209 1.1.1.6 christos addend = (addend & ~howto->src_mask) 2210 1.1.1.6 christos | ((value & 0x3ff) << 5) 2211 1.1.1.6 christos | (((value >> 10) & 0x7fff) << 16) 2212 1.1.1.6 christos | (((value >> 25) & 0x7f) << 32); 2213 1.1.1.6 christos score_bfd_put_48 (input_bfd, addend, hit_data); 2214 1.1.1.6 christos return bfd_reloc_ok; 2215 1.1.1.2 christos } 2216 1.1.1.2 christos 2217 1.1 skrll case R_SCORE_PC19: 2218 1.1.1.2 christos addend = score_bfd_get_32 (input_bfd, hit_data); 2219 1.1 skrll offset = (((addend & howto->src_mask) & 0x3ff0000) >> 6) | ((addend & howto->src_mask) & 0x3ff); 2220 1.1 skrll if ((offset & 0x80000) != 0) 2221 1.1.1.6 christos offset |= 0xfff00000; 2222 1.1 skrll abs_value = value = value - rel_addr + offset; 2223 1.1 skrll /* exceed 20 bit : overflow. */ 2224 1.1 skrll if ((abs_value & 0x80000000) == 0x80000000) 2225 1.1.1.6 christos abs_value = 0xffffffff - value + 1; 2226 1.1 skrll if ((abs_value & 0xfff80000) != 0) 2227 1.1.1.6 christos return bfd_reloc_overflow; 2228 1.1 skrll addend = (addend & ~howto->src_mask) 2229 1.1.1.6 christos | (((value << 6) & howto->src_mask) & 0x3ff0000) | (value & 0x3ff); 2230 1.1.1.2 christos score_bfd_put_32 (input_bfd, addend, hit_data); 2231 1.1 skrll return bfd_reloc_ok; 2232 1.1 skrll 2233 1.1 skrll case R_SCORE16_11: 2234 1.1.1.2 christos addend = score_bfd_get_16 (input_bfd, hit_data); 2235 1.1 skrll offset = addend & howto->src_mask; 2236 1.1.1.6 christos if ((offset & 0x800) != 0) /* Offset is negative. */ 2237 1.1.1.6 christos offset |= 0xfffff000; 2238 1.1 skrll value += offset; 2239 1.1.1.4 christos abs_value = value - rel_addr; 2240 1.1.1.2 christos if ((abs_value & 0xfffff000) != 0) 2241 1.1.1.6 christos return bfd_reloc_overflow; 2242 1.1 skrll addend = (addend & ~howto->src_mask) | (value & howto->src_mask); 2243 1.1.1.2 christos score_bfd_put_16 (input_bfd, addend, hit_data); 2244 1.1 skrll return bfd_reloc_ok; 2245 1.1 skrll 2246 1.1 skrll case R_SCORE16_PC8: 2247 1.1.1.2 christos addend = score_bfd_get_16 (input_bfd, hit_data); 2248 1.1 skrll offset = (addend & howto->src_mask) << 1; 2249 1.1.1.6 christos if ((offset & 0x200) != 0) /* Offset is negative. */ 2250 1.1.1.6 christos offset |= 0xfffffe00; 2251 1.1 skrll abs_value = value = value - rel_addr + offset; 2252 1.1 skrll /* Sign bit + exceed 9 bit. */ 2253 1.1.1.2 christos if (((value & 0xfffffe00) != 0) && ((value & 0xfffffe00) != 0xfffffe00)) 2254 1.1.1.6 christos return bfd_reloc_overflow; 2255 1.1 skrll value >>= 1; 2256 1.1 skrll addend = (addend & ~howto->src_mask) | (value & howto->src_mask); 2257 1.1.1.2 christos score_bfd_put_16 (input_bfd, addend, hit_data); 2258 1.1.1.2 christos return bfd_reloc_ok; 2259 1.1.1.2 christos 2260 1.1.1.2 christos case R_SCORE_BCMP: 2261 1.1.1.2 christos addend = score_bfd_get_32 (input_bfd, hit_data); 2262 1.1.1.2 christos offset = (addend & howto->src_mask) << howto->rightshift; 2263 1.1.1.6 christos if ((offset & 0x200) != 0) /* Offset is negative. */ 2264 1.1.1.6 christos offset |= 0xfffffe00; 2265 1.1.1.2 christos value = value - rel_addr + offset; 2266 1.1.1.2 christos /* Sign bit + exceed 9 bit. */ 2267 1.1.1.2 christos if (((value & 0xfffffe00) != 0) && ((value & 0xfffffe00) != 0xfffffe00)) 2268 1.1.1.6 christos return bfd_reloc_overflow; 2269 1.1.1.2 christos value >>= howto->rightshift; 2270 1.1.1.2 christos addend = (addend & ~howto->src_mask) 2271 1.1.1.6 christos | (value & 0x1) 2272 1.1.1.6 christos | (((value >> 1) & 0x7) << 7) 2273 1.1.1.6 christos | (((value >> 4) & 0x1f) << 21); 2274 1.1.1.2 christos score_bfd_put_32 (input_bfd, addend, hit_data); 2275 1.1 skrll return bfd_reloc_ok; 2276 1.1 skrll 2277 1.1 skrll case R_SCORE_HI16: 2278 1.1 skrll return bfd_reloc_ok; 2279 1.1 skrll 2280 1.1 skrll case R_SCORE_LO16: 2281 1.1.1.2 christos hi16_addend = score_bfd_get_32 (input_bfd, hit_data - 4); 2282 1.1 skrll hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1; 2283 1.1.1.2 christos addend = score_bfd_get_32 (input_bfd, hit_data); 2284 1.1 skrll offset = ((((addend >> 16) & 0x3) << 15) | (addend & 0x7fff)) >> 1; 2285 1.1 skrll offset = (hi16_offset << 16) | (offset & 0xffff); 2286 1.1 skrll 2287 1.1 skrll if (!gp_disp_p) 2288 1.1.1.6 christos uvalue = value + offset; 2289 1.1 skrll else 2290 1.1.1.6 christos uvalue = offset + gp - rel_addr + 4; 2291 1.1 skrll 2292 1.1 skrll hi16_offset = (uvalue >> 16) << 1; 2293 1.1 skrll hi16_value = (hi16_addend & (~(howto->dst_mask))) 2294 1.1.1.6 christos | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000); 2295 1.1.1.2 christos score_bfd_put_32 (input_bfd, hi16_value, hit_data - 4); 2296 1.1 skrll offset = (uvalue & 0xffff) << 1; 2297 1.1 skrll value = (addend & (~(howto->dst_mask))) | (offset & 0x7fff) | ((offset << 1) & 0x30000); 2298 1.1.1.2 christos score_bfd_put_32 (input_bfd, value, hit_data); 2299 1.1 skrll return bfd_reloc_ok; 2300 1.1 skrll 2301 1.1 skrll case R_SCORE_GP15: 2302 1.1.1.2 christos addend = score_bfd_get_32 (input_bfd, hit_data); 2303 1.1 skrll offset = addend & 0x7fff; 2304 1.1 skrll if ((offset & 0x4000) == 0x4000) 2305 1.1.1.6 christos offset |= 0xffffc000; 2306 1.1 skrll value = value + offset - gp; 2307 1.1 skrll if (((value & 0xffffc000) != 0) && ((value & 0xffffc000) != 0xffffc000)) 2308 1.1.1.6 christos return bfd_reloc_overflow; 2309 1.1 skrll value = (addend & ~howto->src_mask) | (value & howto->src_mask); 2310 1.1.1.2 christos score_bfd_put_32 (input_bfd, value, hit_data); 2311 1.1 skrll return bfd_reloc_ok; 2312 1.1 skrll 2313 1.1 skrll case R_SCORE_GOT15: 2314 1.1 skrll case R_SCORE_CALL15: 2315 1.1 skrll if (local_p) 2316 1.1.1.6 christos { 2317 1.1.1.9 christos bool forced; 2318 1.1 skrll 2319 1.1.1.6 christos /* The special case is when the symbol is forced to be local. We need the 2320 1.1.1.6 christos full address in the GOT since no R_SCORE_GOT_LO16 relocation follows. */ 2321 1.1.1.6 christos forced = ! score_elf_local_relocation_p (input_bfd, rel, 2322 1.1.1.9 christos local_sections, false); 2323 1.1.1.6 christos value = score_elf_got16_entry (output_bfd, input_bfd, info, 2324 1.1.1.6 christos symbol + addend, forced); 2325 1.1.1.6 christos if (value == MINUS_ONE) 2326 1.1.1.6 christos return bfd_reloc_outofrange; 2327 1.1.1.6 christos value = score_elf_got_offset_from_index (elf_hash_table (info)->dynobj, 2328 1.1.1.6 christos output_bfd, input_bfd, value); 2329 1.1.1.6 christos } 2330 1.1 skrll else 2331 1.1.1.6 christos { 2332 1.1.1.6 christos value = g; 2333 1.1.1.6 christos } 2334 1.1 skrll 2335 1.1 skrll if ((long) value > 0x3fff || (long) value < -0x4000) 2336 1.1.1.6 christos return bfd_reloc_overflow; 2337 1.1 skrll 2338 1.1.1.2 christos addend = score_bfd_get_32 (input_bfd, hit_data); 2339 1.1 skrll value = (addend & ~howto->dst_mask) | (value & howto->dst_mask); 2340 1.1.1.2 christos score_bfd_put_32 (input_bfd, value, hit_data); 2341 1.1 skrll return bfd_reloc_ok; 2342 1.1 skrll 2343 1.1 skrll case R_SCORE_GPREL32: 2344 1.1 skrll value = (addend + symbol - gp); 2345 1.1 skrll value &= howto->dst_mask; 2346 1.1.1.2 christos score_bfd_put_32 (input_bfd, value, hit_data); 2347 1.1 skrll return bfd_reloc_ok; 2348 1.1 skrll 2349 1.1 skrll case R_SCORE_GOT_LO16: 2350 1.1.1.2 christos addend = score_bfd_get_32 (input_bfd, hit_data); 2351 1.1 skrll value = (((addend >> 16) & 0x3) << 14) | ((addend & 0x7fff) >> 1); 2352 1.1 skrll value += symbol; 2353 1.1.1.2 christos value = (addend & (~(howto->dst_mask))) | ((value & 0x3fff) << 1) 2354 1.1.1.6 christos | (((value >> 14) & 0x3) << 16); 2355 1.1 skrll 2356 1.1.1.2 christos score_bfd_put_32 (input_bfd, value, hit_data); 2357 1.1 skrll return bfd_reloc_ok; 2358 1.1 skrll 2359 1.1 skrll case R_SCORE_DUMMY_HI16: 2360 1.1 skrll return bfd_reloc_ok; 2361 1.1 skrll 2362 1.1 skrll case R_SCORE_GNU_VTINHERIT: 2363 1.1 skrll case R_SCORE_GNU_VTENTRY: 2364 1.1 skrll /* We don't do anything with these at present. */ 2365 1.1 skrll return bfd_reloc_continue; 2366 1.1 skrll 2367 1.1 skrll default: 2368 1.1 skrll return bfd_reloc_notsupported; 2369 1.1 skrll } 2370 1.1 skrll } 2371 1.1 skrll 2372 1.1 skrll /* Score backend functions. */ 2373 1.1.1.9 christos static bool 2374 1.1.1.9 christos s3_bfd_score_info_to_howto (bfd *abfd, 2375 1.1.1.6 christos arelent *bfd_reloc, 2376 1.1.1.6 christos Elf_Internal_Rela *elf_reloc) 2377 1.1 skrll { 2378 1.1 skrll unsigned int r_type; 2379 1.1 skrll 2380 1.1 skrll r_type = ELF32_R_TYPE (elf_reloc->r_info); 2381 1.1.1.2 christos if (r_type >= ARRAY_SIZE (elf32_score_howto_table)) 2382 1.1.1.9 christos { 2383 1.1.1.9 christos /* xgettext:c-format */ 2384 1.1.1.9 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 2385 1.1.1.9 christos abfd, r_type); 2386 1.1.1.9 christos bfd_set_error (bfd_error_bad_value); 2387 1.1.1.9 christos return false; 2388 1.1.1.9 christos } 2389 1.1.1.7 christos 2390 1.1.1.7 christos bfd_reloc->howto = &elf32_score_howto_table[r_type]; 2391 1.1.1.9 christos return true; 2392 1.1 skrll } 2393 1.1 skrll 2394 1.1 skrll /* Relocate an score ELF section. */ 2395 1.1.1.9 christos static int 2396 1.1.1.2 christos s3_bfd_score_elf_relocate_section (bfd *output_bfd, 2397 1.1.1.6 christos struct bfd_link_info *info, 2398 1.1.1.6 christos bfd *input_bfd, 2399 1.1.1.6 christos asection *input_section, 2400 1.1.1.6 christos bfd_byte *contents, 2401 1.1.1.6 christos Elf_Internal_Rela *relocs, 2402 1.1.1.6 christos Elf_Internal_Sym *local_syms, 2403 1.1.1.6 christos asection **local_sections) 2404 1.1 skrll { 2405 1.1 skrll Elf_Internal_Shdr *symtab_hdr; 2406 1.1 skrll Elf_Internal_Rela *rel; 2407 1.1 skrll Elf_Internal_Rela *relend; 2408 1.1 skrll const char *name; 2409 1.1 skrll unsigned long offset; 2410 1.1 skrll unsigned long hi16_addend, hi16_offset, hi16_value, uvalue; 2411 1.1 skrll size_t extsymoff; 2412 1.1.1.9 christos bool gp_disp_p = false; 2413 1.1 skrll 2414 1.1 skrll /* Sort dynsym. */ 2415 1.1 skrll if (elf_hash_table (info)->dynamic_sections_created) 2416 1.1 skrll { 2417 1.1 skrll bfd_size_type dynsecsymcount = 0; 2418 1.1.1.4 christos if (bfd_link_pic (info)) 2419 1.1.1.6 christos { 2420 1.1.1.6 christos asection * p; 2421 1.1.1.12 christos elf_backend_data *bed = get_elf_backend_data (output_bfd); 2422 1.1.1.6 christos 2423 1.1.1.6 christos for (p = output_bfd->sections; p ; p = p->next) 2424 1.1.1.6 christos if ((p->flags & SEC_EXCLUDE) == 0 2425 1.1.1.6 christos && (p->flags & SEC_ALLOC) != 0 2426 1.1.1.6 christos && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p)) 2427 1.1.1.6 christos ++ dynsecsymcount; 2428 1.1.1.6 christos } 2429 1.1 skrll 2430 1.1 skrll if (!score_elf_sort_hash_table (info, dynsecsymcount + 1)) 2431 1.1.1.9 christos return false; 2432 1.1 skrll } 2433 1.1 skrll 2434 1.1 skrll symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 2435 1.1.1.2 christos extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info; 2436 1.1 skrll rel = relocs; 2437 1.1 skrll relend = relocs + input_section->reloc_count; 2438 1.1 skrll for (; rel < relend; rel++) 2439 1.1 skrll { 2440 1.1 skrll int r_type; 2441 1.1 skrll reloc_howto_type *howto; 2442 1.1 skrll unsigned long r_symndx; 2443 1.1 skrll Elf_Internal_Sym *sym; 2444 1.1 skrll asection *sec; 2445 1.1 skrll struct score_elf_link_hash_entry *h; 2446 1.1 skrll bfd_vma relocation = 0; 2447 1.1 skrll bfd_reloc_status_type r; 2448 1.1 skrll arelent bfd_reloc; 2449 1.1 skrll 2450 1.1 skrll r_symndx = ELF32_R_SYM (rel->r_info); 2451 1.1 skrll r_type = ELF32_R_TYPE (rel->r_info); 2452 1.1 skrll 2453 1.1.1.7 christos if (! s3_bfd_score_info_to_howto (input_bfd, &bfd_reloc, (Elf_Internal_Rela *) rel)) 2454 1.1.1.7 christos continue; 2455 1.1 skrll howto = bfd_reloc.howto; 2456 1.1 skrll 2457 1.1 skrll h = NULL; 2458 1.1 skrll sym = NULL; 2459 1.1 skrll sec = NULL; 2460 1.1 skrll 2461 1.1 skrll if (r_symndx < extsymoff) 2462 1.1.1.6 christos { 2463 1.1.1.6 christos sym = local_syms + r_symndx; 2464 1.1.1.6 christos sec = local_sections[r_symndx]; 2465 1.1.1.6 christos relocation = (sec->output_section->vma 2466 1.1.1.6 christos + sec->output_offset 2467 1.1.1.6 christos + sym->st_value); 2468 1.1.1.6 christos name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, sec); 2469 1.1.1.6 christos 2470 1.1.1.6 christos if (!bfd_link_relocatable (info) 2471 1.1.1.6 christos && (sec->flags & SEC_MERGE) 2472 1.1.1.6 christos && ELF_ST_TYPE (sym->st_info) == STT_SECTION) 2473 1.1.1.6 christos { 2474 1.1.1.6 christos asection *msec; 2475 1.1.1.6 christos bfd_vma addend, value; 2476 1.1.1.6 christos 2477 1.1.1.6 christos switch (r_type) 2478 1.1.1.6 christos { 2479 1.1.1.6 christos case R_SCORE_HI16: 2480 1.1.1.6 christos break; 2481 1.1.1.6 christos case R_SCORE_LO16: 2482 1.1.1.6 christos hi16_addend = score_bfd_get_32 (input_bfd, contents + rel->r_offset - 4); 2483 1.1.1.6 christos hi16_offset = ((((hi16_addend >> 16) & 0x3) << 15) | (hi16_addend & 0x7fff)) >> 1; 2484 1.1.1.6 christos value = score_bfd_get_32 (input_bfd, contents + rel->r_offset); 2485 1.1.1.6 christos offset = ((((value >> 16) & 0x3) << 15) | (value & 0x7fff)) >> 1; 2486 1.1.1.6 christos addend = (hi16_offset << 16) | (offset & 0xffff); 2487 1.1.1.6 christos msec = sec; 2488 1.1.1.6 christos addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend); 2489 1.1.1.6 christos addend -= relocation; 2490 1.1.1.6 christos addend += msec->output_section->vma + msec->output_offset; 2491 1.1.1.6 christos uvalue = addend; 2492 1.1.1.6 christos hi16_offset = (uvalue >> 16) << 1; 2493 1.1.1.6 christos hi16_value = (hi16_addend & (~(howto->dst_mask))) 2494 1.1.1.6 christos | (hi16_offset & 0x7fff) | ((hi16_offset << 1) & 0x30000); 2495 1.1.1.6 christos score_bfd_put_32 (input_bfd, hi16_value, contents + rel->r_offset - 4); 2496 1.1.1.6 christos offset = (uvalue & 0xffff) << 1; 2497 1.1.1.6 christos value = (value & (~(howto->dst_mask))) 2498 1.1.1.6 christos | (offset & 0x7fff) | ((offset << 1) & 0x30000); 2499 1.1.1.6 christos score_bfd_put_32 (input_bfd, value, contents + rel->r_offset); 2500 1.1.1.6 christos break; 2501 1.1.1.6 christos 2502 1.1.1.6 christos case R_SCORE_IMM32: 2503 1.1.1.6 christos { 2504 1.1.1.6 christos value = score_bfd_get_48 (input_bfd, contents + rel->r_offset); 2505 1.1.1.6 christos addend = ((value >> 5) & 0x3ff) 2506 1.1.1.6 christos | (((value >> 16) & 0x7fff) << 10) 2507 1.1.1.6 christos | (((value >> 32) & 0x7f) << 25); 2508 1.1.1.6 christos msec = sec; 2509 1.1.1.6 christos addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend); 2510 1.1.1.6 christos addend -= relocation; 2511 1.1.1.6 christos addend += msec->output_section->vma + msec->output_offset; 2512 1.1.1.6 christos addend &= 0xffffffff; 2513 1.1.1.6 christos value = (value & ~howto->src_mask) 2514 1.1.1.6 christos | ((addend & 0x3ff) << 5) 2515 1.1.1.6 christos | (((addend >> 10) & 0x7fff) << 16) 2516 1.1.1.6 christos | (((addend >> 25) & 0x7f) << 32); 2517 1.1.1.6 christos score_bfd_put_48 (input_bfd, value, contents + rel->r_offset); 2518 1.1.1.6 christos break; 2519 1.1.1.6 christos } 2520 1.1.1.6 christos 2521 1.1.1.6 christos case R_SCORE_IMM30: 2522 1.1.1.6 christos { 2523 1.1.1.6 christos int not_word_align_p = 0; 2524 1.1.1.6 christos value = score_bfd_get_48 (input_bfd, contents + rel->r_offset); 2525 1.1.1.6 christos addend = ((value >> 7) & 0xff) 2526 1.1.1.6 christos | (((value >> 16) & 0x7fff) << 8) 2527 1.1.1.6 christos | (((value >> 32) & 0x7f) << 23); 2528 1.1.1.6 christos addend <<= howto->rightshift; 2529 1.1.1.6 christos msec = sec; 2530 1.1.1.6 christos addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend); 2531 1.1.1.6 christos addend -= relocation; 2532 1.1.1.6 christos addend += msec->output_section->vma + msec->output_offset; 2533 1.1.1.6 christos addend &= 0xffffffff; 2534 1.1.1.6 christos 2535 1.1.1.6 christos /* Check lw48/sw48 rd, value/label word align. */ 2536 1.1.1.6 christos if ((addend & 0x3) != 0) 2537 1.1.1.6 christos not_word_align_p = 1; 2538 1.1.1.6 christos 2539 1.1.1.6 christos addend >>= howto->rightshift; 2540 1.1.1.6 christos value = (value & ~howto->src_mask) 2541 1.1.1.6 christos | (((addend & 0xff) >> 0) << 7) 2542 1.1.1.6 christos | (((addend & 0x7fff00) >> 8) << 16) 2543 1.1.1.6 christos | (((addend & 0x3f800000) >> 23) << 32); 2544 1.1.1.6 christos score_bfd_put_48 (input_bfd, value, contents + rel->r_offset); 2545 1.1.1.6 christos 2546 1.1.1.6 christos if (not_word_align_p) 2547 1.1.1.6 christos return bfd_reloc_other; 2548 1.1.1.6 christos else 2549 1.1.1.6 christos break; 2550 1.1.1.6 christos } 2551 1.1.1.6 christos 2552 1.1.1.6 christos case R_SCORE_GOT_LO16: 2553 1.1.1.6 christos value = score_bfd_get_32 (input_bfd, contents + rel->r_offset); 2554 1.1.1.6 christos addend = (((value >> 16) & 0x3) << 14) | ((value & 0x7fff) >> 1); 2555 1.1.1.6 christos msec = sec; 2556 1.1.1.6 christos addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation; 2557 1.1.1.6 christos addend += msec->output_section->vma + msec->output_offset; 2558 1.1.1.6 christos value = (value & (~(howto->dst_mask))) | ((addend & 0x3fff) << 1) 2559 1.1.1.6 christos | (((addend >> 14) & 0x3) << 16); 2560 1.1.1.6 christos 2561 1.1.1.6 christos score_bfd_put_32 (input_bfd, value, contents + rel->r_offset); 2562 1.1.1.6 christos break; 2563 1.1.1.6 christos 2564 1.1.1.6 christos case R_SCORE_ABS32: 2565 1.1.1.6 christos case R_SCORE_REL32: 2566 1.1.1.6 christos value = bfd_get_32 (input_bfd, contents + rel->r_offset); 2567 1.1.1.6 christos /* Get the (signed) value from the instruction. */ 2568 1.1.1.6 christos addend = value & howto->src_mask; 2569 1.1.1.6 christos if (addend & ((howto->src_mask + 1) >> 1)) 2570 1.1.1.6 christos { 2571 1.1.1.6 christos bfd_signed_vma mask; 2572 1.1.1.6 christos 2573 1.1.1.6 christos mask = -1; 2574 1.1.1.6 christos mask &= ~howto->src_mask; 2575 1.1.1.6 christos addend |= mask; 2576 1.1.1.6 christos } 2577 1.1.1.6 christos msec = sec; 2578 1.1.1.6 christos addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation; 2579 1.1.1.6 christos addend += msec->output_section->vma + msec->output_offset; 2580 1.1.1.6 christos value = (value & ~howto->dst_mask) | (addend & howto->dst_mask); 2581 1.1.1.6 christos bfd_put_32 (input_bfd, value, contents + rel->r_offset); 2582 1.1.1.6 christos break; 2583 1.1.1.6 christos 2584 1.1.1.6 christos default: 2585 1.1.1.6 christos value = score_bfd_get_32 (input_bfd, contents + rel->r_offset); 2586 1.1.1.6 christos /* Get the (signed) value from the instruction. */ 2587 1.1.1.6 christos addend = value & howto->src_mask; 2588 1.1.1.6 christos if (addend & ((howto->src_mask + 1) >> 1)) 2589 1.1.1.6 christos { 2590 1.1.1.6 christos bfd_signed_vma mask; 2591 1.1.1.6 christos 2592 1.1.1.6 christos mask = -1; 2593 1.1.1.6 christos mask &= ~howto->src_mask; 2594 1.1.1.6 christos addend |= mask; 2595 1.1.1.6 christos } 2596 1.1.1.6 christos msec = sec; 2597 1.1.1.6 christos addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend) - relocation; 2598 1.1.1.6 christos addend += msec->output_section->vma + msec->output_offset; 2599 1.1.1.6 christos value = (value & ~howto->dst_mask) | (addend & howto->dst_mask); 2600 1.1.1.6 christos score_bfd_put_32 (input_bfd, value, contents + rel->r_offset); 2601 1.1.1.6 christos break; 2602 1.1.1.6 christos } 2603 1.1.1.6 christos } 2604 1.1.1.6 christos } 2605 1.1 skrll else 2606 1.1.1.6 christos { 2607 1.1.1.6 christos /* For global symbols we look up the symbol in the hash-table. */ 2608 1.1.1.6 christos h = ((struct score_elf_link_hash_entry *) 2609 1.1.1.6 christos elf_sym_hashes (input_bfd) [r_symndx - extsymoff]); 2610 1.1.1.4 christos 2611 1.1.1.4 christos if (info->wrap_hash != NULL 2612 1.1.1.4 christos && (input_section->flags & SEC_DEBUGGING) != 0) 2613 1.1.1.4 christos h = ((struct score_elf_link_hash_entry *) 2614 1.1.1.4 christos unwrap_hash_lookup (info, input_bfd, &h->root.root)); 2615 1.1.1.4 christos 2616 1.1.1.6 christos /* Find the real hash-table entry for this symbol. */ 2617 1.1.1.6 christos while (h->root.root.type == bfd_link_hash_indirect 2618 1.1.1.6 christos || h->root.root.type == bfd_link_hash_warning) 2619 1.1.1.6 christos h = (struct score_elf_link_hash_entry *) h->root.root.u.i.link; 2620 1.1.1.6 christos 2621 1.1.1.6 christos /* Record the name of this symbol, for our caller. */ 2622 1.1.1.6 christos name = h->root.root.root.string; 2623 1.1.1.6 christos 2624 1.1.1.6 christos /* See if this is the special GP_DISP_LABEL symbol. Note that such a 2625 1.1.1.6 christos symbol must always be a global symbol. */ 2626 1.1.1.6 christos if (strcmp (name, GP_DISP_LABEL) == 0) 2627 1.1.1.6 christos { 2628 1.1.1.6 christos /* Relocations against GP_DISP_LABEL are permitted only with 2629 1.1.1.6 christos R_SCORE_HI16 and R_SCORE_LO16 relocations. */ 2630 1.1.1.6 christos if (r_type != R_SCORE_HI16 && r_type != R_SCORE_LO16) 2631 1.1.1.6 christos return bfd_reloc_notsupported; 2632 1.1.1.6 christos 2633 1.1.1.9 christos gp_disp_p = true; 2634 1.1.1.6 christos } 2635 1.1.1.6 christos 2636 1.1.1.6 christos /* If this symbol is defined, calculate its address. Note that 2637 1.1.1.6 christos GP_DISP_LABEL is a magic symbol, always implicitly defined by the 2638 1.1.1.6 christos linker, so it's inappropriate to check to see whether or not 2639 1.1.1.6 christos its defined. */ 2640 1.1.1.6 christos else if ((h->root.root.type == bfd_link_hash_defined 2641 1.1.1.6 christos || h->root.root.type == bfd_link_hash_defweak) 2642 1.1.1.6 christos && h->root.root.u.def.section) 2643 1.1.1.6 christos { 2644 1.1.1.6 christos sec = h->root.root.u.def.section; 2645 1.1.1.6 christos if (sec->output_section) 2646 1.1.1.6 christos relocation = (h->root.root.u.def.value 2647 1.1.1.6 christos + sec->output_section->vma 2648 1.1.1.6 christos + sec->output_offset); 2649 1.1.1.6 christos else 2650 1.1.1.6 christos { 2651 1.1.1.6 christos relocation = h->root.root.u.def.value; 2652 1.1.1.6 christos } 2653 1.1.1.6 christos } 2654 1.1.1.6 christos else if (h->root.root.type == bfd_link_hash_undefweak) 2655 1.1.1.6 christos /* We allow relocations against undefined weak symbols, giving 2656 1.1.1.6 christos it the value zero, so that you can undefined weak functions 2657 1.1.1.6 christos and check to see if they exist by looking at their addresses. */ 2658 1.1.1.6 christos relocation = 0; 2659 1.1.1.6 christos else if (info->unresolved_syms_in_objects == RM_IGNORE 2660 1.1.1.6 christos && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT) 2661 1.1.1.6 christos relocation = 0; 2662 1.1.1.6 christos else if (strcmp (name, "_DYNAMIC_LINK") == 0) 2663 1.1.1.6 christos { 2664 1.1.1.6 christos /* If this is a dynamic link, we should have created a _DYNAMIC_LINK symbol 2665 1.1.1.6 christos in s3_bfd_score_elf_create_dynamic_sections. Otherwise, we should define 2666 1.1.1.6 christos the symbol with a value of 0. */ 2667 1.1.1.6 christos BFD_ASSERT (! bfd_link_pic (info)); 2668 1.1.1.6 christos BFD_ASSERT (bfd_get_section_by_name (output_bfd, ".dynamic") == NULL); 2669 1.1.1.6 christos relocation = 0; 2670 1.1.1.6 christos } 2671 1.1.1.6 christos else if (!bfd_link_relocatable (info)) 2672 1.1.1.6 christos { 2673 1.1.1.9 christos info->callbacks->undefined_symbol 2674 1.1.1.9 christos (info, h->root.root.root.string, input_bfd, input_section, 2675 1.1.1.9 christos rel->r_offset, 2676 1.1.1.9 christos (info->unresolved_syms_in_objects == RM_DIAGNOSE 2677 1.1.1.9 christos && !info->warn_unresolved_syms) 2678 1.1.1.5 christos || ELF_ST_VISIBILITY (h->root.other)); 2679 1.1.1.9 christos relocation = 0; 2680 1.1.1.9 christos } 2681 1.1.1.6 christos } 2682 1.1 skrll 2683 1.1.1.3 christos if (sec != NULL && discarded_section (sec)) 2684 1.1.1.2 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, 2685 1.1.1.12 christos rel, 1, relend, R_SCORE_NONE, 2686 1.1.1.12 christos howto, 0, contents); 2687 1.1 skrll 2688 1.1.1.4 christos if (bfd_link_relocatable (info)) 2689 1.1.1.6 christos { 2690 1.1.1.6 christos /* This is a relocatable link. We don't have to change 2691 1.1.1.6 christos anything, unless the reloc is against a section symbol, 2692 1.1.1.6 christos in which case we have to adjust according to where the 2693 1.1.1.6 christos section symbol winds up in the output section. */ 2694 1.1.1.6 christos if (r_symndx < symtab_hdr->sh_info) 2695 1.1.1.6 christos { 2696 1.1.1.6 christos sym = local_syms + r_symndx; 2697 1.1.1.6 christos if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) 2698 1.1.1.6 christos { 2699 1.1.1.6 christos sec = local_sections[r_symndx]; 2700 1.1.1.6 christos score_elf_add_to_rel (input_bfd, contents + rel->r_offset, 2701 1.1.1.6 christos howto, (bfd_signed_vma) (sec->output_offset + sym->st_value)); 2702 1.1.1.6 christos } 2703 1.1.1.6 christos } 2704 1.1.1.6 christos continue; 2705 1.1.1.6 christos } 2706 1.1 skrll 2707 1.1.1.2 christos /* This is a final link. */ 2708 1.1 skrll r = score_elf_final_link_relocate (howto, input_bfd, output_bfd, 2709 1.1.1.6 christos input_section, contents, rel, relocs, 2710 1.1.1.6 christos relocation, info, name, 2711 1.1.1.6 christos (h ? ELF_ST_TYPE ((unsigned int)h->root.root.type) : 2712 1.1.1.6 christos ELF_ST_TYPE ((unsigned int)sym->st_info)), h, local_sections, 2713 1.1.1.6 christos gp_disp_p); 2714 1.1 skrll 2715 1.1 skrll if (r != bfd_reloc_ok) 2716 1.1.1.6 christos { 2717 1.1.1.6 christos const char *msg = (const char *)0; 2718 1.1 skrll 2719 1.1.1.6 christos switch (r) 2720 1.1.1.6 christos { 2721 1.1.1.6 christos case bfd_reloc_overflow: 2722 1.1.1.6 christos /* If the overflowing reloc was to an undefined symbol, 2723 1.1.1.6 christos we have already printed one error message and there 2724 1.1.1.6 christos is no point complaining again. */ 2725 1.1.1.5 christos if (!h || h->root.root.type != bfd_link_hash_undefined) 2726 1.1.1.5 christos (*info->callbacks->reloc_overflow) 2727 1.1.1.5 christos (info, NULL, name, howto->name, (bfd_vma) 0, 2728 1.1.1.5 christos input_bfd, input_section, rel->r_offset); 2729 1.1.1.6 christos break; 2730 1.1.1.6 christos case bfd_reloc_undefined: 2731 1.1.1.5 christos (*info->callbacks->undefined_symbol) 2732 1.1.1.9 christos (info, name, input_bfd, input_section, rel->r_offset, true); 2733 1.1.1.6 christos break; 2734 1.1 skrll 2735 1.1.1.6 christos case bfd_reloc_outofrange: 2736 1.1.1.6 christos msg = _("internal error: out of range error"); 2737 1.1.1.6 christos goto common_error; 2738 1.1.1.6 christos 2739 1.1.1.6 christos case bfd_reloc_notsupported: 2740 1.1.1.6 christos msg = _("internal error: unsupported relocation error"); 2741 1.1.1.6 christos goto common_error; 2742 1.1.1.6 christos 2743 1.1.1.6 christos case bfd_reloc_dangerous: 2744 1.1.1.6 christos msg = _("internal error: dangerous error"); 2745 1.1.1.6 christos goto common_error; 2746 1.1.1.6 christos 2747 1.1.1.6 christos /* Use bfd_reloc_other to check lw48, sw48 word align. */ 2748 1.1.1.6 christos case bfd_reloc_other: 2749 1.1.1.7 christos msg = _("address not word aligned"); 2750 1.1.1.6 christos goto common_error; 2751 1.1.1.6 christos 2752 1.1.1.6 christos default: 2753 1.1.1.6 christos msg = _("internal error: unknown error"); 2754 1.1.1.6 christos /* Fall through. */ 2755 1.1 skrll 2756 1.1.1.6 christos common_error: 2757 1.1.1.5 christos (*info->callbacks->warning) (info, msg, name, input_bfd, 2758 1.1.1.5 christos input_section, rel->r_offset); 2759 1.1.1.6 christos break; 2760 1.1.1.6 christos } 2761 1.1.1.6 christos } 2762 1.1 skrll } 2763 1.1 skrll 2764 1.1.1.9 christos return true; 2765 1.1 skrll } 2766 1.1 skrll 2767 1.1 skrll /* Look through the relocs for a section during the first phase, and 2768 1.1 skrll allocate space in the global offset table. */ 2769 1.1.1.9 christos static bool 2770 1.1.1.2 christos s3_bfd_score_elf_check_relocs (bfd *abfd, 2771 1.1.1.6 christos struct bfd_link_info *info, 2772 1.1.1.6 christos asection *sec, 2773 1.1.1.6 christos const Elf_Internal_Rela *relocs) 2774 1.1 skrll { 2775 1.1 skrll bfd *dynobj; 2776 1.1 skrll Elf_Internal_Shdr *symtab_hdr; 2777 1.1 skrll struct elf_link_hash_entry **sym_hashes; 2778 1.1 skrll struct score_got_info *g; 2779 1.1 skrll size_t extsymoff; 2780 1.1 skrll const Elf_Internal_Rela *rel; 2781 1.1 skrll const Elf_Internal_Rela *rel_end; 2782 1.1 skrll asection *sgot; 2783 1.1 skrll asection *sreloc; 2784 1.1 skrll 2785 1.1.1.4 christos if (bfd_link_relocatable (info)) 2786 1.1.1.9 christos return true; 2787 1.1 skrll 2788 1.1 skrll dynobj = elf_hash_table (info)->dynobj; 2789 1.1 skrll symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 2790 1.1 skrll sym_hashes = elf_sym_hashes (abfd); 2791 1.1.1.2 christos extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info; 2792 1.1 skrll 2793 1.1 skrll if (dynobj == NULL) 2794 1.1 skrll { 2795 1.1 skrll sgot = NULL; 2796 1.1 skrll g = NULL; 2797 1.1 skrll } 2798 1.1 skrll else 2799 1.1 skrll { 2800 1.1.1.9 christos sgot = score_elf_got_section (dynobj, false); 2801 1.1 skrll if (sgot == NULL) 2802 1.1.1.6 christos g = NULL; 2803 1.1 skrll else 2804 1.1.1.6 christos { 2805 1.1.1.6 christos BFD_ASSERT (score_elf_section_data (sgot) != NULL); 2806 1.1.1.6 christos g = score_elf_section_data (sgot)->u.got_info; 2807 1.1.1.6 christos BFD_ASSERT (g != NULL); 2808 1.1.1.6 christos } 2809 1.1 skrll } 2810 1.1 skrll 2811 1.1 skrll sreloc = NULL; 2812 1.1.1.6 christos rel_end = relocs + sec->reloc_count; 2813 1.1 skrll for (rel = relocs; rel < rel_end; ++rel) 2814 1.1 skrll { 2815 1.1 skrll unsigned long r_symndx; 2816 1.1 skrll unsigned int r_type; 2817 1.1 skrll struct elf_link_hash_entry *h; 2818 1.1 skrll 2819 1.1 skrll r_symndx = ELF32_R_SYM (rel->r_info); 2820 1.1 skrll r_type = ELF32_R_TYPE (rel->r_info); 2821 1.1 skrll 2822 1.1 skrll if (r_symndx < extsymoff) 2823 1.1.1.6 christos { 2824 1.1.1.6 christos h = NULL; 2825 1.1.1.6 christos } 2826 1.1 skrll else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr)) 2827 1.1.1.6 christos { 2828 1.1.1.6 christos _bfd_error_handler 2829 1.1.1.6 christos /* xgettext:c-format */ 2830 1.1.1.7 christos (_("%pB: malformed reloc detected for section %pA"), abfd, sec); 2831 1.1.1.6 christos bfd_set_error (bfd_error_bad_value); 2832 1.1.1.9 christos return false; 2833 1.1.1.6 christos } 2834 1.1 skrll else 2835 1.1.1.6 christos { 2836 1.1.1.6 christos h = sym_hashes[r_symndx - extsymoff]; 2837 1.1 skrll 2838 1.1.1.6 christos /* This may be an indirect symbol created because of a version. */ 2839 1.1.1.6 christos if (h != NULL) 2840 1.1.1.6 christos { 2841 1.1.1.6 christos while (h->root.type == bfd_link_hash_indirect) 2842 1.1.1.6 christos h = (struct elf_link_hash_entry *)h->root.u.i.link; 2843 1.1.1.6 christos } 2844 1.1.1.6 christos } 2845 1.1 skrll 2846 1.1 skrll /* Some relocs require a global offset table. */ 2847 1.1 skrll if (dynobj == NULL || sgot == NULL) 2848 1.1.1.6 christos { 2849 1.1.1.6 christos switch (r_type) 2850 1.1.1.6 christos { 2851 1.1.1.6 christos case R_SCORE_GOT15: 2852 1.1.1.6 christos case R_SCORE_CALL15: 2853 1.1.1.6 christos if (dynobj == NULL) 2854 1.1.1.6 christos elf_hash_table (info)->dynobj = dynobj = abfd; 2855 1.1.1.9 christos if (!score_elf_create_got_section (dynobj, info, false)) 2856 1.1.1.9 christos return false; 2857 1.1.1.6 christos g = score_elf_got_info (dynobj, &sgot); 2858 1.1.1.6 christos break; 2859 1.1.1.6 christos case R_SCORE_ABS32: 2860 1.1.1.6 christos case R_SCORE_REL32: 2861 1.1.1.6 christos if (dynobj == NULL 2862 1.1.1.4 christos && (bfd_link_pic (info) || h != NULL) 2863 1.1.1.4 christos && (sec->flags & SEC_ALLOC) != 0) 2864 1.1.1.6 christos elf_hash_table (info)->dynobj = dynobj = abfd; 2865 1.1.1.6 christos break; 2866 1.1.1.6 christos default: 2867 1.1.1.6 christos break; 2868 1.1.1.6 christos } 2869 1.1.1.6 christos } 2870 1.1 skrll 2871 1.1 skrll if (!h && (r_type == R_SCORE_GOT_LO16)) 2872 1.1.1.6 christos { 2873 1.1.1.6 christos if (! score_elf_record_local_got_symbol (abfd, r_symndx, rel->r_addend, g)) 2874 1.1.1.9 christos return false; 2875 1.1.1.6 christos } 2876 1.1 skrll 2877 1.1 skrll switch (r_type) 2878 1.1.1.6 christos { 2879 1.1.1.6 christos case R_SCORE_CALL15: 2880 1.1.1.6 christos if (h == NULL) 2881 1.1.1.6 christos { 2882 1.1.1.6 christos _bfd_error_handler 2883 1.1.1.6 christos /* xgettext:c-format */ 2884 1.1.1.7 christos (_("%pB: CALL15 reloc at %#" PRIx64 " not against global symbol"), 2885 1.1.1.7 christos abfd, (uint64_t) rel->r_offset); 2886 1.1.1.6 christos bfd_set_error (bfd_error_bad_value); 2887 1.1.1.9 christos return false; 2888 1.1.1.6 christos } 2889 1.1.1.6 christos else 2890 1.1.1.6 christos { 2891 1.1.1.6 christos /* This symbol requires a global offset table entry. */ 2892 1.1.1.6 christos if (! score_elf_record_global_got_symbol (h, abfd, info, g)) 2893 1.1.1.9 christos return false; 2894 1.1.1.6 christos 2895 1.1.1.6 christos /* We need a stub, not a plt entry for the undefined function. But we record 2896 1.1.1.6 christos it as if it needs plt. See _bfd_elf_adjust_dynamic_symbol. */ 2897 1.1.1.6 christos h->needs_plt = 1; 2898 1.1.1.6 christos h->type = STT_FUNC; 2899 1.1.1.6 christos } 2900 1.1.1.6 christos break; 2901 1.1.1.6 christos case R_SCORE_GOT15: 2902 1.1.1.6 christos if (h && ! score_elf_record_global_got_symbol (h, abfd, info, g)) 2903 1.1.1.9 christos return false; 2904 1.1.1.6 christos break; 2905 1.1.1.6 christos case R_SCORE_ABS32: 2906 1.1.1.6 christos case R_SCORE_REL32: 2907 1.1.1.6 christos if ((bfd_link_pic (info) || h != NULL) 2908 1.1.1.4 christos && (sec->flags & SEC_ALLOC) != 0) 2909 1.1.1.6 christos { 2910 1.1.1.6 christos if (sreloc == NULL) 2911 1.1.1.6 christos { 2912 1.1.1.9 christos sreloc = score_elf_rel_dyn_section (dynobj, true); 2913 1.1.1.6 christos if (sreloc == NULL) 2914 1.1.1.9 christos return false; 2915 1.1.1.6 christos } 2916 1.1 skrll #define SCORE_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY) 2917 1.1.1.6 christos if (bfd_link_pic (info)) 2918 1.1.1.6 christos { 2919 1.1.1.6 christos /* When creating a shared object, we must copy these reloc types into 2920 1.1.1.6 christos the output file as R_SCORE_REL32 relocs. We make room for this reloc 2921 1.1.1.6 christos in the .rel.dyn reloc section. */ 2922 1.1.1.6 christos score_elf_allocate_dynamic_relocations (dynobj, 1); 2923 1.1.1.6 christos if ((sec->flags & SCORE_READONLY_SECTION) 2924 1.1.1.6 christos == SCORE_READONLY_SECTION) 2925 1.1.1.6 christos /* We tell the dynamic linker that there are 2926 1.1.1.6 christos relocations against the text segment. */ 2927 1.1.1.6 christos info->flags |= DF_TEXTREL; 2928 1.1.1.6 christos } 2929 1.1.1.6 christos else 2930 1.1.1.6 christos { 2931 1.1.1.6 christos struct score_elf_link_hash_entry *hscore; 2932 1.1.1.6 christos 2933 1.1.1.6 christos /* We only need to copy this reloc if the symbol is 2934 1.1.1.6 christos defined in a dynamic object. */ 2935 1.1.1.6 christos hscore = (struct score_elf_link_hash_entry *)h; 2936 1.1.1.6 christos ++hscore->possibly_dynamic_relocs; 2937 1.1.1.6 christos if ((sec->flags & SCORE_READONLY_SECTION) 2938 1.1.1.6 christos == SCORE_READONLY_SECTION) 2939 1.1.1.6 christos /* We need it to tell the dynamic linker if there 2940 1.1.1.6 christos are relocations against the text segment. */ 2941 1.1.1.9 christos hscore->readonly_reloc = true; 2942 1.1.1.6 christos } 2943 1.1.1.6 christos 2944 1.1.1.6 christos /* Even though we don't directly need a GOT entry for this symbol, 2945 1.1.1.6 christos a symbol must have a dynamic symbol table index greater that 2946 1.1.1.6 christos DT_SCORE_GOTSYM if there are dynamic relocations against it. */ 2947 1.1.1.6 christos if (h != NULL) 2948 1.1.1.6 christos { 2949 1.1.1.6 christos if (dynobj == NULL) 2950 1.1.1.6 christos elf_hash_table (info)->dynobj = dynobj = abfd; 2951 1.1.1.9 christos if (! score_elf_create_got_section (dynobj, info, true)) 2952 1.1.1.9 christos return false; 2953 1.1.1.6 christos g = score_elf_got_info (dynobj, &sgot); 2954 1.1.1.6 christos if (! score_elf_record_global_got_symbol (h, abfd, info, g)) 2955 1.1.1.9 christos return false; 2956 1.1.1.6 christos } 2957 1.1.1.6 christos } 2958 1.1.1.6 christos break; 2959 1.1.1.6 christos 2960 1.1.1.6 christos /* This relocation describes the C++ object vtable hierarchy. 2961 1.1.1.6 christos Reconstruct it for later use during GC. */ 2962 1.1.1.6 christos case R_SCORE_GNU_VTINHERIT: 2963 1.1.1.6 christos if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) 2964 1.1.1.9 christos return false; 2965 1.1.1.6 christos break; 2966 1.1.1.6 christos 2967 1.1.1.6 christos /* This relocation describes which C++ vtable entries are actually 2968 1.1.1.6 christos used. Record for later use during GC. */ 2969 1.1.1.6 christos case R_SCORE_GNU_VTENTRY: 2970 1.1.1.6 christos if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset)) 2971 1.1.1.9 christos return false; 2972 1.1.1.6 christos break; 2973 1.1.1.6 christos default: 2974 1.1.1.6 christos break; 2975 1.1.1.6 christos } 2976 1.1 skrll 2977 1.1 skrll /* We must not create a stub for a symbol that has relocations 2978 1.1.1.6 christos related to taking the function's address. */ 2979 1.1 skrll switch (r_type) 2980 1.1.1.6 christos { 2981 1.1.1.6 christos default: 2982 1.1.1.6 christos if (h != NULL) 2983 1.1.1.6 christos { 2984 1.1.1.6 christos struct score_elf_link_hash_entry *sh; 2985 1.1.1.6 christos 2986 1.1.1.6 christos sh = (struct score_elf_link_hash_entry *) h; 2987 1.1.1.9 christos sh->no_fn_stub = true; 2988 1.1.1.6 christos } 2989 1.1.1.6 christos break; 2990 1.1.1.6 christos case R_SCORE_CALL15: 2991 1.1.1.6 christos break; 2992 1.1.1.6 christos } 2993 1.1 skrll } 2994 1.1 skrll 2995 1.1.1.9 christos return true; 2996 1.1 skrll } 2997 1.1 skrll 2998 1.1.1.9 christos static bool 2999 1.1.1.2 christos s3_bfd_score_elf_add_symbol_hook (bfd *abfd, 3000 1.1.1.6 christos struct bfd_link_info *info ATTRIBUTE_UNUSED, 3001 1.1.1.6 christos Elf_Internal_Sym *sym, 3002 1.1.1.6 christos const char **namep ATTRIBUTE_UNUSED, 3003 1.1.1.6 christos flagword *flagsp ATTRIBUTE_UNUSED, 3004 1.1.1.6 christos asection **secp, 3005 1.1.1.6 christos bfd_vma *valp) 3006 1.1 skrll { 3007 1.1 skrll switch (sym->st_shndx) 3008 1.1 skrll { 3009 1.1 skrll case SHN_COMMON: 3010 1.1 skrll if (sym->st_size > elf_gp_size (abfd)) 3011 1.1.1.6 christos break; 3012 1.1 skrll /* Fall through. */ 3013 1.1 skrll case SHN_SCORE_SCOMMON: 3014 1.1 skrll *secp = bfd_make_section_old_way (abfd, ".scommon"); 3015 1.1.1.9 christos (*secp)->flags |= SEC_IS_COMMON | SEC_SMALL_DATA; 3016 1.1 skrll *valp = sym->st_size; 3017 1.1 skrll break; 3018 1.1 skrll } 3019 1.1 skrll 3020 1.1.1.9 christos return true; 3021 1.1 skrll } 3022 1.1 skrll 3023 1.1 skrll static void 3024 1.1.1.2 christos s3_bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym) 3025 1.1 skrll { 3026 1.1 skrll elf_symbol_type *elfsym; 3027 1.1 skrll 3028 1.1 skrll elfsym = (elf_symbol_type *) asym; 3029 1.1 skrll switch (elfsym->internal_elf_sym.st_shndx) 3030 1.1 skrll { 3031 1.1 skrll case SHN_COMMON: 3032 1.1 skrll if (asym->value > elf_gp_size (abfd)) 3033 1.1.1.6 christos break; 3034 1.1 skrll /* Fall through. */ 3035 1.1 skrll case SHN_SCORE_SCOMMON: 3036 1.1 skrll asym->section = &score_elf_scom_section; 3037 1.1 skrll asym->value = elfsym->internal_elf_sym.st_size; 3038 1.1 skrll break; 3039 1.1 skrll } 3040 1.1 skrll } 3041 1.1 skrll 3042 1.1.1.2 christos static int 3043 1.1.1.2 christos s3_bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED, 3044 1.1.1.6 christos const char *name ATTRIBUTE_UNUSED, 3045 1.1.1.6 christos Elf_Internal_Sym *sym, 3046 1.1.1.6 christos asection *input_sec, 3047 1.1.1.6 christos struct elf_link_hash_entry *h ATTRIBUTE_UNUSED) 3048 1.1 skrll { 3049 1.1 skrll /* If we see a common symbol, which implies a relocatable link, then 3050 1.1 skrll if a symbol was small common in an input file, mark it as small 3051 1.1 skrll common in the output file. */ 3052 1.1 skrll if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0) 3053 1.1 skrll sym->st_shndx = SHN_SCORE_SCOMMON; 3054 1.1 skrll 3055 1.1.1.2 christos return 1; 3056 1.1 skrll } 3057 1.1 skrll 3058 1.1.1.9 christos static bool 3059 1.1.1.2 christos s3_bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED, 3060 1.1.1.6 christos asection *sec, 3061 1.1.1.6 christos int *retval) 3062 1.1 skrll { 3063 1.1.1.8 christos if (strcmp (bfd_section_name (sec), ".scommon") == 0) 3064 1.1 skrll { 3065 1.1 skrll *retval = SHN_SCORE_SCOMMON; 3066 1.1.1.9 christos return true; 3067 1.1 skrll } 3068 1.1 skrll 3069 1.1.1.9 christos return false; 3070 1.1 skrll } 3071 1.1 skrll 3072 1.1 skrll /* Adjust a symbol defined by a dynamic object and referenced by a 3073 1.1 skrll regular object. The current definition is in some section of the 3074 1.1 skrll dynamic object, but we're not including those sections. We have to 3075 1.1 skrll change the definition to something the rest of the link can understand. */ 3076 1.1.1.9 christos static bool 3077 1.1.1.2 christos s3_bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info, 3078 1.1.1.6 christos struct elf_link_hash_entry *h) 3079 1.1 skrll { 3080 1.1 skrll bfd *dynobj; 3081 1.1 skrll struct score_elf_link_hash_entry *hscore; 3082 1.1 skrll asection *s; 3083 1.1 skrll 3084 1.1 skrll dynobj = elf_hash_table (info)->dynobj; 3085 1.1 skrll 3086 1.1 skrll /* Make sure we know what is going on here. */ 3087 1.1 skrll BFD_ASSERT (dynobj != NULL 3088 1.1.1.6 christos && (h->needs_plt 3089 1.1.1.6 christos || h->is_weakalias 3090 1.1.1.6 christos || (h->def_dynamic && h->ref_regular && !h->def_regular))); 3091 1.1 skrll 3092 1.1 skrll /* If this symbol is defined in a dynamic object, we need to copy 3093 1.1 skrll any R_SCORE_ABS32 or R_SCORE_REL32 relocs against it into the output 3094 1.1 skrll file. */ 3095 1.1 skrll hscore = (struct score_elf_link_hash_entry *)h; 3096 1.1.1.4 christos if (!bfd_link_relocatable (info) 3097 1.1 skrll && hscore->possibly_dynamic_relocs != 0 3098 1.1 skrll && (h->root.type == bfd_link_hash_defweak || !h->def_regular)) 3099 1.1 skrll { 3100 1.1 skrll score_elf_allocate_dynamic_relocations (dynobj, hscore->possibly_dynamic_relocs); 3101 1.1 skrll if (hscore->readonly_reloc) 3102 1.1.1.6 christos /* We tell the dynamic linker that there are relocations 3103 1.1.1.6 christos against the text segment. */ 3104 1.1.1.6 christos info->flags |= DF_TEXTREL; 3105 1.1 skrll } 3106 1.1 skrll 3107 1.1 skrll /* For a function, create a stub, if allowed. */ 3108 1.1 skrll if (!hscore->no_fn_stub && h->needs_plt) 3109 1.1 skrll { 3110 1.1 skrll if (!elf_hash_table (info)->dynamic_sections_created) 3111 1.1.1.9 christos return true; 3112 1.1 skrll 3113 1.1 skrll /* If this symbol is not defined in a regular file, then set 3114 1.1.1.6 christos the symbol to the stub location. This is required to make 3115 1.1.1.6 christos function pointers compare as equal between the normal 3116 1.1.1.6 christos executable and the shared library. */ 3117 1.1 skrll if (!h->def_regular) 3118 1.1.1.6 christos { 3119 1.1.1.6 christos /* We need .stub section. */ 3120 1.1.1.6 christos s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME); 3121 1.1.1.6 christos BFD_ASSERT (s != NULL); 3122 1.1.1.6 christos 3123 1.1.1.6 christos h->root.u.def.section = s; 3124 1.1.1.6 christos h->root.u.def.value = s->size; 3125 1.1.1.6 christos 3126 1.1.1.6 christos /* XXX Write this stub address somewhere. */ 3127 1.1.1.6 christos h->plt.offset = s->size; 3128 1.1.1.6 christos 3129 1.1.1.6 christos /* Make room for this stub code. */ 3130 1.1.1.6 christos s->size += SCORE_FUNCTION_STUB_SIZE; 3131 1.1.1.6 christos 3132 1.1.1.6 christos /* The last half word of the stub will be filled with the index 3133 1.1.1.6 christos of this symbol in .dynsym section. */ 3134 1.1.1.9 christos return true; 3135 1.1.1.6 christos } 3136 1.1 skrll } 3137 1.1 skrll else if ((h->type == STT_FUNC) && !h->needs_plt) 3138 1.1 skrll { 3139 1.1 skrll /* This will set the entry for this symbol in the GOT to 0, and 3140 1.1.1.6 christos the dynamic linker will take care of this. */ 3141 1.1 skrll h->root.u.def.value = 0; 3142 1.1.1.9 christos return true; 3143 1.1 skrll } 3144 1.1 skrll 3145 1.1 skrll /* If this is a weak symbol, and there is a real definition, the 3146 1.1 skrll processor independent code will have arranged for us to see the 3147 1.1 skrll real definition first, and we can just use the same value. */ 3148 1.1.1.6 christos if (h->is_weakalias) 3149 1.1 skrll { 3150 1.1.1.6 christos struct elf_link_hash_entry *def = weakdef (h); 3151 1.1.1.6 christos BFD_ASSERT (def->root.type == bfd_link_hash_defined); 3152 1.1.1.6 christos h->root.u.def.section = def->root.u.def.section; 3153 1.1.1.6 christos h->root.u.def.value = def->root.u.def.value; 3154 1.1.1.9 christos return true; 3155 1.1 skrll } 3156 1.1 skrll 3157 1.1 skrll /* This is a reference to a symbol defined by a dynamic object which 3158 1.1 skrll is not a function. */ 3159 1.1.1.9 christos return true; 3160 1.1 skrll } 3161 1.1 skrll 3162 1.1 skrll /* This function is called after all the input files have been read, 3163 1.1 skrll and the input sections have been assigned to output sections. */ 3164 1.1.1.9 christos static bool 3165 1.1.1.11 christos s3_bfd_score_elf_early_size_sections (bfd *output_bfd, 3166 1.1.1.11 christos struct bfd_link_info *info) 3167 1.1 skrll { 3168 1.1 skrll bfd *dynobj; 3169 1.1 skrll asection *s; 3170 1.1 skrll struct score_got_info *g; 3171 1.1 skrll int i; 3172 1.1 skrll bfd_size_type loadable_size = 0; 3173 1.1 skrll bfd_size_type local_gotno; 3174 1.1 skrll bfd *sub; 3175 1.1 skrll 3176 1.1 skrll dynobj = elf_hash_table (info)->dynobj; 3177 1.1 skrll if (dynobj == NULL) 3178 1.1 skrll /* Relocatable links don't have it. */ 3179 1.1.1.9 christos return true; 3180 1.1 skrll 3181 1.1 skrll g = score_elf_got_info (dynobj, &s); 3182 1.1 skrll if (s == NULL) 3183 1.1.1.9 christos return true; 3184 1.1 skrll 3185 1.1 skrll /* Calculate the total loadable size of the output. That will give us the 3186 1.1 skrll maximum number of GOT_PAGE entries required. */ 3187 1.1.1.4 christos for (sub = info->input_bfds; sub; sub = sub->link.next) 3188 1.1 skrll { 3189 1.1 skrll asection *subsection; 3190 1.1 skrll 3191 1.1 skrll for (subsection = sub->sections; 3192 1.1.1.6 christos subsection; 3193 1.1.1.6 christos subsection = subsection->next) 3194 1.1.1.6 christos { 3195 1.1.1.6 christos if ((subsection->flags & SEC_ALLOC) == 0) 3196 1.1.1.6 christos continue; 3197 1.1.1.6 christos loadable_size += ((subsection->size + 0xf) 3198 1.1.1.6 christos &~ (bfd_size_type) 0xf); 3199 1.1.1.6 christos } 3200 1.1 skrll } 3201 1.1 skrll 3202 1.1 skrll /* There has to be a global GOT entry for every symbol with 3203 1.1 skrll a dynamic symbol table index of DT_SCORE_GOTSYM or 3204 1.1 skrll higher. Therefore, it make sense to put those symbols 3205 1.1 skrll that need GOT entries at the end of the symbol table. We 3206 1.1 skrll do that here. */ 3207 1.1 skrll if (! score_elf_sort_hash_table (info, 1)) 3208 1.1.1.9 christos return false; 3209 1.1 skrll 3210 1.1 skrll if (g->global_gotsym != NULL) 3211 1.1 skrll i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx; 3212 1.1 skrll else 3213 1.1 skrll /* If there are no global symbols, or none requiring 3214 1.1 skrll relocations, then GLOBAL_GOTSYM will be NULL. */ 3215 1.1 skrll i = 0; 3216 1.1 skrll 3217 1.1 skrll /* In the worst case, we'll get one stub per dynamic symbol. */ 3218 1.1 skrll loadable_size += SCORE_FUNCTION_STUB_SIZE * i; 3219 1.1 skrll 3220 1.1 skrll /* Assume there are two loadable segments consisting of 3221 1.1 skrll contiguous sections. Is 5 enough? */ 3222 1.1 skrll local_gotno = (loadable_size >> 16) + 5; 3223 1.1 skrll 3224 1.1 skrll g->local_gotno += local_gotno; 3225 1.1 skrll s->size += g->local_gotno * SCORE_ELF_GOT_SIZE (output_bfd); 3226 1.1 skrll 3227 1.1 skrll g->global_gotno = i; 3228 1.1 skrll s->size += i * SCORE_ELF_GOT_SIZE (output_bfd); 3229 1.1 skrll 3230 1.1 skrll score_elf_resolve_final_got_entries (g); 3231 1.1 skrll 3232 1.1 skrll if (s->size > SCORE_ELF_GOT_MAX_SIZE (output_bfd)) 3233 1.1 skrll { 3234 1.1 skrll /* Fixme. Error message or Warning message should be issued here. */ 3235 1.1 skrll } 3236 1.1 skrll 3237 1.1.1.9 christos return true; 3238 1.1 skrll } 3239 1.1 skrll 3240 1.1 skrll /* Set the sizes of the dynamic sections. */ 3241 1.1.1.9 christos static bool 3242 1.1.1.11 christos s3_bfd_score_elf_late_size_sections (bfd *output_bfd, struct bfd_link_info *info) 3243 1.1 skrll { 3244 1.1 skrll bfd *dynobj; 3245 1.1 skrll asection *s; 3246 1.1.1.9 christos bool reltext; 3247 1.1 skrll 3248 1.1 skrll dynobj = elf_hash_table (info)->dynobj; 3249 1.1.1.11 christos if (dynobj == NULL) 3250 1.1.1.11 christos return true; 3251 1.1 skrll 3252 1.1 skrll if (elf_hash_table (info)->dynamic_sections_created) 3253 1.1 skrll { 3254 1.1 skrll /* Set the contents of the .interp section to the interpreter. */ 3255 1.1.1.6 christos if (bfd_link_executable (info) && !info->nointerp) 3256 1.1.1.6 christos { 3257 1.1.1.12 christos s = elf_hash_table (info)->interp; 3258 1.1.1.6 christos BFD_ASSERT (s != NULL); 3259 1.1.1.6 christos s->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1; 3260 1.1.1.6 christos s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER; 3261 1.1.1.11 christos s->alloced = 1; 3262 1.1.1.6 christos } 3263 1.1 skrll } 3264 1.1 skrll 3265 1.1 skrll /* The check_relocs and adjust_dynamic_symbol entry points have 3266 1.1 skrll determined the sizes of the various dynamic sections. Allocate 3267 1.1 skrll memory for them. */ 3268 1.1.1.9 christos reltext = false; 3269 1.1 skrll for (s = dynobj->sections; s != NULL; s = s->next) 3270 1.1 skrll { 3271 1.1 skrll const char *name; 3272 1.1 skrll 3273 1.1 skrll if ((s->flags & SEC_LINKER_CREATED) == 0) 3274 1.1.1.6 christos continue; 3275 1.1 skrll 3276 1.1 skrll /* It's OK to base decisions on the section name, because none 3277 1.1.1.6 christos of the dynobj section names depend upon the input files. */ 3278 1.1.1.8 christos name = bfd_section_name (s); 3279 1.1 skrll 3280 1.1.1.9 christos if (startswith (name, ".rel")) 3281 1.1.1.6 christos { 3282 1.1.1.6 christos if (s->size == 0) 3283 1.1.1.6 christos { 3284 1.1.1.6 christos /* We only strip the section if the output section name 3285 1.1.1.6 christos has the same name. Otherwise, there might be several 3286 1.1.1.6 christos input sections for this output section. FIXME: This 3287 1.1.1.6 christos code is probably not needed these days anyhow, since 3288 1.1.1.6 christos the linker now does not create empty output sections. */ 3289 1.1.1.6 christos if (s->output_section != NULL 3290 1.1.1.6 christos && strcmp (name, 3291 1.1.1.8 christos bfd_section_name (s->output_section)) == 0) 3292 1.1.1.6 christos s->flags |= SEC_EXCLUDE; 3293 1.1.1.6 christos } 3294 1.1.1.6 christos else 3295 1.1.1.6 christos { 3296 1.1.1.6 christos const char *outname; 3297 1.1.1.6 christos asection *target; 3298 1.1.1.6 christos 3299 1.1.1.6 christos /* If this relocation section applies to a read only 3300 1.1.1.6 christos section, then we probably need a DT_TEXTREL entry. 3301 1.1.1.6 christos If the relocation section is .rel.dyn, we always 3302 1.1.1.6 christos assert a DT_TEXTREL entry rather than testing whether 3303 1.1.1.6 christos there exists a relocation to a read only section or 3304 1.1.1.6 christos not. */ 3305 1.1.1.8 christos outname = bfd_section_name (s->output_section); 3306 1.1.1.6 christos target = bfd_get_section_by_name (output_bfd, outname + 4); 3307 1.1.1.6 christos if ((target != NULL 3308 1.1.1.6 christos && (target->flags & SEC_READONLY) != 0 3309 1.1.1.6 christos && (target->flags & SEC_ALLOC) != 0) || strcmp (outname, ".rel.dyn") == 0) 3310 1.1.1.9 christos reltext = true; 3311 1.1.1.6 christos 3312 1.1.1.6 christos /* We use the reloc_count field as a counter if we need 3313 1.1.1.6 christos to copy relocs into the output file. */ 3314 1.1.1.6 christos if (strcmp (name, ".rel.dyn") != 0) 3315 1.1.1.6 christos s->reloc_count = 0; 3316 1.1.1.6 christos } 3317 1.1.1.6 christos } 3318 1.1.1.9 christos else if (startswith (name, ".got")) 3319 1.1.1.6 christos { 3320 1.1.1.11 christos /* s3_bfd_score_elf_early_size_sections() has already done 3321 1.1.1.6 christos most of the work, but some symbols may have been mapped 3322 1.1.1.6 christos to versions that we must now resolve in the got_entries 3323 1.1.1.6 christos hash tables. */ 3324 1.1.1.6 christos } 3325 1.1 skrll else if (strcmp (name, SCORE_ELF_STUB_SECTION_NAME) == 0) 3326 1.1.1.6 christos { 3327 1.1.1.6 christos /* IRIX rld assumes that the function stub isn't at the end 3328 1.1.1.6 christos of .text section. So put a dummy. XXX */ 3329 1.1.1.6 christos s->size += SCORE_FUNCTION_STUB_SIZE; 3330 1.1.1.6 christos } 3331 1.1.1.9 christos else if (! startswith (name, ".init")) 3332 1.1.1.6 christos { 3333 1.1.1.6 christos /* It's not one of our sections, so don't allocate space. */ 3334 1.1.1.6 christos continue; 3335 1.1.1.6 christos } 3336 1.1 skrll 3337 1.1 skrll /* Allocate memory for the section contents. */ 3338 1.1 skrll s->contents = bfd_zalloc (dynobj, s->size); 3339 1.1 skrll if (s->contents == NULL && s->size != 0) 3340 1.1.1.6 christos { 3341 1.1.1.6 christos bfd_set_error (bfd_error_no_memory); 3342 1.1.1.9 christos return false; 3343 1.1.1.6 christos } 3344 1.1.1.11 christos s->alloced = 1; 3345 1.1 skrll } 3346 1.1 skrll 3347 1.1 skrll if (elf_hash_table (info)->dynamic_sections_created) 3348 1.1 skrll { 3349 1.1 skrll /* Add some entries to the .dynamic section. We fill in the 3350 1.1.1.6 christos values later, in s3_bfd_score_elf_finish_dynamic_sections, but we 3351 1.1.1.6 christos must add the entries now so that we get the correct size for 3352 1.1.1.6 christos the .dynamic section. The DT_DEBUG entry is filled in by the 3353 1.1.1.6 christos dynamic linker and used by the debugger. */ 3354 1.1 skrll 3355 1.1 skrll if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0)) 3356 1.1.1.9 christos return false; 3357 1.1 skrll 3358 1.1 skrll if (reltext) 3359 1.1.1.6 christos info->flags |= DF_TEXTREL; 3360 1.1 skrll 3361 1.1 skrll if ((info->flags & DF_TEXTREL) != 0) 3362 1.1.1.6 christos { 3363 1.1.1.6 christos if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0)) 3364 1.1.1.9 christos return false; 3365 1.1.1.6 christos } 3366 1.1 skrll 3367 1.1 skrll if (! SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0)) 3368 1.1.1.9 christos return false; 3369 1.1 skrll 3370 1.1.1.9 christos if (score_elf_rel_dyn_section (dynobj, false)) 3371 1.1.1.6 christos { 3372 1.1.1.6 christos if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0)) 3373 1.1.1.9 christos return false; 3374 1.1.1.6 christos 3375 1.1.1.6 christos if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELSZ, 0)) 3376 1.1.1.9 christos return false; 3377 1.1.1.6 christos 3378 1.1.1.6 christos if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_RELENT, 0)) 3379 1.1.1.9 christos return false; 3380 1.1.1.6 christos } 3381 1.1 skrll 3382 1.1 skrll if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_BASE_ADDRESS, 0)) 3383 1.1.1.9 christos return false; 3384 1.1 skrll 3385 1.1 skrll if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_LOCAL_GOTNO, 0)) 3386 1.1.1.9 christos return false; 3387 1.1 skrll 3388 1.1 skrll if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_SYMTABNO, 0)) 3389 1.1.1.9 christos return false; 3390 1.1 skrll 3391 1.1 skrll if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_UNREFEXTNO, 0)) 3392 1.1.1.9 christos return false; 3393 1.1 skrll 3394 1.1 skrll if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_GOTSYM, 0)) 3395 1.1.1.9 christos return false; 3396 1.1 skrll 3397 1.1 skrll if (!SCORE_ELF_ADD_DYNAMIC_ENTRY (info, DT_SCORE_HIPAGENO, 0)) 3398 1.1.1.9 christos return false; 3399 1.1 skrll } 3400 1.1 skrll 3401 1.1.1.9 christos return true; 3402 1.1 skrll } 3403 1.1 skrll 3404 1.1.1.9 christos static bool 3405 1.1.1.2 christos s3_bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) 3406 1.1 skrll { 3407 1.1 skrll struct elf_link_hash_entry *h; 3408 1.1 skrll struct bfd_link_hash_entry *bh; 3409 1.1 skrll flagword flags; 3410 1.1 skrll asection *s; 3411 1.1 skrll 3412 1.1 skrll flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY 3413 1.1.1.6 christos | SEC_LINKER_CREATED | SEC_READONLY); 3414 1.1 skrll 3415 1.1 skrll /* ABI requests the .dynamic section to be read only. */ 3416 1.1.1.3 christos s = bfd_get_linker_section (abfd, ".dynamic"); 3417 1.1 skrll if (s != NULL) 3418 1.1 skrll { 3419 1.1.1.8 christos if (!bfd_set_section_flags (s, flags)) 3420 1.1.1.9 christos return false; 3421 1.1 skrll } 3422 1.1 skrll 3423 1.1 skrll /* We need to create .got section. */ 3424 1.1.1.9 christos if (!score_elf_create_got_section (abfd, info, false)) 3425 1.1.1.9 christos return false; 3426 1.1 skrll 3427 1.1.1.9 christos if (!score_elf_rel_dyn_section (elf_hash_table (info)->dynobj, true)) 3428 1.1.1.9 christos return false; 3429 1.1 skrll 3430 1.1 skrll /* Create .stub section. */ 3431 1.1.1.3 christos if (bfd_get_linker_section (abfd, SCORE_ELF_STUB_SECTION_NAME) == NULL) 3432 1.1 skrll { 3433 1.1.1.3 christos s = bfd_make_section_anyway_with_flags (abfd, SCORE_ELF_STUB_SECTION_NAME, 3434 1.1.1.3 christos flags | SEC_CODE); 3435 1.1 skrll if (s == NULL 3436 1.1.1.8 christos || !bfd_set_section_alignment (s, 2)) 3437 1.1 skrll 3438 1.1.1.9 christos return false; 3439 1.1 skrll } 3440 1.1 skrll 3441 1.1.1.4 christos if (!bfd_link_pic (info)) 3442 1.1 skrll { 3443 1.1 skrll const char *name; 3444 1.1 skrll 3445 1.1 skrll name = "_DYNAMIC_LINK"; 3446 1.1 skrll bh = NULL; 3447 1.1 skrll if (!(_bfd_generic_link_add_one_symbol 3448 1.1.1.6 christos (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr, 3449 1.1.1.9 christos (bfd_vma) 0, NULL, false, get_elf_backend_data (abfd)->collect, &bh))) 3450 1.1.1.9 christos return false; 3451 1.1 skrll 3452 1.1 skrll h = (struct elf_link_hash_entry *)bh; 3453 1.1 skrll h->non_elf = 0; 3454 1.1 skrll h->def_regular = 1; 3455 1.1 skrll h->type = STT_SECTION; 3456 1.1 skrll 3457 1.1 skrll if (!bfd_elf_link_record_dynamic_symbol (info, h)) 3458 1.1.1.9 christos return false; 3459 1.1 skrll } 3460 1.1 skrll 3461 1.1.1.9 christos return true; 3462 1.1 skrll } 3463 1.1 skrll 3464 1.1 skrll 3465 1.1 skrll /* Finish up dynamic symbol handling. We set the contents of various 3466 1.1 skrll dynamic sections here. */ 3467 1.1.1.9 christos static bool 3468 1.1.1.2 christos s3_bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd, 3469 1.1.1.6 christos struct bfd_link_info *info, 3470 1.1.1.6 christos struct elf_link_hash_entry *h, 3471 1.1.1.6 christos Elf_Internal_Sym *sym) 3472 1.1 skrll { 3473 1.1 skrll bfd *dynobj; 3474 1.1 skrll asection *sgot; 3475 1.1 skrll struct score_got_info *g; 3476 1.1 skrll const char *name; 3477 1.1 skrll 3478 1.1 skrll dynobj = elf_hash_table (info)->dynobj; 3479 1.1 skrll 3480 1.1 skrll if (h->plt.offset != MINUS_ONE) 3481 1.1 skrll { 3482 1.1 skrll asection *s; 3483 1.1 skrll bfd_byte stub[SCORE_FUNCTION_STUB_SIZE]; 3484 1.1 skrll 3485 1.1 skrll /* This symbol has a stub. Set it up. */ 3486 1.1 skrll BFD_ASSERT (h->dynindx != -1); 3487 1.1 skrll 3488 1.1.1.3 christos s = bfd_get_linker_section (dynobj, SCORE_ELF_STUB_SECTION_NAME); 3489 1.1 skrll BFD_ASSERT (s != NULL); 3490 1.1 skrll 3491 1.1 skrll /* FIXME: Can h->dynindex be more than 64K? */ 3492 1.1 skrll if (h->dynindx & 0xffff0000) 3493 1.1.1.11 christos { 3494 1.1.1.11 christos _bfd_error_handler 3495 1.1.1.11 christos (_("%pB: cannot handle more than %d dynamic symbols"), 3496 1.1.1.11 christos output_bfd, 0xffff); 3497 1.1.1.11 christos bfd_set_error (bfd_error_bad_value); 3498 1.1.1.11 christos return false; 3499 1.1.1.11 christos } 3500 1.1 skrll 3501 1.1 skrll /* Fill the stub. */ 3502 1.1.1.2 christos score_bfd_put_32 (output_bfd, STUB_LW, stub); 3503 1.1.1.2 christos score_bfd_put_32 (output_bfd, STUB_MOVE, stub + 4); 3504 1.1.1.2 christos score_bfd_put_32 (output_bfd, STUB_LI16 | (h->dynindx << 1), stub + 8); 3505 1.1.1.2 christos score_bfd_put_32 (output_bfd, STUB_BRL, stub + 12); 3506 1.1 skrll 3507 1.1 skrll BFD_ASSERT (h->plt.offset <= s->size); 3508 1.1 skrll memcpy (s->contents + h->plt.offset, stub, SCORE_FUNCTION_STUB_SIZE); 3509 1.1 skrll 3510 1.1 skrll /* Mark the symbol as undefined. plt.offset != -1 occurs 3511 1.1.1.6 christos only for the referenced symbol. */ 3512 1.1 skrll sym->st_shndx = SHN_UNDEF; 3513 1.1 skrll 3514 1.1 skrll /* The run-time linker uses the st_value field of the symbol 3515 1.1.1.6 christos to reset the global offset table entry for this external 3516 1.1.1.6 christos to its stub address when unlinking a shared object. */ 3517 1.1 skrll sym->st_value = (s->output_section->vma + s->output_offset + h->plt.offset); 3518 1.1 skrll } 3519 1.1 skrll 3520 1.1 skrll BFD_ASSERT (h->dynindx != -1 || h->forced_local); 3521 1.1 skrll 3522 1.1.1.9 christos sgot = score_elf_got_section (dynobj, false); 3523 1.1 skrll BFD_ASSERT (sgot != NULL); 3524 1.1 skrll BFD_ASSERT (score_elf_section_data (sgot) != NULL); 3525 1.1 skrll g = score_elf_section_data (sgot)->u.got_info; 3526 1.1 skrll BFD_ASSERT (g != NULL); 3527 1.1 skrll 3528 1.1 skrll /* Run through the global symbol table, creating GOT entries for all 3529 1.1 skrll the symbols that need them. */ 3530 1.1 skrll if (g->global_gotsym != NULL && h->dynindx >= g->global_gotsym->dynindx) 3531 1.1 skrll { 3532 1.1 skrll bfd_vma offset; 3533 1.1 skrll bfd_vma value; 3534 1.1 skrll 3535 1.1 skrll value = sym->st_value; 3536 1.1 skrll offset = score_elf_global_got_index (dynobj, h); 3537 1.1.1.2 christos score_bfd_put_32 (output_bfd, value, sgot->contents + offset); 3538 1.1 skrll } 3539 1.1 skrll 3540 1.1 skrll /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ 3541 1.1 skrll name = h->root.root.string; 3542 1.1.1.4 christos if (h == elf_hash_table (info)->hdynamic 3543 1.1.1.4 christos || h == elf_hash_table (info)->hgot) 3544 1.1 skrll sym->st_shndx = SHN_ABS; 3545 1.1 skrll else if (strcmp (name, "_DYNAMIC_LINK") == 0) 3546 1.1 skrll { 3547 1.1 skrll sym->st_shndx = SHN_ABS; 3548 1.1 skrll sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION); 3549 1.1 skrll sym->st_value = 1; 3550 1.1 skrll } 3551 1.1 skrll else if (strcmp (name, GP_DISP_LABEL) == 0) 3552 1.1 skrll { 3553 1.1 skrll sym->st_shndx = SHN_ABS; 3554 1.1 skrll sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION); 3555 1.1 skrll sym->st_value = elf_gp (output_bfd); 3556 1.1 skrll } 3557 1.1 skrll 3558 1.1.1.9 christos return true; 3559 1.1 skrll } 3560 1.1 skrll 3561 1.1 skrll /* Finish up the dynamic sections. */ 3562 1.1.1.9 christos static bool 3563 1.1.1.2 christos s3_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd, 3564 1.1.1.12 christos struct bfd_link_info *info, 3565 1.1.1.12 christos bfd_byte *buf ATTRIBUTE_UNUSED) 3566 1.1 skrll { 3567 1.1 skrll bfd *dynobj; 3568 1.1 skrll asection *sdyn; 3569 1.1 skrll asection *sgot; 3570 1.1 skrll asection *s; 3571 1.1 skrll struct score_got_info *g; 3572 1.1 skrll 3573 1.1 skrll dynobj = elf_hash_table (info)->dynobj; 3574 1.1 skrll 3575 1.1.1.3 christos sdyn = bfd_get_linker_section (dynobj, ".dynamic"); 3576 1.1 skrll 3577 1.1.1.9 christos sgot = score_elf_got_section (dynobj, false); 3578 1.1 skrll if (sgot == NULL) 3579 1.1 skrll g = NULL; 3580 1.1 skrll else 3581 1.1 skrll { 3582 1.1 skrll BFD_ASSERT (score_elf_section_data (sgot) != NULL); 3583 1.1 skrll g = score_elf_section_data (sgot)->u.got_info; 3584 1.1 skrll BFD_ASSERT (g != NULL); 3585 1.1 skrll } 3586 1.1 skrll 3587 1.1 skrll if (elf_hash_table (info)->dynamic_sections_created) 3588 1.1 skrll { 3589 1.1 skrll bfd_byte *b; 3590 1.1 skrll 3591 1.1 skrll BFD_ASSERT (sdyn != NULL); 3592 1.1 skrll BFD_ASSERT (g != NULL); 3593 1.1 skrll 3594 1.1 skrll for (b = sdyn->contents; 3595 1.1.1.6 christos b < sdyn->contents + sdyn->size; 3596 1.1.1.6 christos b += SCORE_ELF_DYN_SIZE (dynobj)) 3597 1.1.1.6 christos { 3598 1.1.1.6 christos Elf_Internal_Dyn dyn; 3599 1.1.1.6 christos const char *name; 3600 1.1.1.6 christos size_t elemsize; 3601 1.1.1.9 christos bool swap_out_p; 3602 1.1.1.6 christos 3603 1.1.1.6 christos /* Read in the current dynamic entry. */ 3604 1.1.1.6 christos (*get_elf_backend_data (dynobj)->s->swap_dyn_in) (dynobj, b, &dyn); 3605 1.1.1.6 christos 3606 1.1.1.6 christos /* Assume that we're going to modify it and write it out. */ 3607 1.1.1.9 christos swap_out_p = true; 3608 1.1.1.6 christos 3609 1.1.1.6 christos switch (dyn.d_tag) 3610 1.1.1.6 christos { 3611 1.1.1.6 christos case DT_RELENT: 3612 1.1.1.6 christos dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj); 3613 1.1.1.6 christos break; 3614 1.1.1.6 christos 3615 1.1.1.6 christos case DT_STRSZ: 3616 1.1.1.6 christos /* Rewrite DT_STRSZ. */ 3617 1.1.1.6 christos dyn.d_un.d_val 3618 1.1.1.6 christos = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr); 3619 1.1.1.6 christos break; 3620 1.1.1.6 christos 3621 1.1.1.6 christos case DT_PLTGOT: 3622 1.1.1.6 christos s = elf_hash_table (info)->sgot; 3623 1.1.1.6 christos dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; 3624 1.1.1.6 christos break; 3625 1.1.1.6 christos 3626 1.1.1.6 christos case DT_SCORE_BASE_ADDRESS: 3627 1.1.1.6 christos s = output_bfd->sections; 3628 1.1.1.6 christos BFD_ASSERT (s != NULL); 3629 1.1.1.6 christos dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff; 3630 1.1.1.6 christos break; 3631 1.1.1.6 christos 3632 1.1.1.6 christos case DT_SCORE_LOCAL_GOTNO: 3633 1.1.1.6 christos dyn.d_un.d_val = g->local_gotno; 3634 1.1.1.6 christos break; 3635 1.1.1.6 christos 3636 1.1.1.6 christos case DT_SCORE_UNREFEXTNO: 3637 1.1.1.6 christos /* The index into the dynamic symbol table which is the 3638 1.1.1.6 christos entry of the first external symbol that is not 3639 1.1.1.6 christos referenced within the same object. */ 3640 1.1.1.6 christos dyn.d_un.d_val = bfd_count_sections (output_bfd) + 1; 3641 1.1.1.6 christos break; 3642 1.1.1.6 christos 3643 1.1.1.6 christos case DT_SCORE_GOTSYM: 3644 1.1.1.6 christos if (g->global_gotsym) 3645 1.1.1.6 christos { 3646 1.1.1.6 christos dyn.d_un.d_val = g->global_gotsym->dynindx; 3647 1.1.1.6 christos break; 3648 1.1.1.6 christos } 3649 1.1.1.6 christos /* In case if we don't have global got symbols we default 3650 1.1.1.6 christos to setting DT_SCORE_GOTSYM to the same value as 3651 1.1.1.6 christos DT_SCORE_SYMTABNO. */ 3652 1.1.1.6 christos /* Fall through. */ 3653 1.1.1.6 christos 3654 1.1.1.6 christos case DT_SCORE_SYMTABNO: 3655 1.1.1.6 christos name = ".dynsym"; 3656 1.1.1.6 christos elemsize = SCORE_ELF_SYM_SIZE (output_bfd); 3657 1.1.1.6 christos s = bfd_get_linker_section (dynobj, name); 3658 1.1.1.6 christos dyn.d_un.d_val = s->size / elemsize; 3659 1.1.1.6 christos break; 3660 1.1.1.6 christos 3661 1.1.1.6 christos case DT_SCORE_HIPAGENO: 3662 1.1.1.6 christos dyn.d_un.d_val = g->local_gotno - SCORE_RESERVED_GOTNO; 3663 1.1.1.6 christos break; 3664 1.1.1.6 christos 3665 1.1.1.6 christos default: 3666 1.1.1.9 christos swap_out_p = false; 3667 1.1.1.6 christos break; 3668 1.1.1.6 christos } 3669 1.1.1.6 christos 3670 1.1.1.6 christos if (swap_out_p) 3671 1.1.1.6 christos (*get_elf_backend_data (dynobj)->s->swap_dyn_out) (dynobj, &dyn, b); 3672 1.1.1.6 christos } 3673 1.1 skrll } 3674 1.1 skrll 3675 1.1 skrll /* The first entry of the global offset table will be filled at 3676 1.1 skrll runtime. The second entry will be used by some runtime loaders. 3677 1.1 skrll This isn't the case of IRIX rld. */ 3678 1.1 skrll if (sgot != NULL && sgot->size > 0) 3679 1.1 skrll { 3680 1.1.1.2 christos score_bfd_put_32 (output_bfd, 0, sgot->contents); 3681 1.1.1.2 christos score_bfd_put_32 (output_bfd, 0x80000000, sgot->contents + SCORE_ELF_GOT_SIZE (output_bfd)); 3682 1.1 skrll } 3683 1.1 skrll 3684 1.1 skrll if (sgot != NULL) 3685 1.1 skrll elf_section_data (sgot->output_section)->this_hdr.sh_entsize 3686 1.1 skrll = SCORE_ELF_GOT_SIZE (output_bfd); 3687 1.1 skrll 3688 1.1 skrll 3689 1.1 skrll /* We need to sort the entries of the dynamic relocation section. */ 3690 1.1.1.9 christos s = score_elf_rel_dyn_section (dynobj, false); 3691 1.1 skrll 3692 1.1 skrll if (s != NULL && s->size > (bfd_vma)2 * SCORE_ELF_REL_SIZE (output_bfd)) 3693 1.1 skrll { 3694 1.1 skrll reldyn_sorting_bfd = output_bfd; 3695 1.1 skrll qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1, 3696 1.1.1.6 christos sizeof (Elf32_External_Rel), score_elf_sort_dynamic_relocs); 3697 1.1 skrll } 3698 1.1 skrll 3699 1.1.1.9 christos return true; 3700 1.1 skrll } 3701 1.1 skrll 3702 1.1 skrll /* This function set up the ELF section header for a BFD section in preparation for writing 3703 1.1 skrll it out. This is where the flags and type fields are set for unusual sections. */ 3704 1.1.1.9 christos static bool 3705 1.1.1.2 christos s3_bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED, 3706 1.1.1.6 christos Elf_Internal_Shdr *hdr, 3707 1.1.1.6 christos asection *sec) 3708 1.1 skrll { 3709 1.1 skrll const char *name; 3710 1.1 skrll 3711 1.1.1.8 christos name = bfd_section_name (sec); 3712 1.1 skrll 3713 1.1 skrll if (strcmp (name, ".got") == 0 3714 1.1 skrll || strcmp (name, ".srdata") == 0 3715 1.1 skrll || strcmp (name, ".sdata") == 0 3716 1.1 skrll || strcmp (name, ".sbss") == 0) 3717 1.1 skrll hdr->sh_flags |= SHF_SCORE_GPREL; 3718 1.1 skrll 3719 1.1.1.9 christos return true; 3720 1.1 skrll } 3721 1.1 skrll 3722 1.1 skrll /* This function do additional processing on the ELF section header before writing 3723 1.1 skrll it out. This is used to set the flags and type fields for some sections. */ 3724 1.1 skrll 3725 1.1 skrll /* assign_file_positions_except_relocs() check section flag and if it is allocatable, 3726 1.1 skrll warning message will be issued. backend_fake_section is called before 3727 1.1 skrll assign_file_positions_except_relocs(); backend_section_processing after it. so, we 3728 1.1 skrll modify section flag there, but not backend_fake_section. */ 3729 1.1.1.9 christos static bool 3730 1.1.1.2 christos s3_bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr) 3731 1.1 skrll { 3732 1.1 skrll if (hdr->bfd_section != NULL) 3733 1.1 skrll { 3734 1.1.1.8 christos const char *name = bfd_section_name (hdr->bfd_section); 3735 1.1 skrll 3736 1.1 skrll if (strcmp (name, ".sdata") == 0) 3737 1.1.1.6 christos { 3738 1.1.1.6 christos hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL; 3739 1.1.1.6 christos hdr->sh_type = SHT_PROGBITS; 3740 1.1.1.6 christos } 3741 1.1 skrll else if (strcmp (name, ".sbss") == 0) 3742 1.1.1.6 christos { 3743 1.1.1.6 christos hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_SCORE_GPREL; 3744 1.1.1.6 christos hdr->sh_type = SHT_NOBITS; 3745 1.1.1.6 christos } 3746 1.1 skrll else if (strcmp (name, ".srdata") == 0) 3747 1.1.1.6 christos { 3748 1.1.1.6 christos hdr->sh_flags |= SHF_ALLOC | SHF_SCORE_GPREL; 3749 1.1.1.6 christos hdr->sh_type = SHT_PROGBITS; 3750 1.1.1.6 christos } 3751 1.1 skrll } 3752 1.1 skrll 3753 1.1.1.9 christos return true; 3754 1.1 skrll } 3755 1.1 skrll 3756 1.1.1.9 christos static bool 3757 1.1.1.2 christos s3_bfd_score_elf_write_section (bfd *output_bfd, asection *sec, bfd_byte *contents) 3758 1.1 skrll { 3759 1.1 skrll bfd_byte *to, *from, *end; 3760 1.1 skrll int i; 3761 1.1 skrll 3762 1.1 skrll if (strcmp (sec->name, ".pdr") != 0) 3763 1.1.1.9 christos return false; 3764 1.1 skrll 3765 1.1 skrll if (score_elf_section_data (sec)->u.tdata == NULL) 3766 1.1.1.9 christos return false; 3767 1.1 skrll 3768 1.1 skrll to = contents; 3769 1.1 skrll end = contents + sec->size; 3770 1.1 skrll for (from = contents, i = 0; from < end; from += PDR_SIZE, i++) 3771 1.1 skrll { 3772 1.1 skrll if ((score_elf_section_data (sec)->u.tdata)[i] == 1) 3773 1.1.1.6 christos continue; 3774 1.1 skrll 3775 1.1 skrll if (to != from) 3776 1.1.1.6 christos memcpy (to, from, PDR_SIZE); 3777 1.1 skrll 3778 1.1 skrll to += PDR_SIZE; 3779 1.1 skrll } 3780 1.1 skrll bfd_set_section_contents (output_bfd, sec->output_section, contents, 3781 1.1.1.6 christos (file_ptr) sec->output_offset, sec->size); 3782 1.1 skrll 3783 1.1.1.9 christos return true; 3784 1.1 skrll } 3785 1.1 skrll 3786 1.1 skrll /* Copy data from a SCORE ELF indirect symbol to its direct symbol, hiding the old 3787 1.1 skrll indirect symbol. Process additional relocation information. */ 3788 1.1 skrll static void 3789 1.1.1.2 christos s3_bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info, 3790 1.1.1.6 christos struct elf_link_hash_entry *dir, 3791 1.1.1.6 christos struct elf_link_hash_entry *ind) 3792 1.1 skrll { 3793 1.1 skrll struct score_elf_link_hash_entry *dirscore, *indscore; 3794 1.1 skrll 3795 1.1 skrll _bfd_elf_link_hash_copy_indirect (info, dir, ind); 3796 1.1 skrll 3797 1.1 skrll if (ind->root.type != bfd_link_hash_indirect) 3798 1.1 skrll return; 3799 1.1 skrll 3800 1.1 skrll dirscore = (struct score_elf_link_hash_entry *) dir; 3801 1.1 skrll indscore = (struct score_elf_link_hash_entry *) ind; 3802 1.1 skrll dirscore->possibly_dynamic_relocs += indscore->possibly_dynamic_relocs; 3803 1.1 skrll 3804 1.1 skrll if (indscore->readonly_reloc) 3805 1.1.1.9 christos dirscore->readonly_reloc = true; 3806 1.1 skrll 3807 1.1 skrll if (indscore->no_fn_stub) 3808 1.1.1.9 christos dirscore->no_fn_stub = true; 3809 1.1 skrll } 3810 1.1 skrll 3811 1.1 skrll /* Remove information about discarded functions from other sections which mention them. */ 3812 1.1.1.9 christos static bool 3813 1.1.1.2 christos s3_bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie, 3814 1.1.1.6 christos struct bfd_link_info *info) 3815 1.1 skrll { 3816 1.1 skrll asection *o; 3817 1.1.1.9 christos bool ret = false; 3818 1.1 skrll unsigned char *tdata; 3819 1.1 skrll size_t i, skip; 3820 1.1 skrll 3821 1.1 skrll o = bfd_get_section_by_name (abfd, ".pdr"); 3822 1.1 skrll if ((!o) || (o->size == 0) || (o->size % PDR_SIZE != 0) 3823 1.1 skrll || (o->output_section != NULL && bfd_is_abs_section (o->output_section))) 3824 1.1.1.9 christos return false; 3825 1.1 skrll 3826 1.1 skrll tdata = bfd_zmalloc (o->size / PDR_SIZE); 3827 1.1 skrll if (!tdata) 3828 1.1.1.9 christos return false; 3829 1.1 skrll 3830 1.1 skrll cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, info->keep_memory); 3831 1.1 skrll if (!cookie->rels) 3832 1.1 skrll { 3833 1.1 skrll free (tdata); 3834 1.1.1.9 christos return false; 3835 1.1 skrll } 3836 1.1 skrll 3837 1.1 skrll cookie->rel = cookie->rels; 3838 1.1 skrll cookie->relend = cookie->rels + o->reloc_count; 3839 1.1 skrll 3840 1.1 skrll for (i = 0, skip = 0; i < o->size; i++) 3841 1.1 skrll { 3842 1.1 skrll if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie)) 3843 1.1.1.6 christos { 3844 1.1.1.6 christos tdata[i] = 1; 3845 1.1.1.6 christos skip++; 3846 1.1.1.6 christos } 3847 1.1 skrll } 3848 1.1 skrll 3849 1.1 skrll if (skip != 0) 3850 1.1 skrll { 3851 1.1 skrll score_elf_section_data (o)->u.tdata = tdata; 3852 1.1 skrll o->size -= skip * PDR_SIZE; 3853 1.1.1.9 christos ret = true; 3854 1.1 skrll } 3855 1.1 skrll else 3856 1.1 skrll free (tdata); 3857 1.1 skrll 3858 1.1 skrll if (!info->keep_memory) 3859 1.1 skrll free (cookie->rels); 3860 1.1 skrll 3861 1.1 skrll return ret; 3862 1.1 skrll } 3863 1.1 skrll 3864 1.1 skrll /* Signal that discard_info() has removed the discarded relocations for this section. */ 3865 1.1.1.9 christos static bool 3866 1.1.1.2 christos s3_bfd_score_elf_ignore_discarded_relocs (asection *sec) 3867 1.1 skrll { 3868 1.1 skrll if (strcmp (sec->name, ".pdr") == 0) 3869 1.1.1.9 christos return true; 3870 1.1.1.9 christos return false; 3871 1.1 skrll } 3872 1.1 skrll 3873 1.1 skrll /* Return the section that should be marked against GC for a given 3874 1.1 skrll relocation. */ 3875 1.1 skrll static asection * 3876 1.1.1.2 christos s3_bfd_score_elf_gc_mark_hook (asection *sec, 3877 1.1.1.6 christos struct bfd_link_info *info, 3878 1.1.1.12 christos struct elf_reloc_cookie *cookie, 3879 1.1.1.6 christos struct elf_link_hash_entry *h, 3880 1.1.1.12 christos unsigned int symndx) 3881 1.1 skrll { 3882 1.1 skrll if (h != NULL) 3883 1.1.1.12 christos switch (ELF32_R_TYPE (cookie->rel->r_info)) 3884 1.1 skrll { 3885 1.1 skrll case R_SCORE_GNU_VTINHERIT: 3886 1.1 skrll case R_SCORE_GNU_VTENTRY: 3887 1.1.1.6 christos return NULL; 3888 1.1 skrll } 3889 1.1 skrll 3890 1.1.1.12 christos return _bfd_elf_gc_mark_hook (sec, info, cookie, h, symndx); 3891 1.1 skrll } 3892 1.1 skrll 3893 1.1 skrll /* Support for core dump NOTE sections. */ 3894 1.1 skrll 3895 1.1.1.9 christos static bool 3896 1.1.1.2 christos s3_bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) 3897 1.1 skrll { 3898 1.1 skrll int offset; 3899 1.1 skrll unsigned int raw_size; 3900 1.1 skrll 3901 1.1 skrll switch (note->descsz) 3902 1.1 skrll { 3903 1.1 skrll default: 3904 1.1.1.9 christos return false; 3905 1.1 skrll 3906 1.1.1.6 christos case 148: /* Linux/Score 32-bit. */ 3907 1.1 skrll /* pr_cursig */ 3908 1.1.1.4 christos elf_tdata (abfd)->core->signal 3909 1.1.1.4 christos = score_bfd_get_16 (abfd, note->descdata + 12); 3910 1.1 skrll 3911 1.1 skrll /* pr_pid */ 3912 1.1.1.4 christos elf_tdata (abfd)->core->lwpid 3913 1.1.1.4 christos = score_bfd_get_32 (abfd, note->descdata + 24); 3914 1.1 skrll 3915 1.1 skrll /* pr_reg */ 3916 1.1 skrll offset = 72; 3917 1.1 skrll raw_size = 72; 3918 1.1 skrll 3919 1.1 skrll break; 3920 1.1 skrll } 3921 1.1 skrll 3922 1.1 skrll /* Make a ".reg/999" section. */ 3923 1.1.1.4 christos return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size, 3924 1.1.1.4 christos note->descpos + offset); 3925 1.1 skrll } 3926 1.1 skrll 3927 1.1.1.9 christos static bool 3928 1.1.1.2 christos s3_bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) 3929 1.1 skrll { 3930 1.1 skrll switch (note->descsz) 3931 1.1 skrll { 3932 1.1 skrll default: 3933 1.1.1.9 christos return false; 3934 1.1 skrll 3935 1.1.1.6 christos case 124: /* Linux/Score elf_prpsinfo. */ 3936 1.1.1.4 christos elf_tdata (abfd)->core->program 3937 1.1.1.4 christos = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16); 3938 1.1.1.4 christos elf_tdata (abfd)->core->command 3939 1.1.1.4 christos = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80); 3940 1.1 skrll } 3941 1.1 skrll 3942 1.1 skrll /* Note that for some reason, a spurious space is tacked 3943 1.1 skrll onto the end of the args in some (at least one anyway) 3944 1.1 skrll implementations, so strip it off if it exists. */ 3945 1.1 skrll 3946 1.1 skrll { 3947 1.1.1.4 christos char *command = elf_tdata (abfd)->core->command; 3948 1.1 skrll int n = strlen (command); 3949 1.1 skrll 3950 1.1 skrll if (0 < n && command[n - 1] == ' ') 3951 1.1 skrll command[n - 1] = '\0'; 3952 1.1 skrll } 3953 1.1 skrll 3954 1.1.1.9 christos return true; 3955 1.1 skrll } 3956 1.1 skrll 3957 1.1 skrll 3958 1.1 skrll /* Score BFD functions. */ 3959 1.1 skrll static reloc_howto_type * 3960 1.1.1.2 christos s3_elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code) 3961 1.1 skrll { 3962 1.1 skrll unsigned int i; 3963 1.1 skrll 3964 1.1.1.2 christos for (i = 0; i < ARRAY_SIZE (elf32_score_reloc_map); i++) 3965 1.1 skrll if (elf32_score_reloc_map[i].bfd_reloc_val == code) 3966 1.1 skrll return &elf32_score_howto_table[elf32_score_reloc_map[i].elf_reloc_val]; 3967 1.1 skrll 3968 1.1 skrll return NULL; 3969 1.1 skrll } 3970 1.1 skrll 3971 1.1 skrll static reloc_howto_type * 3972 1.1 skrll elf32_score_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 3973 1.1.1.6 christos const char *r_name) 3974 1.1 skrll { 3975 1.1 skrll unsigned int i; 3976 1.1 skrll 3977 1.1 skrll for (i = 0; 3978 1.1 skrll i < (sizeof (elf32_score_howto_table) 3979 1.1.1.6 christos / sizeof (elf32_score_howto_table[0])); 3980 1.1 skrll i++) 3981 1.1 skrll if (elf32_score_howto_table[i].name != NULL 3982 1.1.1.6 christos && strcasecmp (elf32_score_howto_table[i].name, r_name) == 0) 3983 1.1 skrll return &elf32_score_howto_table[i]; 3984 1.1 skrll 3985 1.1 skrll return NULL; 3986 1.1 skrll } 3987 1.1 skrll 3988 1.1.1.9 christos static bool 3989 1.1.1.2 christos s3_elf32_score_print_private_bfd_data (bfd *abfd, void * ptr) 3990 1.1 skrll { 3991 1.1 skrll FILE *file = (FILE *) ptr; 3992 1.1 skrll 3993 1.1 skrll BFD_ASSERT (abfd != NULL && ptr != NULL); 3994 1.1 skrll 3995 1.1 skrll /* Print normal ELF private data. */ 3996 1.1 skrll _bfd_elf_print_private_bfd_data (abfd, ptr); 3997 1.1 skrll 3998 1.1 skrll /* xgettext:c-format */ 3999 1.1 skrll fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags); 4000 1.1 skrll if (elf_elfheader (abfd)->e_flags & EF_SCORE_PIC) 4001 1.1 skrll { 4002 1.1 skrll fprintf (file, _(" [pic]")); 4003 1.1 skrll } 4004 1.1 skrll if (elf_elfheader (abfd)->e_flags & EF_SCORE_FIXDEP) 4005 1.1 skrll { 4006 1.1 skrll fprintf (file, _(" [fix dep]")); 4007 1.1 skrll } 4008 1.1 skrll fputc ('\n', file); 4009 1.1 skrll 4010 1.1.1.9 christos return true; 4011 1.1 skrll } 4012 1.1 skrll 4013 1.1.1.9 christos static bool 4014 1.1.1.6 christos s3_elf32_score_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) 4015 1.1 skrll { 4016 1.1.1.6 christos bfd *obfd = info->output_bfd; 4017 1.1 skrll flagword in_flags; 4018 1.1 skrll flagword out_flags; 4019 1.1 skrll 4020 1.1.1.6 christos if (!_bfd_generic_verify_endian_match (ibfd, info)) 4021 1.1.1.9 christos return false; 4022 1.1.1.9 christos 4023 1.1.1.9 christos /* FIXME: What should be checked when linking shared libraries? */ 4024 1.1.1.9 christos if ((ibfd->flags & DYNAMIC) != 0) 4025 1.1.1.9 christos return true; 4026 1.1 skrll 4027 1.1.1.12 christos if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) 4028 1.1.1.12 christos return true; 4029 1.1.1.12 christos 4030 1.1 skrll in_flags = elf_elfheader (ibfd)->e_flags; 4031 1.1 skrll out_flags = elf_elfheader (obfd)->e_flags; 4032 1.1 skrll 4033 1.1 skrll in_flags = elf_elfheader (ibfd)->e_flags; 4034 1.1 skrll out_flags = elf_elfheader (obfd)->e_flags; 4035 1.1 skrll 4036 1.1 skrll if (! elf_flags_init (obfd)) 4037 1.1 skrll { 4038 1.1.1.9 christos elf_flags_init (obfd) = true; 4039 1.1 skrll elf_elfheader (obfd)->e_flags = in_flags; 4040 1.1 skrll 4041 1.1 skrll if (bfd_get_arch (obfd) == bfd_get_arch (ibfd) 4042 1.1.1.6 christos && bfd_get_arch_info (obfd)->the_default) 4043 1.1.1.6 christos { 4044 1.1.1.6 christos return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd)); 4045 1.1.1.6 christos } 4046 1.1 skrll 4047 1.1.1.9 christos return true; 4048 1.1 skrll } 4049 1.1 skrll 4050 1.1 skrll if (((in_flags & EF_SCORE_PIC) != 0) != ((out_flags & EF_SCORE_PIC) != 0)) 4051 1.1.1.6 christos _bfd_error_handler 4052 1.1.1.7 christos (_("%pB: warning: linking PIC files with non-PIC files"), ibfd); 4053 1.1 skrll 4054 1.1 skrll /* FIXME: Maybe dependency fix compatibility should be checked here. */ 4055 1.1 skrll 4056 1.1.1.9 christos return true; 4057 1.1 skrll } 4058 1.1 skrll 4059 1.1.1.9 christos static bool 4060 1.1.1.2 christos s3_elf32_score_new_section_hook (bfd *abfd, asection *sec) 4061 1.1 skrll { 4062 1.1 skrll struct _score_elf_section_data *sdata; 4063 1.1 skrll 4064 1.1.1.11 christos sdata = bfd_zalloc (abfd, sizeof (*sdata)); 4065 1.1 skrll if (sdata == NULL) 4066 1.1.1.9 christos return false; 4067 1.1 skrll sec->used_by_bfd = sdata; 4068 1.1 skrll 4069 1.1 skrll return _bfd_elf_new_section_hook (abfd, sec); 4070 1.1 skrll } 4071 1.1 skrll 4072 1.1.1.2 christos /*****************************************************************************/ 4073 1.1.1.2 christos 4074 1.1.1.2 christos /* s3_s7: backend hooks. */ 4075 1.1.1.9 christos static bool 4076 1.1.1.2 christos _bfd_score_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, 4077 1.1.1.6 christos arelent *bfd_reloc, 4078 1.1.1.6 christos Elf_Internal_Rela *elf_reloc) 4079 1.1.1.2 christos { 4080 1.1.1.2 christos if (bfd_get_mach (abfd) == bfd_mach_score3) 4081 1.1.1.2 christos return s3_bfd_score_info_to_howto (abfd, bfd_reloc, elf_reloc); 4082 1.1.1.2 christos else 4083 1.1.1.2 christos return s7_bfd_score_info_to_howto (abfd, bfd_reloc, elf_reloc); 4084 1.1.1.2 christos } 4085 1.1.1.2 christos 4086 1.1.1.9 christos static int 4087 1.1.1.2 christos _bfd_score_elf_relocate_section (bfd *output_bfd, 4088 1.1.1.6 christos struct bfd_link_info *info, 4089 1.1.1.6 christos bfd *input_bfd, 4090 1.1.1.6 christos asection *input_section, 4091 1.1.1.6 christos bfd_byte *contents, 4092 1.1.1.6 christos Elf_Internal_Rela *relocs, 4093 1.1.1.6 christos Elf_Internal_Sym *local_syms, 4094 1.1.1.6 christos asection **local_sections) 4095 1.1.1.2 christos { 4096 1.1.1.2 christos if (bfd_get_mach (output_bfd) == bfd_mach_score3) 4097 1.1.1.2 christos return s3_bfd_score_elf_relocate_section (output_bfd, 4098 1.1.1.6 christos info, input_bfd, input_section, contents, relocs, 4099 1.1.1.6 christos local_syms, local_sections); 4100 1.1.1.2 christos else 4101 1.1.1.2 christos return s7_bfd_score_elf_relocate_section (output_bfd, 4102 1.1.1.6 christos info, input_bfd, input_section, contents, relocs, 4103 1.1.1.6 christos local_syms, local_sections); 4104 1.1.1.2 christos } 4105 1.1.1.2 christos 4106 1.1.1.9 christos static bool 4107 1.1.1.2 christos _bfd_score_elf_check_relocs (bfd *abfd, 4108 1.1.1.6 christos struct bfd_link_info *info, 4109 1.1.1.6 christos asection *sec, 4110 1.1.1.6 christos const Elf_Internal_Rela *relocs) 4111 1.1.1.2 christos { 4112 1.1.1.2 christos if (bfd_get_mach (abfd) == bfd_mach_score3) 4113 1.1.1.2 christos return s3_bfd_score_elf_check_relocs (abfd, info, sec, relocs); 4114 1.1.1.2 christos else 4115 1.1.1.2 christos return s7_bfd_score_elf_check_relocs (abfd, info, sec, relocs); 4116 1.1.1.2 christos } 4117 1.1.1.2 christos 4118 1.1.1.9 christos static bool 4119 1.1.1.2 christos _bfd_score_elf_add_symbol_hook (bfd *abfd, 4120 1.1.1.6 christos struct bfd_link_info *info ATTRIBUTE_UNUSED, 4121 1.1.1.6 christos Elf_Internal_Sym *sym, 4122 1.1.1.6 christos const char **namep ATTRIBUTE_UNUSED, 4123 1.1.1.6 christos flagword *flagsp ATTRIBUTE_UNUSED, 4124 1.1.1.6 christos asection **secp, 4125 1.1.1.6 christos bfd_vma *valp) 4126 1.1.1.2 christos { 4127 1.1.1.2 christos if (bfd_get_mach (abfd) == bfd_mach_score3) 4128 1.1.1.2 christos return s3_bfd_score_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, 4129 1.1.1.6 christos secp, valp); 4130 1.1.1.2 christos else 4131 1.1.1.2 christos return s7_bfd_score_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, 4132 1.1.1.6 christos secp, valp); 4133 1.1.1.2 christos } 4134 1.1.1.2 christos 4135 1.1.1.2 christos static void 4136 1.1.1.2 christos _bfd_score_elf_symbol_processing (bfd *abfd, asymbol *asym) 4137 1.1.1.2 christos { 4138 1.1.1.2 christos if (bfd_get_mach (abfd) == bfd_mach_score3) 4139 1.1.1.2 christos return s3_bfd_score_elf_symbol_processing (abfd, asym); 4140 1.1.1.2 christos else 4141 1.1.1.2 christos return s7_bfd_score_elf_symbol_processing (abfd, asym); 4142 1.1.1.2 christos } 4143 1.1.1.2 christos 4144 1.1.1.2 christos static int 4145 1.1.1.2 christos _bfd_score_elf_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED, 4146 1.1.1.2 christos const char *name ATTRIBUTE_UNUSED, 4147 1.1.1.2 christos Elf_Internal_Sym *sym, 4148 1.1.1.2 christos asection *input_sec, 4149 1.1.1.2 christos struct elf_link_hash_entry *h ATTRIBUTE_UNUSED) 4150 1.1.1.2 christos { 4151 1.1.1.2 christos /* If link a empty .o, then this filed is NULL. */ 4152 1.1.1.2 christos if (info->input_bfds == NULL) 4153 1.1.1.2 christos { 4154 1.1.1.2 christos /* If we see a common symbol, which implies a relocatable link, then 4155 1.1.1.6 christos if a symbol was small common in an input file, mark it as small 4156 1.1.1.6 christos common in the output file. */ 4157 1.1.1.2 christos if (sym->st_shndx == SHN_COMMON && strcmp (input_sec->name, ".scommon") == 0) 4158 1.1.1.6 christos sym->st_shndx = SHN_SCORE_SCOMMON; 4159 1.1.1.2 christos return 1; 4160 1.1.1.2 christos } 4161 1.1.1.2 christos 4162 1.1.1.2 christos if (bfd_get_mach (info->input_bfds) == bfd_mach_score3) 4163 1.1.1.2 christos return s3_bfd_score_elf_link_output_symbol_hook (info, name, sym, input_sec, h); 4164 1.1.1.2 christos else 4165 1.1.1.2 christos return s7_bfd_score_elf_link_output_symbol_hook (info, name, sym, input_sec, h); 4166 1.1.1.2 christos } 4167 1.1.1.2 christos 4168 1.1.1.9 christos static bool 4169 1.1.1.2 christos _bfd_score_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED, 4170 1.1.1.6 christos asection *sec, 4171 1.1.1.6 christos int *retval) 4172 1.1.1.2 christos { 4173 1.1.1.2 christos if (bfd_get_mach (abfd) == bfd_mach_score3) 4174 1.1.1.2 christos return s3_bfd_score_elf_section_from_bfd_section (abfd, sec, retval); 4175 1.1.1.2 christos else 4176 1.1.1.2 christos return s7_bfd_score_elf_section_from_bfd_section (abfd, sec, retval); 4177 1.1.1.2 christos } 4178 1.1.1.2 christos 4179 1.1.1.9 christos static bool 4180 1.1.1.2 christos _bfd_score_elf_adjust_dynamic_symbol (struct bfd_link_info *info, 4181 1.1.1.6 christos struct elf_link_hash_entry *h) 4182 1.1.1.2 christos { 4183 1.1.1.2 christos if (bfd_get_mach (info->input_bfds) == bfd_mach_score3) 4184 1.1.1.2 christos return s3_bfd_score_elf_adjust_dynamic_symbol (info, h); 4185 1.1.1.2 christos else 4186 1.1.1.2 christos return s7_bfd_score_elf_adjust_dynamic_symbol (info, h); 4187 1.1.1.2 christos } 4188 1.1.1.2 christos 4189 1.1.1.9 christos static bool 4190 1.1.1.11 christos _bfd_score_elf_early_size_sections (bfd *output_bfd, 4191 1.1.1.11 christos struct bfd_link_info *info) 4192 1.1.1.2 christos { 4193 1.1.1.2 christos if (bfd_get_mach (output_bfd) == bfd_mach_score3) 4194 1.1.1.11 christos return s3_bfd_score_elf_early_size_sections (output_bfd, info); 4195 1.1.1.2 christos else 4196 1.1.1.11 christos return s7_bfd_score_elf_early_size_sections (output_bfd, info); 4197 1.1.1.2 christos } 4198 1.1.1.2 christos 4199 1.1.1.9 christos static bool 4200 1.1.1.11 christos _bfd_score_elf_late_size_sections (bfd *output_bfd, struct bfd_link_info *info) 4201 1.1.1.2 christos { 4202 1.1.1.2 christos if (bfd_get_mach (output_bfd) == bfd_mach_score3) 4203 1.1.1.11 christos return s3_bfd_score_elf_late_size_sections (output_bfd, info); 4204 1.1.1.2 christos else 4205 1.1.1.11 christos return s7_bfd_score_elf_late_size_sections (output_bfd, info); 4206 1.1.1.2 christos } 4207 1.1.1.2 christos 4208 1.1.1.9 christos static bool 4209 1.1.1.2 christos _bfd_score_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) 4210 1.1.1.2 christos { 4211 1.1.1.2 christos if (bfd_get_mach (abfd) == bfd_mach_score3) 4212 1.1.1.2 christos return s3_bfd_score_elf_create_dynamic_sections (abfd, info); 4213 1.1.1.2 christos else 4214 1.1.1.2 christos return s7_bfd_score_elf_create_dynamic_sections (abfd, info); 4215 1.1.1.2 christos } 4216 1.1.1.2 christos 4217 1.1.1.9 christos static bool 4218 1.1.1.2 christos _bfd_score_elf_finish_dynamic_symbol (bfd *output_bfd, 4219 1.1.1.6 christos struct bfd_link_info *info, 4220 1.1.1.6 christos struct elf_link_hash_entry *h, 4221 1.1.1.6 christos Elf_Internal_Sym *sym) 4222 1.1.1.2 christos { 4223 1.1.1.2 christos if (bfd_get_mach (output_bfd) == bfd_mach_score3) 4224 1.1.1.2 christos return s3_bfd_score_elf_finish_dynamic_symbol (output_bfd, info, h, sym); 4225 1.1.1.2 christos else 4226 1.1.1.2 christos return s7_bfd_score_elf_finish_dynamic_symbol (output_bfd, info, h, sym); 4227 1.1.1.2 christos } 4228 1.1.1.2 christos 4229 1.1.1.9 christos static bool 4230 1.1.1.2 christos _bfd_score_elf_finish_dynamic_sections (bfd *output_bfd, 4231 1.1.1.12 christos struct bfd_link_info *info, 4232 1.1.1.12 christos bfd_byte *buf) 4233 1.1.1.2 christos { 4234 1.1.1.2 christos if (bfd_get_mach (output_bfd) == bfd_mach_score3) 4235 1.1.1.12 christos return s3_bfd_score_elf_finish_dynamic_sections (output_bfd, info, buf); 4236 1.1.1.2 christos else 4237 1.1.1.12 christos return s7_bfd_score_elf_finish_dynamic_sections (output_bfd, info, buf); 4238 1.1.1.2 christos } 4239 1.1.1.2 christos 4240 1.1.1.9 christos static bool 4241 1.1.1.2 christos _bfd_score_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED, 4242 1.1.1.6 christos Elf_Internal_Shdr *hdr, 4243 1.1.1.6 christos asection *sec) 4244 1.1.1.2 christos { 4245 1.1.1.2 christos if (bfd_get_mach (abfd) == bfd_mach_score3) 4246 1.1.1.2 christos return s3_bfd_score_elf_fake_sections (abfd, hdr, sec); 4247 1.1.1.2 christos else 4248 1.1.1.2 christos return s7_bfd_score_elf_fake_sections (abfd, hdr, sec); 4249 1.1.1.2 christos } 4250 1.1.1.2 christos 4251 1.1.1.9 christos static bool 4252 1.1.1.2 christos _bfd_score_elf_section_processing (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Shdr *hdr) 4253 1.1.1.2 christos { 4254 1.1.1.2 christos if (bfd_get_mach (abfd) == bfd_mach_score3) 4255 1.1.1.2 christos return s3_bfd_score_elf_section_processing (abfd, hdr); 4256 1.1.1.2 christos else 4257 1.1.1.2 christos return s7_bfd_score_elf_section_processing (abfd, hdr); 4258 1.1.1.2 christos } 4259 1.1.1.2 christos 4260 1.1.1.9 christos static bool 4261 1.1.1.2 christos _bfd_score_elf_write_section (bfd *output_bfd, 4262 1.1.1.6 christos struct bfd_link_info *link_info ATTRIBUTE_UNUSED, 4263 1.1.1.6 christos asection *sec, bfd_byte *contents) 4264 1.1.1.2 christos { 4265 1.1.1.2 christos if (bfd_get_mach (output_bfd) == bfd_mach_score3) 4266 1.1.1.2 christos return s3_bfd_score_elf_write_section (output_bfd, sec, contents); 4267 1.1.1.2 christos else 4268 1.1.1.2 christos return s7_bfd_score_elf_write_section (output_bfd, sec, contents); 4269 1.1.1.2 christos } 4270 1.1.1.2 christos 4271 1.1.1.2 christos static void 4272 1.1.1.2 christos _bfd_score_elf_copy_indirect_symbol (struct bfd_link_info *info, 4273 1.1.1.6 christos struct elf_link_hash_entry *dir, 4274 1.1.1.6 christos struct elf_link_hash_entry *ind) 4275 1.1.1.2 christos { 4276 1.1.1.2 christos if (bfd_get_mach (info->input_bfds) == bfd_mach_score3) 4277 1.1.1.2 christos return s3_bfd_score_elf_copy_indirect_symbol (info, dir, ind); 4278 1.1.1.2 christos else 4279 1.1.1.2 christos return s7_bfd_score_elf_copy_indirect_symbol (info, dir, ind); 4280 1.1.1.2 christos } 4281 1.1.1.2 christos 4282 1.1.1.2 christos static void 4283 1.1.1.2 christos _bfd_score_elf_hide_symbol (struct bfd_link_info *info, 4284 1.1.1.6 christos struct elf_link_hash_entry *entry, 4285 1.1.1.9 christos bool force_local) 4286 1.1.1.2 christos { 4287 1.1.1.2 christos if (bfd_get_mach (info->input_bfds) == bfd_mach_score3) 4288 1.1.1.2 christos return s3_bfd_score_elf_hide_symbol (info, entry, force_local); 4289 1.1.1.2 christos else 4290 1.1.1.2 christos return s7_bfd_score_elf_hide_symbol (info, entry, force_local); 4291 1.1.1.2 christos } 4292 1.1.1.2 christos 4293 1.1.1.9 christos static bool 4294 1.1.1.2 christos _bfd_score_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie, 4295 1.1.1.6 christos struct bfd_link_info *info) 4296 1.1.1.2 christos { 4297 1.1.1.2 christos if (bfd_get_mach (abfd) == bfd_mach_score3) 4298 1.1.1.2 christos return s3_bfd_score_elf_discard_info (abfd, cookie, info); 4299 1.1.1.2 christos else 4300 1.1.1.2 christos return s7_bfd_score_elf_discard_info (abfd, cookie, info); 4301 1.1.1.2 christos } 4302 1.1.1.2 christos 4303 1.1.1.9 christos static bool 4304 1.1.1.2 christos _bfd_score_elf_ignore_discarded_relocs (asection *sec) 4305 1.1.1.2 christos { 4306 1.1.1.2 christos if (bfd_get_mach (sec->owner) == bfd_mach_score3) 4307 1.1.1.2 christos return s3_bfd_score_elf_ignore_discarded_relocs (sec); 4308 1.1.1.2 christos else 4309 1.1.1.2 christos return s7_bfd_score_elf_ignore_discarded_relocs (sec); 4310 1.1.1.2 christos } 4311 1.1.1.2 christos 4312 1.1.1.2 christos static asection * 4313 1.1.1.2 christos _bfd_score_elf_gc_mark_hook (asection *sec, 4314 1.1.1.6 christos struct bfd_link_info *info, 4315 1.1.1.12 christos struct elf_reloc_cookie *cookie, 4316 1.1.1.6 christos struct elf_link_hash_entry *h, 4317 1.1.1.12 christos unsigned int symndx) 4318 1.1.1.2 christos { 4319 1.1.1.2 christos if (bfd_get_mach (info->input_bfds) == bfd_mach_score3) 4320 1.1.1.12 christos return s3_bfd_score_elf_gc_mark_hook (sec, info, cookie, h, symndx); 4321 1.1.1.2 christos else 4322 1.1.1.12 christos return s7_bfd_score_elf_gc_mark_hook (sec, info, cookie, h, symndx); 4323 1.1.1.2 christos } 4324 1.1.1.2 christos 4325 1.1.1.9 christos static bool 4326 1.1.1.2 christos _bfd_score_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) 4327 1.1.1.2 christos { 4328 1.1.1.2 christos if (bfd_get_mach (abfd) == bfd_mach_score3) 4329 1.1.1.2 christos return s3_bfd_score_elf_grok_prstatus (abfd, note); 4330 1.1.1.2 christos else 4331 1.1.1.2 christos return s7_bfd_score_elf_grok_prstatus (abfd, note); 4332 1.1.1.2 christos } 4333 1.1.1.2 christos 4334 1.1.1.9 christos static bool 4335 1.1.1.2 christos _bfd_score_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) 4336 1.1.1.2 christos { 4337 1.1.1.2 christos if (bfd_get_mach (abfd) == bfd_mach_score3) 4338 1.1.1.2 christos return s3_bfd_score_elf_grok_psinfo (abfd, note); 4339 1.1.1.2 christos else 4340 1.1.1.2 christos return s7_bfd_score_elf_grok_psinfo (abfd, note); 4341 1.1.1.2 christos } 4342 1.1.1.2 christos 4343 1.1.1.2 christos static reloc_howto_type * 4344 1.1.1.2 christos elf32_score_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code) 4345 1.1.1.2 christos { 4346 1.1.1.2 christos /* s3: NOTE!!! 4347 1.1.1.2 christos gas will call elf32_score_reloc_type_lookup, and don't write elf file. 4348 1.1.1.2 christos So just using score3, but we don't know ld will call this or not. 4349 1.1.1.2 christos If so, this way can't work. */ 4350 1.1.1.2 christos 4351 1.1.1.2 christos if (score3) 4352 1.1.1.2 christos return s3_elf32_score_reloc_type_lookup (abfd, code); 4353 1.1.1.2 christos else 4354 1.1.1.2 christos return s7_elf32_score_reloc_type_lookup (abfd, code); 4355 1.1.1.2 christos } 4356 1.1.1.2 christos 4357 1.1.1.2 christos /* Create a score elf linker hash table. 4358 1.1.1.2 christos This is a copy of _bfd_elf_link_hash_table_create() except with a 4359 1.1.1.2 christos different hash table entry creation function. */ 4360 1.1.1.2 christos 4361 1.1.1.2 christos static struct bfd_link_hash_table * 4362 1.1.1.2 christos elf32_score_link_hash_table_create (bfd *abfd) 4363 1.1.1.2 christos { 4364 1.1.1.2 christos struct elf_link_hash_table *ret; 4365 1.1.1.9 christos size_t amt = sizeof (struct elf_link_hash_table); 4366 1.1.1.2 christos 4367 1.1.1.4 christos ret = (struct elf_link_hash_table *) bfd_zmalloc (amt); 4368 1.1.1.2 christos if (ret == NULL) 4369 1.1.1.2 christos return NULL; 4370 1.1.1.2 christos 4371 1.1.1.2 christos if (!_bfd_elf_link_hash_table_init (ret, abfd, score_elf_link_hash_newfunc, 4372 1.1.1.11 christos sizeof (struct score_elf_link_hash_entry))) 4373 1.1.1.2 christos { 4374 1.1.1.2 christos free (ret); 4375 1.1.1.2 christos return NULL; 4376 1.1.1.2 christos } 4377 1.1.1.2 christos 4378 1.1.1.2 christos return &ret->root; 4379 1.1.1.2 christos } 4380 1.1.1.2 christos 4381 1.1.1.9 christos static bool 4382 1.1.1.2 christos elf32_score_print_private_bfd_data (bfd *abfd, void * ptr) 4383 1.1.1.2 christos { 4384 1.1.1.2 christos if (bfd_get_mach (abfd) == bfd_mach_score3) 4385 1.1.1.2 christos return s3_elf32_score_print_private_bfd_data (abfd, ptr); 4386 1.1.1.2 christos else 4387 1.1.1.2 christos return s7_elf32_score_print_private_bfd_data (abfd, ptr); 4388 1.1.1.2 christos } 4389 1.1.1.2 christos 4390 1.1.1.9 christos static bool 4391 1.1.1.6 christos elf32_score_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) 4392 1.1.1.2 christos { 4393 1.1.1.6 christos if (bfd_get_mach (info->output_bfd) == bfd_mach_score3) 4394 1.1.1.6 christos return s3_elf32_score_merge_private_bfd_data (ibfd, info); 4395 1.1.1.2 christos else 4396 1.1.1.6 christos return s7_elf32_score_merge_private_bfd_data (ibfd, info); 4397 1.1.1.2 christos } 4398 1.1.1.2 christos 4399 1.1.1.9 christos static bool 4400 1.1.1.2 christos elf32_score_new_section_hook (bfd *abfd, asection *sec) 4401 1.1.1.2 christos { 4402 1.1.1.2 christos if (bfd_get_mach (abfd) == bfd_mach_score3) 4403 1.1.1.2 christos return s3_elf32_score_new_section_hook (abfd, sec); 4404 1.1.1.2 christos else 4405 1.1.1.2 christos return s7_elf32_score_new_section_hook (abfd, sec); 4406 1.1.1.2 christos } 4407 1.1.1.2 christos 4408 1.1.1.2 christos 4409 1.1.1.2 christos /* s3_s7: don't need to split. */ 4410 1.1.1.2 christos 4411 1.1.1.2 christos /* Set the right machine number. */ 4412 1.1.1.9 christos static bool 4413 1.1.1.2 christos _bfd_score_elf_score_object_p (bfd * abfd) 4414 1.1.1.2 christos { 4415 1.1.1.2 christos int e_set = bfd_mach_score7; 4416 1.1.1.2 christos 4417 1.1.1.2 christos if (elf_elfheader (abfd)->e_machine == EM_SCORE) 4418 1.1.1.2 christos { 4419 1.1.1.2 christos int e_mach = elf_elfheader (abfd)->e_flags & EF_SCORE_MACH & EF_OMIT_PIC_FIXDD; 4420 1.1.1.2 christos switch (e_mach) 4421 1.1.1.6 christos { 4422 1.1.1.6 christos /* Set default target is score7. */ 4423 1.1.1.6 christos default: 4424 1.1.1.6 christos case E_SCORE_MACH_SCORE7: 4425 1.1.1.6 christos e_set = bfd_mach_score7; 4426 1.1.1.6 christos break; 4427 1.1.1.6 christos 4428 1.1.1.6 christos case E_SCORE_MACH_SCORE3: 4429 1.1.1.6 christos e_set = bfd_mach_score3; 4430 1.1.1.6 christos break; 4431 1.1.1.6 christos } 4432 1.1.1.2 christos } 4433 1.1.1.2 christos 4434 1.1.1.2 christos return bfd_default_set_arch_mach (abfd, bfd_arch_score, e_set); 4435 1.1.1.2 christos } 4436 1.1.1.2 christos 4437 1.1.1.9 christos bool 4438 1.1.1.2 christos _bfd_score_elf_common_definition (Elf_Internal_Sym *sym) 4439 1.1.1.2 christos { 4440 1.1.1.2 christos return (sym->st_shndx == SHN_COMMON || sym->st_shndx == SHN_SCORE_SCOMMON); 4441 1.1.1.2 christos } 4442 1.1.1.2 christos 4443 1.1.1.2 christos /*****************************************************************************/ 4444 1.1.1.2 christos 4445 1.1 skrll 4446 1.1.1.6 christos #define USE_REL 1 4447 1.1.1.6 christos #define TARGET_LITTLE_SYM score_elf32_le_vec 4448 1.1.1.6 christos #define TARGET_LITTLE_NAME "elf32-littlescore" 4449 1.1.1.6 christos #define TARGET_BIG_SYM score_elf32_be_vec 4450 1.1.1.6 christos #define TARGET_BIG_NAME "elf32-bigscore" 4451 1.1.1.6 christos #define ELF_ARCH bfd_arch_score 4452 1.1.1.6 christos #define ELF_MACHINE_CODE EM_SCORE 4453 1.1.1.6 christos #define ELF_MACHINE_ALT1 EM_SCORE_OLD 4454 1.1.1.11 christos #define ELF_TARGET_ID SCORE_ELF_DATA 4455 1.1.1.6 christos #define ELF_MAXPAGESIZE 0x8000 4456 1.1.1.6 christos 4457 1.1.1.7 christos #define elf_info_to_howto NULL 4458 1.1.1.6 christos #define elf_info_to_howto_rel _bfd_score_info_to_howto 4459 1.1.1.6 christos #define elf_backend_relocate_section _bfd_score_elf_relocate_section 4460 1.1.1.6 christos #define elf_backend_check_relocs _bfd_score_elf_check_relocs 4461 1.1.1.6 christos #define elf_backend_add_symbol_hook _bfd_score_elf_add_symbol_hook 4462 1.1.1.6 christos #define elf_backend_symbol_processing _bfd_score_elf_symbol_processing 4463 1.1 skrll #define elf_backend_link_output_symbol_hook \ 4464 1.1 skrll _bfd_score_elf_link_output_symbol_hook 4465 1.1 skrll #define elf_backend_section_from_bfd_section \ 4466 1.1 skrll _bfd_score_elf_section_from_bfd_section 4467 1.1 skrll #define elf_backend_adjust_dynamic_symbol \ 4468 1.1 skrll _bfd_score_elf_adjust_dynamic_symbol 4469 1.1.1.11 christos #define elf_backend_early_size_sections \ 4470 1.1.1.11 christos _bfd_score_elf_early_size_sections 4471 1.1.1.11 christos #define elf_backend_late_size_sections \ 4472 1.1.1.11 christos _bfd_score_elf_late_size_sections 4473 1.1.1.7 christos #define elf_backend_omit_section_dynsym _bfd_elf_omit_section_dynsym_all 4474 1.1 skrll #define elf_backend_create_dynamic_sections \ 4475 1.1 skrll _bfd_score_elf_create_dynamic_sections 4476 1.1 skrll #define elf_backend_finish_dynamic_symbol \ 4477 1.1 skrll _bfd_score_elf_finish_dynamic_symbol 4478 1.1 skrll #define elf_backend_finish_dynamic_sections \ 4479 1.1 skrll _bfd_score_elf_finish_dynamic_sections 4480 1.1.1.6 christos #define elf_backend_fake_sections _bfd_score_elf_fake_sections 4481 1.1.1.6 christos #define elf_backend_section_processing _bfd_score_elf_section_processing 4482 1.1.1.6 christos #define elf_backend_write_section _bfd_score_elf_write_section 4483 1.1 skrll #define elf_backend_copy_indirect_symbol _bfd_score_elf_copy_indirect_symbol 4484 1.1.1.6 christos #define elf_backend_hide_symbol _bfd_score_elf_hide_symbol 4485 1.1.1.6 christos #define elf_backend_discard_info _bfd_score_elf_discard_info 4486 1.1 skrll #define elf_backend_ignore_discarded_relocs \ 4487 1.1 skrll _bfd_score_elf_ignore_discarded_relocs 4488 1.1.1.6 christos #define elf_backend_gc_mark_hook _bfd_score_elf_gc_mark_hook 4489 1.1.1.6 christos #define elf_backend_grok_prstatus _bfd_score_elf_grok_prstatus 4490 1.1.1.6 christos #define elf_backend_grok_psinfo _bfd_score_elf_grok_psinfo 4491 1.1.1.6 christos #define elf_backend_can_gc_sections 1 4492 1.1.1.6 christos #define elf_backend_want_plt_sym 0 4493 1.1.1.6 christos #define elf_backend_got_header_size (4 * SCORE_RESERVED_GOTNO) 4494 1.1.1.6 christos #define elf_backend_plt_header_size 0 4495 1.1.1.9 christos #define elf_backend_collect true 4496 1.1.1.9 christos #define elf_backend_type_change_ok true 4497 1.1.1.6 christos #define elf_backend_object_p _bfd_score_elf_score_object_p 4498 1.1 skrll 4499 1.1.1.6 christos #define bfd_elf32_bfd_reloc_type_lookup elf32_score_reloc_type_lookup 4500 1.1 skrll #define bfd_elf32_bfd_reloc_name_lookup \ 4501 1.1 skrll elf32_score_reloc_name_lookup 4502 1.1 skrll #define bfd_elf32_bfd_link_hash_table_create elf32_score_link_hash_table_create 4503 1.1 skrll #define bfd_elf32_bfd_print_private_bfd_data elf32_score_print_private_bfd_data 4504 1.1 skrll #define bfd_elf32_bfd_merge_private_bfd_data elf32_score_merge_private_bfd_data 4505 1.1.1.6 christos #define bfd_elf32_new_section_hook elf32_score_new_section_hook 4506 1.1 skrll 4507 1.1 skrll #include "elf32-target.h" 4508