1 /* Morpho Technologies MT specific support for 32-bit ELF 2 Copyright (C) 2001-2014 Free Software Foundation, Inc. 3 4 This file is part of BFD, the Binary File Descriptor library. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, 19 MA 02111-1307, USA. */ 20 21 #include "sysdep.h" 22 #include "bfd.h" 23 #include "libbfd.h" 24 #include "elf-bfd.h" 25 #include "elf/mt.h" 26 27 /* Prototypes. */ 28 static reloc_howto_type * mt_reloc_type_lookup 29 (bfd *, bfd_reloc_code_real_type); 30 31 static void mt_info_to_howto_rela 32 (bfd *, arelent *, Elf_Internal_Rela *); 33 34 static bfd_reloc_status_type mt_elf_relocate_hi16 35 (bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma); 36 37 static bfd_reloc_status_type mt_final_link_relocate 38 (reloc_howto_type *, bfd *, asection *, bfd_byte *, 39 Elf_Internal_Rela *, bfd_vma); 40 41 static bfd_boolean mt_elf_relocate_section 42 (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, 43 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **); 44 45 /* Relocation tables. */ 46 static reloc_howto_type mt_elf_howto_table [] = 47 { 48 /* This reloc does nothing. */ 49 HOWTO (R_MT_NONE, /* type */ 50 0, /* rightshift */ 51 2, /* size (0 = byte, 1 = short, 2 = long) */ 52 32, /* bitsize */ 53 FALSE, /* pc_relative */ 54 0, /* bitpos */ 55 complain_overflow_dont, /* complain_on_overflow */ 56 bfd_elf_generic_reloc, /* special_function */ 57 "R_MT_NONE", /* name */ 58 FALSE, /* partial_inplace */ 59 0 , /* src_mask */ 60 0, /* dst_mask */ 61 FALSE), /* pcrel_offset */ 62 63 /* A 16 bit absolute relocation. */ 64 HOWTO (R_MT_16, /* type */ 65 0, /* rightshift */ 66 2, /* size (0 = byte, 1 = short, 2 = long) */ 67 16, /* bitsize */ 68 FALSE, /* pc_relative */ 69 0, /* bitpos */ 70 complain_overflow_dont, /* complain_on_overflow */ 71 bfd_elf_generic_reloc, /* special_function */ 72 "R_MT_16", /* name */ 73 FALSE, /* partial_inplace */ 74 0 , /* src_mask */ 75 0xffff, /* dst_mask */ 76 FALSE), /* pcrel_offset */ 77 78 /* A 32 bit absolute relocation. */ 79 HOWTO (R_MT_32, /* type */ 80 0, /* rightshift */ 81 2, /* size (0 = byte, 1 = short, 2 = long) */ 82 32, /* bitsize */ 83 FALSE, /* pc_relative */ 84 0, /* bitpos */ 85 complain_overflow_dont, /* complain_on_overflow */ 86 bfd_elf_generic_reloc, /* special_function */ 87 "R_MT_32", /* name */ 88 FALSE, /* partial_inplace */ 89 0 , /* src_mask */ 90 0xffffffff, /* dst_mask */ 91 FALSE), /* pcrel_offset */ 92 93 /* A 32 bit pc-relative relocation. */ 94 HOWTO (R_MT_32_PCREL, /* type */ 95 0, /* rightshift */ 96 2, /* size (0 = byte, 1 = short, 2 = long) */ 97 32, /* bitsize */ 98 TRUE, /* pc_relative */ 99 0, /* bitpos */ 100 complain_overflow_dont, /* complain_on_overflow */ 101 bfd_elf_generic_reloc, /* special_function */ 102 "R_MT_32_PCREL", /* name */ 103 FALSE, /* partial_inplace */ 104 0 , /* src_mask */ 105 0xffffffff, /* dst_mask */ 106 TRUE), /* pcrel_offset */ 107 108 /* A 16 bit pc-relative relocation. */ 109 HOWTO (R_MT_PC16, /* type */ 110 0, /* rightshift */ 111 2, /* size (0 = byte, 1 = short, 2 = long) */ 112 16, /* bitsize */ 113 TRUE, /* pc_relative */ 114 0, /* bitpos */ 115 complain_overflow_signed, /* complain_on_overflow */ 116 bfd_elf_generic_reloc, /* special_function */ 117 "R_MT_PC16", /* name */ 118 FALSE, /* partial_inplace */ 119 0, /* src_mask */ 120 0xffff, /* dst_mask */ 121 TRUE), /* pcrel_offset */ 122 123 /* high 16 bits of symbol value. */ 124 HOWTO (R_MT_HI16, /* type */ 125 0, /* rightshift */ 126 2, /* size (0 = byte, 1 = short, 2 = long) */ 127 16, /* bitsize */ 128 FALSE, /* pc_relative */ 129 0, /* bitpos */ 130 complain_overflow_dont, /* complain_on_overflow */ 131 bfd_elf_generic_reloc, /* special_function */ 132 "R_MT_HI16", /* name */ 133 FALSE, /* partial_inplace */ 134 0xffff0000, /* src_mask */ 135 0xffff0000, /* dst_mask */ 136 FALSE), /* pcrel_offset */ 137 138 /* Low 16 bits of symbol value. */ 139 HOWTO (R_MT_LO16, /* type */ 140 0, /* rightshift */ 141 2, /* size (0 = byte, 1 = short, 2 = long) */ 142 16, /* bitsize */ 143 FALSE, /* pc_relative */ 144 0, /* bitpos */ 145 complain_overflow_dont, /* complain_on_overflow */ 146 bfd_elf_generic_reloc, /* special_function */ 147 "R_MT_LO16", /* name */ 148 FALSE, /* partial_inplace */ 149 0xffff, /* src_mask */ 150 0xffff, /* dst_mask */ 151 FALSE), /* pcrel_offset */ 152 }; 153 154 /* Map BFD reloc types to MT ELF reloc types. */ 155 156 static reloc_howto_type * 157 mt_reloc_type_lookup 158 (bfd * abfd ATTRIBUTE_UNUSED, 159 bfd_reloc_code_real_type code) 160 { 161 /* Note that the mt_elf_howto_table is indxed by the R_ 162 constants. Thus, the order that the howto records appear in the 163 table *must* match the order of the relocation types defined in 164 include/elf/mt.h. */ 165 166 switch (code) 167 { 168 case BFD_RELOC_NONE: 169 return &mt_elf_howto_table[ (int) R_MT_NONE]; 170 case BFD_RELOC_16: 171 return &mt_elf_howto_table[ (int) R_MT_16]; 172 case BFD_RELOC_32: 173 return &mt_elf_howto_table[ (int) R_MT_32]; 174 case BFD_RELOC_32_PCREL: 175 return &mt_elf_howto_table[ (int) R_MT_32_PCREL]; 176 case BFD_RELOC_16_PCREL: 177 return &mt_elf_howto_table[ (int) R_MT_PC16]; 178 case BFD_RELOC_HI16: 179 return &mt_elf_howto_table[ (int) R_MT_HI16]; 180 case BFD_RELOC_LO16: 181 return &mt_elf_howto_table[ (int) R_MT_LO16]; 182 183 default: 184 /* Pacify gcc -Wall. */ 185 return NULL; 186 } 187 return NULL; 188 } 189 190 static reloc_howto_type * 191 mt_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 192 const char *r_name) 193 { 194 unsigned int i; 195 196 for (i = 0; 197 i < sizeof (mt_elf_howto_table) / sizeof (mt_elf_howto_table[0]); 198 i++) 199 if (mt_elf_howto_table[i].name != NULL 200 && strcasecmp (mt_elf_howto_table[i].name, r_name) == 0) 201 return &mt_elf_howto_table[i]; 202 203 return NULL; 204 } 205 206 bfd_reloc_status_type 207 mt_elf_relocate_hi16 208 (bfd * input_bfd, 209 Elf_Internal_Rela * relhi, 210 bfd_byte * contents, 211 bfd_vma value) 212 { 213 bfd_vma insn; 214 215 insn = bfd_get_32 (input_bfd, contents + relhi->r_offset); 216 217 value += relhi->r_addend; 218 value >>= 16; 219 insn = ((insn & ~0xFFFF) | value); 220 221 bfd_put_32 (input_bfd, insn, contents + relhi->r_offset); 222 return bfd_reloc_ok; 223 } 224 225 /* XXX: The following code is the result of a cut&paste. This unfortunate 227 practice is very widespread in the various target back-end files. */ 228 229 /* Set the howto pointer for a MT ELF reloc. */ 230 231 static void 232 mt_info_to_howto_rela 233 (bfd * abfd ATTRIBUTE_UNUSED, 234 arelent * cache_ptr, 235 Elf_Internal_Rela * dst) 236 { 237 unsigned int r_type; 238 239 r_type = ELF32_R_TYPE (dst->r_info); 240 cache_ptr->howto = & mt_elf_howto_table [r_type]; 241 } 242 243 /* Perform a single relocation. By default we use the standard BFD 244 routines. */ 245 246 static bfd_reloc_status_type 247 mt_final_link_relocate 248 (reloc_howto_type * howto, 249 bfd * input_bfd, 250 asection * input_section, 251 bfd_byte * contents, 252 Elf_Internal_Rela * rel, 253 bfd_vma relocation) 254 { 255 return _bfd_final_link_relocate (howto, input_bfd, input_section, 256 contents, rel->r_offset, 257 relocation, rel->r_addend); 258 } 259 260 /* Relocate a MT ELF section. 261 There is some attempt to make this function usable for many architectures, 262 both USE_REL and USE_RELA ['twould be nice if such a critter existed], 263 if only to serve as a learning tool. 264 265 The RELOCATE_SECTION function is called by the new ELF backend linker 266 to handle the relocations for a section. 267 268 The relocs are always passed as Rela structures; if the section 269 actually uses Rel structures, the r_addend field will always be 270 zero. 271 272 This function is responsible for adjusting the section contents as 273 necessary, and (if using Rela relocs and generating a relocatable 274 output file) adjusting the reloc addend as necessary. 275 276 This function does not have to worry about setting the reloc 277 address or the reloc symbol index. 278 279 LOCAL_SYMS is a pointer to the swapped in local symbols. 280 281 LOCAL_SECTIONS is an array giving the section in the input file 282 corresponding to the st_shndx field of each local symbol. 283 284 The global hash table entry for the global symbols can be found 285 via elf_sym_hashes (input_bfd). 286 287 When generating relocatable output, this function must handle 288 STB_LOCAL/STT_SECTION symbols specially. The output symbol is 289 going to be the section symbol corresponding to the output 290 section, which means that the addend must be adjusted 291 accordingly. */ 292 293 static bfd_boolean 294 mt_elf_relocate_section 295 (bfd * output_bfd ATTRIBUTE_UNUSED, 296 struct bfd_link_info * info, 297 bfd * input_bfd, 298 asection * input_section, 299 bfd_byte * contents, 300 Elf_Internal_Rela * relocs, 301 Elf_Internal_Sym * local_syms, 302 asection ** local_sections) 303 { 304 Elf_Internal_Shdr * symtab_hdr; 305 struct elf_link_hash_entry ** sym_hashes; 306 Elf_Internal_Rela * rel; 307 Elf_Internal_Rela * relend; 308 309 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; 310 sym_hashes = elf_sym_hashes (input_bfd); 311 relend = relocs + input_section->reloc_count; 312 313 for (rel = relocs; rel < relend; rel ++) 314 { 315 reloc_howto_type * howto; 316 unsigned long r_symndx; 317 Elf_Internal_Sym * sym; 318 asection * sec; 319 struct elf_link_hash_entry * h; 320 bfd_vma relocation; 321 bfd_reloc_status_type r; 322 const char * name = NULL; 323 int r_type; 324 325 r_type = ELF32_R_TYPE (rel->r_info); 326 327 r_symndx = ELF32_R_SYM (rel->r_info); 328 329 howto = mt_elf_howto_table + ELF32_R_TYPE (rel->r_info); 330 h = NULL; 331 sym = NULL; 332 sec = NULL; 333 334 if (r_symndx < symtab_hdr->sh_info) 335 { 336 sym = local_syms + r_symndx; 337 sec = local_sections [r_symndx]; 338 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 339 340 name = bfd_elf_string_from_elf_section 341 (input_bfd, symtab_hdr->sh_link, sym->st_name); 342 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name; 343 } 344 else 345 { 346 bfd_boolean unresolved_reloc; 347 bfd_boolean warned, ignored; 348 349 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 350 r_symndx, symtab_hdr, sym_hashes, 351 h, sec, relocation, 352 unresolved_reloc, warned, ignored); 353 354 name = h->root.root.string; 355 } 356 357 if (sec != NULL && discarded_section (sec)) 358 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, 359 rel, 1, relend, howto, 0, contents); 360 361 if (info->relocatable) 362 continue; 363 364 /* Finally, the sole MT-specific part. */ 365 switch (r_type) 366 { 367 case R_MT_HI16: 368 r = mt_elf_relocate_hi16 (input_bfd, rel, contents, relocation); 369 break; 370 default: 371 r = mt_final_link_relocate (howto, input_bfd, input_section, 372 contents, rel, relocation); 373 break; 374 } 375 376 377 if (r != bfd_reloc_ok) 378 { 379 const char * msg = (const char *) NULL; 380 381 switch (r) 382 { 383 case bfd_reloc_overflow: 384 r = info->callbacks->reloc_overflow 385 (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0, 386 input_bfd, input_section, rel->r_offset); 387 break; 388 389 case bfd_reloc_undefined: 390 r = info->callbacks->undefined_symbol 391 (info, name, input_bfd, input_section, rel->r_offset, TRUE); 392 break; 393 394 case bfd_reloc_outofrange: 395 msg = _("internal error: out of range error"); 396 break; 397 398 case bfd_reloc_dangerous: 399 msg = _("internal error: dangerous relocation"); 400 break; 401 402 default: 403 msg = _("internal error: unknown error"); 404 break; 405 } 406 407 if (msg) 408 r = info->callbacks->warning 409 (info, msg, name, input_bfd, input_section, rel->r_offset); 410 411 if (! r) 412 return FALSE; 413 } 414 } 415 416 return TRUE; 417 } 418 419 /* Look through the relocs for a section during the first phase. 420 Since we don't do .gots or .plts, we just need to consider the 421 virtual table relocs for gc. */ 422 423 static bfd_boolean 424 mt_elf_check_relocs 425 (bfd * abfd, 426 struct bfd_link_info * info, 427 asection * sec, 428 const Elf_Internal_Rela * relocs) 429 { 430 Elf_Internal_Shdr * symtab_hdr; 431 struct elf_link_hash_entry ** sym_hashes; 432 const Elf_Internal_Rela * rel; 433 const Elf_Internal_Rela * rel_end; 434 435 if (info->relocatable) 436 return TRUE; 437 438 symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 439 sym_hashes = elf_sym_hashes (abfd); 440 441 rel_end = relocs + sec->reloc_count; 442 for (rel = relocs; rel < rel_end; rel++) 443 { 444 struct elf_link_hash_entry *h; 445 unsigned long r_symndx; 446 447 r_symndx = ELF32_R_SYM (rel->r_info); 448 if (r_symndx < symtab_hdr->sh_info) 449 h = NULL; 450 else 451 { 452 h = sym_hashes[r_symndx - symtab_hdr->sh_info]; 453 while (h->root.type == bfd_link_hash_indirect 454 || h->root.type == bfd_link_hash_warning) 455 h = (struct elf_link_hash_entry *) h->root.u.i.link; 456 457 /* PR15323, ref flags aren't set for references in the same 458 object. */ 459 h->root.non_ir_ref = 1; 460 } 461 } 462 463 return TRUE; 464 } 465 466 /* Return the MACH for an e_flags value. */ 467 468 static int 469 elf32_mt_machine (bfd *abfd) 470 { 471 switch (elf_elfheader (abfd)->e_flags & EF_MT_CPU_MASK) 472 { 473 case EF_MT_CPU_MRISC: return bfd_mach_ms1; 474 case EF_MT_CPU_MRISC2: return bfd_mach_mrisc2; 475 case EF_MT_CPU_MS2: return bfd_mach_ms2; 476 } 477 478 return bfd_mach_ms1; 479 } 480 481 static bfd_boolean 482 mt_elf_object_p (bfd * abfd) 483 { 484 bfd_default_set_arch_mach (abfd, bfd_arch_mt, elf32_mt_machine (abfd)); 485 486 return TRUE; 487 } 488 489 /* Function to set the ELF flag bits. */ 490 491 static bfd_boolean 492 mt_elf_set_private_flags (bfd * abfd, 493 flagword flags) 494 { 495 elf_elfheader (abfd)->e_flags = flags; 496 elf_flags_init (abfd) = TRUE; 497 return TRUE; 498 } 499 500 /* Merge backend specific data from an object file to the output 501 object file when linking. */ 502 503 static bfd_boolean 504 mt_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd) 505 { 506 flagword old_flags, new_flags; 507 bfd_boolean ok = TRUE; 508 509 /* Check if we have the same endianness. */ 510 if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE) 511 return FALSE; 512 513 /* If they're not both mt, then merging is meaningless, so just 514 don't do it. */ 515 if (strcmp (ibfd->arch_info->arch_name, "mt") != 0) 516 return TRUE; 517 if (strcmp (obfd->arch_info->arch_name, "mt") != 0) 518 return TRUE; 519 520 new_flags = elf_elfheader (ibfd)->e_flags; 521 old_flags = elf_elfheader (obfd)->e_flags; 522 523 #ifdef DEBUG 524 _bfd_error_handler ("%B: old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s", 525 ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no"); 526 #endif 527 528 if (!elf_flags_init (obfd)) 529 { 530 old_flags = new_flags; 531 elf_flags_init (obfd) = TRUE; 532 } 533 else if ((new_flags & EF_MT_CPU_MASK) != (old_flags & EF_MT_CPU_MASK)) 534 { 535 /* CPU has changed. This is invalid, because MRISC, MRISC2 and 536 MS2 are not subsets of each other. */ 537 ok = FALSE; 538 } 539 540 if (ok) 541 { 542 obfd->arch_info = ibfd->arch_info; 543 elf_elfheader (obfd)->e_flags = old_flags; 544 } 545 546 return ok; 547 } 548 549 static bfd_boolean 550 mt_elf_print_private_bfd_data (bfd * abfd, void * ptr) 551 { 552 FILE * file = (FILE *) ptr; 553 flagword flags; 554 555 BFD_ASSERT (abfd != NULL && ptr != NULL); 556 557 /* Print normal ELF private data. */ 558 _bfd_elf_print_private_bfd_data (abfd, ptr); 559 560 flags = elf_elfheader (abfd)->e_flags; 561 fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags); 562 563 switch (flags & EF_MT_CPU_MASK) 564 { 565 default: 566 case EF_MT_CPU_MRISC: fprintf (file, " ms1-16-002"); break; 567 case EF_MT_CPU_MRISC2: fprintf (file, " ms1-16-003"); break; 568 case EF_MT_CPU_MS2: fprintf (file, " ms2"); break; 569 } 570 571 fputc ('\n', file); 572 573 return TRUE; 574 } 575 576 577 #define TARGET_BIG_SYM mt_elf32_vec 579 #define TARGET_BIG_NAME "elf32-mt" 580 581 #define ELF_ARCH bfd_arch_mt 582 #define ELF_MACHINE_CODE EM_MT 583 #define ELF_MAXPAGESIZE 1 /* No pages on the MT. */ 584 585 #define elf_info_to_howto_rel NULL 586 #define elf_info_to_howto mt_info_to_howto_rela 587 588 #define elf_backend_relocate_section mt_elf_relocate_section 589 590 #define bfd_elf32_bfd_reloc_type_lookup mt_reloc_type_lookup 591 #define bfd_elf32_bfd_reloc_name_lookup mt_reloc_name_lookup 592 593 #define elf_backend_check_relocs mt_elf_check_relocs 594 #define elf_backend_object_p mt_elf_object_p 595 #define elf_backend_rela_normal 1 596 597 #define elf_backend_can_gc_sections 1 598 599 #define bfd_elf32_bfd_set_private_flags mt_elf_set_private_flags 600 #define bfd_elf32_bfd_merge_private_bfd_data mt_elf_merge_private_bfd_data 601 #define bfd_elf32_bfd_print_private_bfd_data mt_elf_print_private_bfd_data 602 603 #include "elf32-target.h" 604