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