1 /* Morpho Technologies MT specific support for 32-bit ELF 2 Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 3 Free Software Foundation, Inc. 4 5 This file is part of BFD, the Binary File Descriptor library. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, 20 MA 02111-1307, USA. */ 21 22 #include "sysdep.h" 23 #include "bfd.h" 24 #include "libbfd.h" 25 #include "elf-bfd.h" 26 #include "elf/mt.h" 27 28 /* Prototypes. */ 29 static reloc_howto_type * mt_reloc_type_lookup 30 (bfd *, bfd_reloc_code_real_type); 31 32 static void mt_info_to_howto_rela 33 (bfd *, arelent *, Elf_Internal_Rela *); 34 35 static bfd_reloc_status_type mt_elf_relocate_hi16 36 (bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma); 37 38 static bfd_reloc_status_type mt_final_link_relocate 39 (reloc_howto_type *, bfd *, asection *, bfd_byte *, 40 Elf_Internal_Rela *, bfd_vma); 41 42 static bfd_boolean mt_elf_relocate_section 43 (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, 44 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **); 45 46 /* Relocation tables. */ 47 static reloc_howto_type mt_elf_howto_table [] = 48 { 49 /* This reloc does nothing. */ 50 HOWTO (R_MT_NONE, /* type */ 51 0, /* rightshift */ 52 2, /* size (0 = byte, 1 = short, 2 = long) */ 53 32, /* bitsize */ 54 FALSE, /* pc_relative */ 55 0, /* bitpos */ 56 complain_overflow_dont, /* complain_on_overflow */ 57 bfd_elf_generic_reloc, /* special_function */ 58 "R_MT_NONE", /* name */ 59 FALSE, /* partial_inplace */ 60 0 , /* src_mask */ 61 0, /* dst_mask */ 62 FALSE), /* pcrel_offset */ 63 64 /* A 16 bit absolute relocation. */ 65 HOWTO (R_MT_16, /* type */ 66 0, /* rightshift */ 67 2, /* size (0 = byte, 1 = short, 2 = long) */ 68 16, /* bitsize */ 69 FALSE, /* pc_relative */ 70 0, /* bitpos */ 71 complain_overflow_dont, /* complain_on_overflow */ 72 bfd_elf_generic_reloc, /* special_function */ 73 "R_MT_16", /* name */ 74 FALSE, /* partial_inplace */ 75 0 , /* src_mask */ 76 0xffff, /* dst_mask */ 77 FALSE), /* pcrel_offset */ 78 79 /* A 32 bit absolute relocation. */ 80 HOWTO (R_MT_32, /* type */ 81 0, /* rightshift */ 82 2, /* size (0 = byte, 1 = short, 2 = long) */ 83 32, /* bitsize */ 84 FALSE, /* pc_relative */ 85 0, /* bitpos */ 86 complain_overflow_dont, /* complain_on_overflow */ 87 bfd_elf_generic_reloc, /* special_function */ 88 "R_MT_32", /* name */ 89 FALSE, /* partial_inplace */ 90 0 , /* src_mask */ 91 0xffffffff, /* dst_mask */ 92 FALSE), /* pcrel_offset */ 93 94 /* A 32 bit pc-relative relocation. */ 95 HOWTO (R_MT_32_PCREL, /* type */ 96 0, /* rightshift */ 97 2, /* size (0 = byte, 1 = short, 2 = long) */ 98 32, /* bitsize */ 99 TRUE, /* pc_relative */ 100 0, /* bitpos */ 101 complain_overflow_dont, /* complain_on_overflow */ 102 bfd_elf_generic_reloc, /* special_function */ 103 "R_MT_32_PCREL", /* name */ 104 FALSE, /* partial_inplace */ 105 0 , /* src_mask */ 106 0xffffffff, /* dst_mask */ 107 TRUE), /* pcrel_offset */ 108 109 /* A 16 bit pc-relative relocation. */ 110 HOWTO (R_MT_PC16, /* type */ 111 0, /* rightshift */ 112 2, /* size (0 = byte, 1 = short, 2 = long) */ 113 16, /* bitsize */ 114 TRUE, /* pc_relative */ 115 0, /* bitpos */ 116 complain_overflow_signed, /* complain_on_overflow */ 117 bfd_elf_generic_reloc, /* special_function */ 118 "R_MT_PC16", /* name */ 119 FALSE, /* partial_inplace */ 120 0, /* src_mask */ 121 0xffff, /* dst_mask */ 122 TRUE), /* pcrel_offset */ 123 124 /* high 16 bits of symbol value. */ 125 HOWTO (R_MT_HI16, /* type */ 126 0, /* rightshift */ 127 2, /* size (0 = byte, 1 = short, 2 = long) */ 128 16, /* bitsize */ 129 FALSE, /* pc_relative */ 130 0, /* bitpos */ 131 complain_overflow_dont, /* complain_on_overflow */ 132 bfd_elf_generic_reloc, /* special_function */ 133 "R_MT_HI16", /* name */ 134 FALSE, /* partial_inplace */ 135 0xffff0000, /* src_mask */ 136 0xffff0000, /* dst_mask */ 137 FALSE), /* pcrel_offset */ 138 139 /* Low 16 bits of symbol value. */ 140 HOWTO (R_MT_LO16, /* type */ 141 0, /* rightshift */ 142 2, /* size (0 = byte, 1 = short, 2 = long) */ 143 16, /* bitsize */ 144 FALSE, /* pc_relative */ 145 0, /* bitpos */ 146 complain_overflow_dont, /* complain_on_overflow */ 147 bfd_elf_generic_reloc, /* special_function */ 148 "R_MT_LO16", /* name */ 149 FALSE, /* partial_inplace */ 150 0xffff, /* src_mask */ 151 0xffff, /* dst_mask */ 152 FALSE), /* pcrel_offset */ 153 }; 154 155 /* Map BFD reloc types to MT ELF reloc types. */ 156 157 static reloc_howto_type * 158 mt_reloc_type_lookup 159 (bfd * abfd ATTRIBUTE_UNUSED, 160 bfd_reloc_code_real_type code) 161 { 162 /* Note that the mt_elf_howto_table is indxed by the R_ 163 constants. Thus, the order that the howto records appear in the 164 table *must* match the order of the relocation types defined in 165 include/elf/mt.h. */ 166 167 switch (code) 168 { 169 case BFD_RELOC_NONE: 170 return &mt_elf_howto_table[ (int) R_MT_NONE]; 171 case BFD_RELOC_16: 172 return &mt_elf_howto_table[ (int) R_MT_16]; 173 case BFD_RELOC_32: 174 return &mt_elf_howto_table[ (int) R_MT_32]; 175 case BFD_RELOC_32_PCREL: 176 return &mt_elf_howto_table[ (int) R_MT_32_PCREL]; 177 case BFD_RELOC_16_PCREL: 178 return &mt_elf_howto_table[ (int) R_MT_PC16]; 179 case BFD_RELOC_HI16: 180 return &mt_elf_howto_table[ (int) R_MT_HI16]; 181 case BFD_RELOC_LO16: 182 return &mt_elf_howto_table[ (int) R_MT_LO16]; 183 184 default: 185 /* Pacify gcc -Wall. */ 186 return NULL; 187 } 188 return NULL; 189 } 190 191 static reloc_howto_type * 192 mt_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 193 const char *r_name) 194 { 195 unsigned int i; 196 197 for (i = 0; 198 i < sizeof (mt_elf_howto_table) / sizeof (mt_elf_howto_table[0]); 199 i++) 200 if (mt_elf_howto_table[i].name != NULL 201 && strcasecmp (mt_elf_howto_table[i].name, r_name) == 0) 202 return &mt_elf_howto_table[i]; 203 204 return NULL; 205 } 206 207 bfd_reloc_status_type 208 mt_elf_relocate_hi16 209 (bfd * input_bfd, 210 Elf_Internal_Rela * relhi, 211 bfd_byte * contents, 212 bfd_vma value) 213 { 214 bfd_vma insn; 215 216 insn = bfd_get_32 (input_bfd, contents + relhi->r_offset); 217 218 value += relhi->r_addend; 219 value >>= 16; 220 insn = ((insn & ~0xFFFF) | value); 221 222 bfd_put_32 (input_bfd, insn, contents + relhi->r_offset); 223 return bfd_reloc_ok; 224 } 225 226 /* 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; 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); 353 354 name = h->root.root.string; 355 } 356 357 if (sec != NULL && elf_discarded_section (sec)) 358 { 359 /* For relocs against symbols from removed linkonce sections, 360 or sections discarded by a linker script, we just want the 361 section contents zeroed. Avoid any special processing. */ 362 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); 363 rel->r_info = 0; 364 rel->r_addend = 0; 365 continue; 366 } 367 368 if (info->relocatable) 369 continue; 370 371 /* Finally, the sole MT-specific part. */ 372 switch (r_type) 373 { 374 case R_MT_HI16: 375 r = mt_elf_relocate_hi16 (input_bfd, rel, contents, relocation); 376 break; 377 default: 378 r = mt_final_link_relocate (howto, input_bfd, input_section, 379 contents, rel, relocation); 380 break; 381 } 382 383 384 if (r != bfd_reloc_ok) 385 { 386 const char * msg = (const char *) NULL; 387 388 switch (r) 389 { 390 case bfd_reloc_overflow: 391 r = info->callbacks->reloc_overflow 392 (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0, 393 input_bfd, input_section, rel->r_offset); 394 break; 395 396 case bfd_reloc_undefined: 397 r = info->callbacks->undefined_symbol 398 (info, name, input_bfd, input_section, rel->r_offset, TRUE); 399 break; 400 401 case bfd_reloc_outofrange: 402 msg = _("internal error: out of range error"); 403 break; 404 405 case bfd_reloc_dangerous: 406 msg = _("internal error: dangerous relocation"); 407 break; 408 409 default: 410 msg = _("internal error: unknown error"); 411 break; 412 } 413 414 if (msg) 415 r = info->callbacks->warning 416 (info, msg, name, input_bfd, input_section, rel->r_offset); 417 418 if (! r) 419 return FALSE; 420 } 421 } 422 423 return TRUE; 424 } 425 426 /* Look through the relocs for a section during the first phase. 427 Since we don't do .gots or .plts, we just need to consider the 428 virtual table relocs for gc. */ 429 430 static bfd_boolean 431 mt_elf_check_relocs 432 (bfd * abfd, 433 struct bfd_link_info * info, 434 asection * sec, 435 const Elf_Internal_Rela * relocs) 436 { 437 Elf_Internal_Shdr * symtab_hdr; 438 struct elf_link_hash_entry ** sym_hashes; 439 const Elf_Internal_Rela * rel; 440 const Elf_Internal_Rela * rel_end; 441 442 if (info->relocatable) 443 return TRUE; 444 445 symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 446 sym_hashes = elf_sym_hashes (abfd); 447 448 rel_end = relocs + sec->reloc_count; 449 for (rel = relocs; rel < rel_end; rel++) 450 { 451 struct elf_link_hash_entry *h; 452 unsigned long r_symndx; 453 454 r_symndx = ELF32_R_SYM (rel->r_info); 455 if (r_symndx < symtab_hdr->sh_info) 456 h = NULL; 457 else 458 { 459 h = sym_hashes[r_symndx - symtab_hdr->sh_info]; 460 while (h->root.type == bfd_link_hash_indirect 461 || h->root.type == bfd_link_hash_warning) 462 h = (struct elf_link_hash_entry *) h->root.u.i.link; 463 } 464 } 465 466 return TRUE; 467 } 468 469 /* Return the MACH for an e_flags value. */ 470 471 static int 472 elf32_mt_machine (bfd *abfd) 473 { 474 switch (elf_elfheader (abfd)->e_flags & EF_MT_CPU_MASK) 475 { 476 case EF_MT_CPU_MRISC: return bfd_mach_ms1; 477 case EF_MT_CPU_MRISC2: return bfd_mach_mrisc2; 478 case EF_MT_CPU_MS2: return bfd_mach_ms2; 479 } 480 481 return bfd_mach_ms1; 482 } 483 484 static bfd_boolean 485 mt_elf_object_p (bfd * abfd) 486 { 487 bfd_default_set_arch_mach (abfd, bfd_arch_mt, elf32_mt_machine (abfd)); 488 489 return TRUE; 490 } 491 492 /* Function to set the ELF flag bits. */ 493 494 static bfd_boolean 495 mt_elf_set_private_flags (bfd * abfd, 496 flagword flags) 497 { 498 elf_elfheader (abfd)->e_flags = flags; 499 elf_flags_init (abfd) = TRUE; 500 return TRUE; 501 } 502 503 static bfd_boolean 504 mt_elf_copy_private_bfd_data (bfd * ibfd, bfd * obfd) 505 { 506 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour 507 || bfd_get_flavour (obfd) != bfd_target_elf_flavour) 508 return TRUE; 509 510 BFD_ASSERT (!elf_flags_init (obfd) 511 || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags); 512 513 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; 514 elf_flags_init (obfd) = TRUE; 515 516 /* Copy object attributes. */ 517 _bfd_elf_copy_obj_attributes (ibfd, obfd); 518 519 return TRUE; 520 } 521 522 /* Merge backend specific data from an object file to the output 523 object file when linking. */ 524 525 static bfd_boolean 526 mt_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd) 527 { 528 flagword old_flags, new_flags; 529 bfd_boolean ok = TRUE; 530 531 /* Check if we have the same endianess. */ 532 if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE) 533 return FALSE; 534 535 /* If they're not both mt, then merging is meaningless, so just 536 don't do it. */ 537 if (strcmp (ibfd->arch_info->arch_name, "mt") != 0) 538 return TRUE; 539 if (strcmp (obfd->arch_info->arch_name, "mt") != 0) 540 return TRUE; 541 542 new_flags = elf_elfheader (ibfd)->e_flags; 543 old_flags = elf_elfheader (obfd)->e_flags; 544 545 #ifdef DEBUG 546 _bfd_error_handler ("%B: old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s", 547 ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no"); 548 #endif 549 550 if (!elf_flags_init (obfd)) 551 { 552 old_flags = new_flags; 553 elf_flags_init (obfd) = TRUE; 554 } 555 else if ((new_flags & EF_MT_CPU_MASK) != (old_flags & EF_MT_CPU_MASK)) 556 { 557 /* CPU has changed. This is invalid, because MRISC, MRISC2 and 558 MS2 are not subsets of each other. */ 559 ok = FALSE; 560 } 561 562 if (ok) 563 { 564 obfd->arch_info = ibfd->arch_info; 565 elf_elfheader (obfd)->e_flags = old_flags; 566 } 567 568 return ok; 569 } 570 571 static bfd_boolean 572 mt_elf_print_private_bfd_data (bfd * abfd, void * ptr) 573 { 574 FILE * file = (FILE *) ptr; 575 flagword flags; 576 577 BFD_ASSERT (abfd != NULL && ptr != NULL); 578 579 /* Print normal ELF private data. */ 580 _bfd_elf_print_private_bfd_data (abfd, ptr); 581 582 flags = elf_elfheader (abfd)->e_flags; 583 fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags); 584 585 switch (flags & EF_MT_CPU_MASK) 586 { 587 default: 588 case EF_MT_CPU_MRISC: fprintf (file, " ms1-16-002"); break; 589 case EF_MT_CPU_MRISC2: fprintf (file, " ms1-16-003"); break; 590 case EF_MT_CPU_MS2: fprintf (file, " ms2"); break; 591 } 592 593 fputc ('\n', file); 594 595 return TRUE; 596 } 597 598 599 #define TARGET_BIG_SYM bfd_elf32_mt_vec 600 #define TARGET_BIG_NAME "elf32-mt" 601 602 #define ELF_ARCH bfd_arch_mt 603 #define ELF_MACHINE_CODE EM_MT 604 #define ELF_MAXPAGESIZE 1 /* No pages on the MT. */ 605 606 #define elf_info_to_howto_rel NULL 607 #define elf_info_to_howto mt_info_to_howto_rela 608 609 #define elf_backend_relocate_section mt_elf_relocate_section 610 611 #define bfd_elf32_bfd_reloc_type_lookup mt_reloc_type_lookup 612 #define bfd_elf32_bfd_reloc_name_lookup mt_reloc_name_lookup 613 614 #define elf_backend_check_relocs mt_elf_check_relocs 615 #define elf_backend_object_p mt_elf_object_p 616 #define elf_backend_rela_normal 1 617 618 #define elf_backend_can_gc_sections 1 619 620 #define bfd_elf32_bfd_set_private_flags mt_elf_set_private_flags 621 #define bfd_elf32_bfd_copy_private_bfd_data mt_elf_copy_private_bfd_data 622 #define bfd_elf32_bfd_merge_private_bfd_data mt_elf_merge_private_bfd_data 623 #define bfd_elf32_bfd_print_private_bfd_data mt_elf_print_private_bfd_data 624 625 #include "elf32-target.h" 626