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