elf32-mep.c revision 214634
1/* MeP-specific support for 32-bit ELF. 2 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 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 2 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 20 21#include "sysdep.h" 22#include "bfd.h" 23#include "libbfd.h" 24#include "elf-bfd.h" 25#include "elf/mep.h" 26#include "libiberty.h" 27 28/* Forward declarations. */ 29 30/* Private relocation functions. */ 31 32#define MEPREL(type, size, bits, right, left, pcrel, overflow, mask) \ 33 {(unsigned)type, right, size, bits, pcrel, left, overflow, mep_reloc, #type, FALSE, 0, mask, 0 } 34 35#define N complain_overflow_dont 36#define S complain_overflow_signed 37#define U complain_overflow_unsigned 38 39static bfd_reloc_status_type mep_reloc (bfd *, arelent *, struct bfd_symbol *, 40 void *, asection *, bfd *, char **); 41 42static reloc_howto_type mep_elf_howto_table [] = 43{ 44 /* type, size, bits, leftshift, rightshift, pcrel, OD/OS/OU, mask. */ 45 MEPREL (R_MEP_NONE, 0, 0, 0, 0, 0, N, 0), 46 MEPREL (R_RELC, 0, 0, 0, 0, 0, N, 0), 47 /* MEPRELOC:HOWTO */ 48 /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h. */ 49 MEPREL (R_MEP_8, 0, 8, 0, 0, 0, U, 0xff), 50 MEPREL (R_MEP_16, 1, 16, 0, 0, 0, U, 0xffff), 51 MEPREL (R_MEP_32, 2, 32, 0, 0, 0, U, 0xffffffff), 52 MEPREL (R_MEP_PCREL8A2, 1, 8, 1, 1, 1, S, 0x00fe), 53 MEPREL (R_MEP_PCREL12A2,1, 12, 1, 1, 1, S, 0x0ffe), 54 MEPREL (R_MEP_PCREL17A2,2, 17, 0, 1, 1, S, 0x0000ffff), 55 MEPREL (R_MEP_PCREL24A2,2, 24, 0, 1, 1, S, 0x07f0ffff), 56 MEPREL (R_MEP_PCABS24A2,2, 24, 0, 1, 0, U, 0x07f0ffff), 57 MEPREL (R_MEP_LOW16, 2, 16, 0, 0, 0, N, 0x0000ffff), 58 MEPREL (R_MEP_HI16U, 2, 32, 0,16, 0, N, 0x0000ffff), 59 MEPREL (R_MEP_HI16S, 2, 32, 0,16, 0, N, 0x0000ffff), 60 MEPREL (R_MEP_GPREL, 2, 16, 0, 0, 0, S, 0x0000ffff), 61 MEPREL (R_MEP_TPREL, 2, 16, 0, 0, 0, S, 0x0000ffff), 62 MEPREL (R_MEP_TPREL7, 1, 7, 0, 0, 0, U, 0x007f), 63 MEPREL (R_MEP_TPREL7A2, 1, 7, 1, 1, 0, U, 0x007e), 64 MEPREL (R_MEP_TPREL7A4, 1, 7, 2, 2, 0, U, 0x007c), 65 MEPREL (R_MEP_UIMM24, 2, 24, 0, 0, 0, U, 0x00ffffff), 66 MEPREL (R_MEP_ADDR24A4, 2, 24, 0, 2, 0, U, 0x00fcffff), 67 MEPREL (R_MEP_GNU_VTINHERIT,1, 0,16,32, 0, N, 0x0000), 68 MEPREL (R_MEP_GNU_VTENTRY,1, 0,16,32, 0, N, 0x0000), 69 /* MEPRELOC:END */ 70}; 71 72#define VALID_MEP_RELOC(N) ((N) >= 0 \ 73 && (N) < ARRAY_SIZE (mep_elf_howto_table) 74 75#undef N 76#undef S 77#undef U 78 79static bfd_reloc_status_type 80mep_reloc 81 (bfd * abfd ATTRIBUTE_UNUSED, 82 arelent * reloc_entry ATTRIBUTE_UNUSED, 83 struct bfd_symbol * symbol ATTRIBUTE_UNUSED, 84 void * data ATTRIBUTE_UNUSED, 85 asection * input_section ATTRIBUTE_UNUSED, 86 bfd * output_bfd ATTRIBUTE_UNUSED, 87 char ** error_message ATTRIBUTE_UNUSED) 88{ 89 return bfd_reloc_ok; 90} 91 92 93 94#define BFD_RELOC_MEP_NONE BFD_RELOC_NONE 95#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) 96#define MAP(n) case BFD_RELOC_MEP_##n: type = R_MEP_##n; break 97#else 98#define MAP(n) case BFD_RELOC_MEP_/**/n: type = R_MEP_/**/n; break 99#endif 100 101static reloc_howto_type * 102mep_reloc_type_lookup 103 (bfd * abfd ATTRIBUTE_UNUSED, 104 bfd_reloc_code_real_type code) 105{ 106 unsigned int type = 0; 107 108 switch (code) 109 { 110 MAP(NONE); 111 case BFD_RELOC_8: 112 type = R_MEP_8; 113 break; 114 case BFD_RELOC_16: 115 type = R_MEP_16; 116 break; 117 case BFD_RELOC_32: 118 type = R_MEP_32; 119 break; 120 case BFD_RELOC_VTABLE_ENTRY: 121 type = R_MEP_GNU_VTENTRY; 122 break; 123 case BFD_RELOC_VTABLE_INHERIT: 124 type = R_MEP_GNU_VTINHERIT; 125 break; 126 case BFD_RELOC_RELC: 127 type = R_RELC; 128 break; 129 130 /* MEPRELOC:MAP */ 131 /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h. */ 132 MAP(8); 133 MAP(16); 134 MAP(32); 135 MAP(PCREL8A2); 136 MAP(PCREL12A2); 137 MAP(PCREL17A2); 138 MAP(PCREL24A2); 139 MAP(PCABS24A2); 140 MAP(LOW16); 141 MAP(HI16U); 142 MAP(HI16S); 143 MAP(GPREL); 144 MAP(TPREL); 145 MAP(TPREL7); 146 MAP(TPREL7A2); 147 MAP(TPREL7A4); 148 MAP(UIMM24); 149 MAP(ADDR24A4); 150 MAP(GNU_VTINHERIT); 151 MAP(GNU_VTENTRY); 152 /* MEPRELOC:END */ 153 154 default: 155 /* Pacify gcc -Wall. */ 156 fprintf (stderr, "mep: no reloc for code %d\n", code); 157 return NULL; 158 } 159 160 if (mep_elf_howto_table[type].type != type) 161 { 162 fprintf (stderr, "MeP: howto %d has type %d\n", type, mep_elf_howto_table[type].type); 163 abort (); 164 } 165 166 return mep_elf_howto_table + type; 167} 168 169#undef MAP 170 171static reloc_howto_type * 172mep_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) 173{ 174 unsigned int i; 175 176 for (i = 0; 177 i < sizeof (mep_elf_howto_table) / sizeof (mep_elf_howto_table[0]); 178 i++) 179 if (mep_elf_howto_table[i].name != NULL 180 && strcasecmp (mep_elf_howto_table[i].name, r_name) == 0) 181 return &mep_elf_howto_table[i]; 182 183 return NULL; 184} 185 186/* Perform a single relocation. */ 187 188static struct bfd_link_info *mep_info; 189static int warn_tp = 0, warn_sda = 0; 190 191static bfd_vma 192mep_lookup_global 193 (char * name, 194 bfd_vma ofs, 195 bfd_vma * cache, 196 int * warn) 197{ 198 struct bfd_link_hash_entry *h; 199 200 if (*cache || *warn) 201 return *cache; 202 203 h = bfd_link_hash_lookup (mep_info->hash, name, FALSE, FALSE, TRUE); 204 if (h == 0 || h->type != bfd_link_hash_defined) 205 { 206 *warn = ofs + 1; 207 return 0; 208 } 209 *cache = (h->u.def.value 210 + h->u.def.section->output_section->vma 211 + h->u.def.section->output_offset); 212 return *cache; 213} 214 215static bfd_vma 216mep_tpoff_base (bfd_vma ofs) 217{ 218 static bfd_vma cache = 0; 219 return mep_lookup_global ("__tpbase", ofs, &cache, &warn_tp); 220} 221 222static bfd_vma 223mep_sdaoff_base (bfd_vma ofs) 224{ 225 static bfd_vma cache = 0; 226 return mep_lookup_global ("__sdabase", ofs, &cache, &warn_sda); 227} 228 229static bfd_reloc_status_type 230mep_final_link_relocate 231 (reloc_howto_type * howto, 232 bfd * input_bfd, 233 asection * input_section, 234 bfd_byte * contents, 235 Elf_Internal_Rela * rel, 236 bfd_vma relocation) 237{ 238 unsigned long u; 239 long s; 240 unsigned char *byte; 241 bfd_vma pc; 242 bfd_reloc_status_type r = bfd_reloc_ok; 243 int e2, e4; 244 245 if (bfd_big_endian (input_bfd)) 246 { 247 e2 = 0; 248 e4 = 0; 249 } 250 else 251 { 252 e2 = 1; 253 e4 = 3; 254 } 255 256 pc = (input_section->output_section->vma 257 + input_section->output_offset 258 + rel->r_offset); 259 260 s = relocation + rel->r_addend; 261 262 byte = (unsigned char *)contents + rel->r_offset; 263 264 if (howto->type == R_MEP_PCREL24A2 265 && s == 0 266 && pc >= 0x800000) 267 { 268 /* This is an unreachable branch to an undefined weak function. 269 Silently ignore it, since the opcode can't do that but should 270 never be executed anyway. */ 271 return bfd_reloc_ok; 272 } 273 274 if (howto->pc_relative) 275 s -= pc; 276 277 u = (unsigned long) s; 278 279 switch (howto->type) 280 { 281 /* MEPRELOC:APPLY */ 282 /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h. */ 283 case R_MEP_8: /* 76543210 */ 284 if (u > 255) r = bfd_reloc_overflow; 285 byte[0] = (u & 0xff); 286 break; 287 case R_MEP_16: /* fedcba9876543210 */ 288 if (u > 65535) r = bfd_reloc_overflow; 289 byte[0^e2] = ((u >> 8) & 0xff); 290 byte[1^e2] = (u & 0xff); 291 break; 292 case R_MEP_32: /* vutsrqponmlkjihgfedcba9876543210 */ 293 byte[0^e4] = ((u >> 24) & 0xff); 294 byte[1^e4] = ((u >> 16) & 0xff); 295 byte[2^e4] = ((u >> 8) & 0xff); 296 byte[3^e4] = (u & 0xff); 297 break; 298 case R_MEP_PCREL8A2: /* --------7654321- */ 299 if (-128 > s || s > 127) r = bfd_reloc_overflow; 300 byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe); 301 break; 302 case R_MEP_PCREL12A2: /* ----ba987654321- */ 303 if (-2048 > s || s > 2047) r = bfd_reloc_overflow; 304 byte[0^e2] = (byte[0^e2] & 0xf0) | ((s >> 8) & 0x0f); 305 byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe); 306 break; 307 case R_MEP_PCREL17A2: /* ----------------gfedcba987654321 */ 308 if (-65536 > s || s > 65535) r = bfd_reloc_overflow; 309 byte[2^e2] = ((s >> 9) & 0xff); 310 byte[3^e2] = ((s >> 1) & 0xff); 311 break; 312 case R_MEP_PCREL24A2: /* -----7654321----nmlkjihgfedcba98 */ 313 if (-8388608 > s || s > 8388607) r = bfd_reloc_overflow; 314 byte[0^e2] = (byte[0^e2] & 0xf8) | ((s >> 5) & 0x07); 315 byte[1^e2] = (byte[1^e2] & 0x0f) | ((s << 3) & 0xf0); 316 byte[2^e2] = ((s >> 16) & 0xff); 317 byte[3^e2] = ((s >> 8) & 0xff); 318 break; 319 case R_MEP_PCABS24A2: /* -----7654321----nmlkjihgfedcba98 */ 320 if (u > 16777215) r = bfd_reloc_overflow; 321 byte[0^e2] = (byte[0^e2] & 0xf8) | ((u >> 5) & 0x07); 322 byte[1^e2] = (byte[1^e2] & 0x0f) | ((u << 3) & 0xf0); 323 byte[2^e2] = ((u >> 16) & 0xff); 324 byte[3^e2] = ((u >> 8) & 0xff); 325 break; 326 case R_MEP_LOW16: /* ----------------fedcba9876543210 */ 327 byte[2^e2] = ((u >> 8) & 0xff); 328 byte[3^e2] = (u & 0xff); 329 break; 330 case R_MEP_HI16U: /* ----------------vutsrqponmlkjihg */ 331 byte[2^e2] = ((u >> 24) & 0xff); 332 byte[3^e2] = ((u >> 16) & 0xff); 333 break; 334 case R_MEP_HI16S: /* ----------------vutsrqponmlkjihg */ 335 byte[2^e2] = ((s >> 24) & 0xff); 336 byte[3^e2] = ((s >> 16) & 0xff); 337 break; 338 case R_MEP_GPREL: /* ----------------fedcba9876543210 */ 339 s -= mep_sdaoff_base(rel->r_offset); 340 if (-32768 > s || s > 32767) r = bfd_reloc_overflow; 341 byte[2^e2] = ((s >> 8) & 0xff); 342 byte[3^e2] = (s & 0xff); 343 break; 344 case R_MEP_TPREL: /* ----------------fedcba9876543210 */ 345 s -= mep_tpoff_base(rel->r_offset); 346 if (-32768 > s || s > 32767) r = bfd_reloc_overflow; 347 byte[2^e2] = ((s >> 8) & 0xff); 348 byte[3^e2] = (s & 0xff); 349 break; 350 case R_MEP_TPREL7: /* ---------6543210 */ 351 u -= mep_tpoff_base(rel->r_offset); 352 if (u > 127) r = bfd_reloc_overflow; 353 byte[1^e2] = (byte[1^e2] & 0x80) | (u & 0x7f); 354 break; 355 case R_MEP_TPREL7A2: /* ---------654321- */ 356 u -= mep_tpoff_base(rel->r_offset); 357 if (u > 127) r = bfd_reloc_overflow; 358 byte[1^e2] = (byte[1^e2] & 0x81) | (u & 0x7e); 359 break; 360 case R_MEP_TPREL7A4: /* ---------65432-- */ 361 u -= mep_tpoff_base(rel->r_offset); 362 if (u > 127) r = bfd_reloc_overflow; 363 byte[1^e2] = (byte[1^e2] & 0x83) | (u & 0x7c); 364 break; 365 case R_MEP_UIMM24: /* --------76543210nmlkjihgfedcba98 */ 366 if (u > 16777215) r = bfd_reloc_overflow; 367 byte[1^e2] = (u & 0xff); 368 byte[2^e2] = ((u >> 16) & 0xff); 369 byte[3^e2] = ((u >> 8) & 0xff); 370 break; 371 case R_MEP_ADDR24A4: /* --------765432--nmlkjihgfedcba98 */ 372 if (u > 16777215) r = bfd_reloc_overflow; 373 byte[1^e2] = (byte[1^e2] & 0x03) | (u & 0xfc); 374 byte[2^e2] = ((u >> 16) & 0xff); 375 byte[3^e2] = ((u >> 8) & 0xff); 376 break; 377 case R_MEP_GNU_VTINHERIT: /* ---------------- */ 378 break; 379 case R_MEP_GNU_VTENTRY: /* ---------------- */ 380 break; 381 /* MEPRELOC:END */ 382 default: 383 abort (); 384 } 385 386 return r; 387} 388 389/* Set the howto pointer for a MEP ELF reloc. */ 390 391static void 392mep_info_to_howto_rela 393 (bfd * abfd ATTRIBUTE_UNUSED, 394 arelent * cache_ptr, 395 Elf_Internal_Rela * dst) 396{ 397 unsigned int r_type; 398 399 r_type = ELF32_R_TYPE (dst->r_info); 400 cache_ptr->howto = & mep_elf_howto_table [r_type]; 401} 402 403/* Look through the relocs for a section during the first phase. 404 Since we don't do .gots or .plts, we just need to consider the 405 virtual table relocs for gc. */ 406 407static bfd_boolean 408mep_elf_check_relocs 409 (bfd * abfd, 410 struct bfd_link_info * info, 411 asection * sec, 412 const Elf_Internal_Rela * relocs) 413{ 414 Elf_Internal_Shdr * symtab_hdr; 415 struct elf_link_hash_entry ** sym_hashes; 416 struct elf_link_hash_entry ** sym_hashes_end; 417 const Elf_Internal_Rela * rel; 418 const Elf_Internal_Rela * rel_end; 419 420 if (info->relocatable) 421 return TRUE; 422 423 symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 424 sym_hashes = elf_sym_hashes (abfd); 425 sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym); 426 if (!elf_bad_symtab (abfd)) 427 sym_hashes_end -= symtab_hdr->sh_info; 428 429 rel_end = relocs + sec->reloc_count; 430 for (rel = relocs; rel < rel_end; rel++) 431 { 432 struct elf_link_hash_entry *h; 433 unsigned long r_symndx; 434 435 r_symndx = ELF32_R_SYM (rel->r_info); 436 if (r_symndx < symtab_hdr->sh_info) 437 h = NULL; 438 else 439 h = sym_hashes[r_symndx - symtab_hdr->sh_info]; 440 } 441 return TRUE; 442} 443 444 445/* Relocate a MEP ELF section. 446 There is some attempt to make this function usable for many architectures, 447 both USE_REL and USE_RELA ['twould be nice if such a critter existed], 448 if only to serve as a learning tool. 449 450 The RELOCATE_SECTION function is called by the new ELF backend linker 451 to handle the relocations for a section. 452 453 The relocs are always passed as Rela structures; if the section 454 actually uses Rel structures, the r_addend field will always be 455 zero. 456 457 This function is responsible for adjusting the section contents as 458 necessary, and (if using Rela relocs and generating a relocatable 459 output file) adjusting the reloc addend as necessary. 460 461 This function does not have to worry about setting the reloc 462 address or the reloc symbol index. 463 464 LOCAL_SYMS is a pointer to the swapped in local symbols. 465 466 LOCAL_SECTIONS is an array giving the section in the input file 467 corresponding to the st_shndx field of each local symbol. 468 469 The global hash table entry for the global symbols can be found 470 via elf_sym_hashes (input_bfd). 471 472 When generating relocatable output, this function must handle 473 STB_LOCAL/STT_SECTION symbols specially. The output symbol is 474 going to be the section symbol corresponding to the output 475 section, which means that the addend must be adjusted 476 accordingly. */ 477 478static bfd_boolean 479mep_elf_relocate_section 480 (bfd * output_bfd ATTRIBUTE_UNUSED, 481 struct bfd_link_info * info, 482 bfd * input_bfd, 483 asection * input_section, 484 bfd_byte * contents, 485 Elf_Internal_Rela * relocs, 486 Elf_Internal_Sym * local_syms, 487 asection ** local_sections) 488{ 489 Elf_Internal_Shdr * symtab_hdr; 490 struct elf_link_hash_entry ** sym_hashes; 491 Elf_Internal_Rela * rel; 492 Elf_Internal_Rela * relend; 493 494 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; 495 sym_hashes = elf_sym_hashes (input_bfd); 496 relend = relocs + input_section->reloc_count; 497 498 mep_info = info; 499 500 for (rel = relocs; rel < relend; rel ++) 501 { 502 reloc_howto_type * howto; 503 unsigned long r_symndx; 504 Elf_Internal_Sym * sym; 505 asection * sec; 506 struct elf_link_hash_entry * h; 507 bfd_vma relocation; 508 bfd_reloc_status_type r; 509 const char * name = NULL; 510 int r_type; 511 512 r_type = ELF32_R_TYPE (rel->r_info); 513 514 r_symndx = ELF32_R_SYM (rel->r_info); 515 516 /* Is this a complex relocation? */ 517 if (!info->relocatable && ELF32_R_TYPE (rel->r_info) == R_RELC) 518 { 519 bfd_elf_perform_complex_relocation (output_bfd, info, 520 input_bfd, input_section, contents, 521 rel, local_syms, local_sections); 522 continue; 523 } 524 525 howto = mep_elf_howto_table + ELF32_R_TYPE (rel->r_info); 526 h = NULL; 527 sym = NULL; 528 sec = NULL; 529 530 if (r_symndx < symtab_hdr->sh_info) 531 { 532 sym = local_syms + r_symndx; 533 sec = local_sections [r_symndx]; 534 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 535 536 name = bfd_elf_string_from_elf_section 537 (input_bfd, symtab_hdr->sh_link, sym->st_name); 538 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name; 539#if 0 540 fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n", 541 sec->name, name, sym->st_name, 542 sec->output_section->vma, sec->output_offset, 543 sym->st_value, rel->r_addend); 544#endif 545 } 546 else 547 { 548 relocation = 0; 549 h = sym_hashes [r_symndx]; 550 551 while (h->root.type == bfd_link_hash_indirect 552 || h->root.type == bfd_link_hash_warning) 553 h = (struct elf_link_hash_entry *) h->root.u.i.link; 554 555 name = h->root.root.string; 556 557 if (h->root.type == bfd_link_hash_defined 558 || h->root.type == bfd_link_hash_defweak) 559 { 560 sec = h->root.u.def.section; 561 relocation = (h->root.u.def.value 562 + sec->output_section->vma 563 + sec->output_offset); 564#if 0 565 fprintf (stderr, 566 "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n", 567 sec->name, name, h->root.u.def.value, 568 sec->output_section->vma, sec->output_offset, relocation); 569#endif 570 } 571 else if (h->root.type == bfd_link_hash_undefweak) 572 { 573#if 0 574 fprintf (stderr, "undefined: sec: %s, name: %s\n", 575 sec->name, name); 576#endif 577 } 578 else if (!info->relocatable) 579 { 580 if (! ((*info->callbacks->undefined_symbol) 581 (info, h->root.root.string, input_bfd, 582 input_section, rel->r_offset, 583 (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR)))) 584 return FALSE; 585#if 0 586 fprintf (stderr, "unknown: name: %s\n", name); 587#endif 588 } 589 } 590 591 if (sec != NULL && elf_discarded_section (sec)) 592 { 593 /* For relocs against symbols from removed linkonce sections, 594 or sections discarded by a linker script, we just want the 595 section contents zeroed. Avoid any special processing. */ 596 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); 597 rel->r_info = 0; 598 rel->r_addend = 0; 599 continue; 600 } 601 602 if (info->relocatable) 603 { 604 /* This is a relocatable link. We don't have to change 605 anything, unless the reloc is against a section symbol, 606 in which case we have to adjust according to where the 607 section symbol winds up in the output section. */ 608 if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION) 609 rel->r_addend += sec->output_offset; 610 continue; 611 } 612 613 switch (r_type) 614 { 615 default: 616 r = mep_final_link_relocate (howto, input_bfd, input_section, 617 contents, rel, relocation); 618 break; 619 } 620 621 if (r != bfd_reloc_ok) 622 { 623 const char * msg = (const char *) NULL; 624 625 switch (r) 626 { 627 case bfd_reloc_overflow: 628 r = info->callbacks->reloc_overflow 629 (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0, 630 input_bfd, input_section, rel->r_offset); 631 break; 632 633 case bfd_reloc_undefined: 634 r = info->callbacks->undefined_symbol 635 (info, name, input_bfd, input_section, rel->r_offset, TRUE); 636 break; 637 638 case bfd_reloc_outofrange: 639 msg = _("internal error: out of range error"); 640 break; 641 642 case bfd_reloc_notsupported: 643 msg = _("internal error: unsupported relocation error"); 644 break; 645 646 case bfd_reloc_dangerous: 647 msg = _("internal error: dangerous relocation"); 648 break; 649 650 default: 651 msg = _("internal error: unknown error"); 652 break; 653 } 654 655 if (msg) 656 r = info->callbacks->warning 657 (info, msg, name, input_bfd, input_section, rel->r_offset); 658 659 if (! r) 660 return FALSE; 661 } 662 } 663 664 if (warn_tp) 665 info->callbacks->undefined_symbol 666 (info, "__tpbase", input_bfd, input_section, warn_tp-1, TRUE); 667 if (warn_sda) 668 info->callbacks->undefined_symbol 669 (info, "__sdabase", input_bfd, input_section, warn_sda-1, TRUE); 670 if (warn_sda || warn_tp) 671 return FALSE; 672 673 return TRUE; 674} 675 676 677/* Update the got entry reference counts for the section being 678 removed. */ 679 680static bfd_boolean 681mep_elf_gc_sweep_hook 682 (bfd * abfd ATTRIBUTE_UNUSED, 683 struct bfd_link_info * info ATTRIBUTE_UNUSED, 684 asection * sec ATTRIBUTE_UNUSED, 685 const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED) 686{ 687 return TRUE; 688} 689 690/* Return the section that should be marked against GC for a given 691 relocation. */ 692 693static asection * 694mep_elf_gc_mark_hook 695 (asection * sec, 696 struct bfd_link_info * info ATTRIBUTE_UNUSED, 697 Elf_Internal_Rela * rel, 698 struct elf_link_hash_entry * h, 699 Elf_Internal_Sym * sym) 700{ 701 if (h != NULL) 702 { 703 switch (ELF32_R_TYPE (rel->r_info)) 704 { 705 default: 706 switch (h->root.type) 707 { 708 case bfd_link_hash_defined: 709 case bfd_link_hash_defweak: 710 return h->root.u.def.section; 711 712 case bfd_link_hash_common: 713 return h->root.u.c.p->section; 714 715 default: 716 break; 717 } 718 } 719 } 720 else 721 { 722 if (!(elf_bad_symtab (sec->owner) 723 && ELF_ST_BIND (sym->st_info) != STB_LOCAL) 724 && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE) 725 && sym->st_shndx != SHN_COMMON)) 726 return bfd_section_from_elf_index (sec->owner, sym->st_shndx); 727 } 728 729 return NULL; 730} 731 732 733/* Function to set the ELF flag bits. */ 734 735static bfd_boolean 736mep_elf_set_private_flags (bfd * abfd, 737 flagword flags) 738{ 739 elf_elfheader (abfd)->e_flags = flags; 740 elf_flags_init (abfd) = TRUE; 741 return TRUE; 742} 743 744static bfd_boolean 745mep_elf_copy_private_bfd_data (bfd * ibfd, bfd * obfd) 746{ 747 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour 748 || bfd_get_flavour (obfd) != bfd_target_elf_flavour) 749 return TRUE; 750 751 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; 752 elf_flags_init (obfd) = TRUE; 753 754 /* Copy object attributes. */ 755 _bfd_elf_copy_obj_attributes (ibfd, obfd); 756 757 return TRUE; 758} 759 760/* Merge backend specific data from an object file to the output 761 object file when linking. */ 762 763static bfd_boolean 764mep_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd) 765{ 766 static bfd *last_ibfd = 0; 767 flagword old_flags, new_flags; 768 flagword old_partial, new_partial; 769 770 /* Check if we have the same endianess. */ 771 if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE) 772 return FALSE; 773 774 new_flags = elf_elfheader (ibfd)->e_flags; 775 old_flags = elf_elfheader (obfd)->e_flags; 776 777#ifdef DEBUG 778 _bfd_error_handler ("%B: old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s", 779 ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no"); 780#endif 781 782 /* First call, no flags set. */ 783 if (!elf_flags_init (obfd)) 784 { 785 elf_flags_init (obfd) = TRUE; 786 old_flags = new_flags; 787 } 788 else if ((new_flags | old_flags) & EF_MEP_LIBRARY) 789 { 790 /* Non-library flags trump library flags. The choice doesn't really 791 matter if both OLD_FLAGS and NEW_FLAGS have EF_MEP_LIBRARY set. */ 792 if (old_flags & EF_MEP_LIBRARY) 793 old_flags = new_flags; 794 } 795 else 796 { 797 /* Make sure they're for the same mach. Allow upgrade from the "mep" 798 mach. */ 799 new_partial = (new_flags & EF_MEP_CPU_MASK); 800 old_partial = (old_flags & EF_MEP_CPU_MASK); 801 if (new_partial == old_partial) 802 ; 803 else if (new_partial == EF_MEP_CPU_MEP) 804 ; 805 else if (old_partial == EF_MEP_CPU_MEP) 806 old_flags = (old_flags & ~EF_MEP_CPU_MASK) | new_partial; 807 else 808 { 809 _bfd_error_handler (_("%B and %B are for different cores"), last_ibfd, ibfd); 810 bfd_set_error (bfd_error_invalid_target); 811 return FALSE; 812 } 813 814 /* Make sure they're for the same me_module. Allow basic config to 815 mix with any other. */ 816 new_partial = (new_flags & EF_MEP_INDEX_MASK); 817 old_partial = (old_flags & EF_MEP_INDEX_MASK); 818 if (new_partial == old_partial) 819 ; 820 else if (new_partial == 0) 821 ; 822 else if (old_partial == 0) 823 old_flags = (old_flags & ~EF_MEP_INDEX_MASK) | new_partial; 824 else 825 { 826 _bfd_error_handler (_("%B and %B are for different configurations"), last_ibfd, ibfd); 827 bfd_set_error (bfd_error_invalid_target); 828 return FALSE; 829 } 830 } 831 832 elf_elfheader (obfd)->e_flags = old_flags; 833 last_ibfd = ibfd; 834 return TRUE; 835} 836 837/* This will be edited by the MeP configration tool. */ 838static const char * config_names[] = 839{ 840 "basic" 841 /* start-mepcfgtool */ 842 ,"simple" 843 ,"fmax" 844 /* end-mepcfgtool */ 845}; 846 847static const char * core_names[] = 848{ 849 "MeP", "MeP-c2", "MeP-c3", "MeP-h1" 850}; 851 852static bfd_boolean 853mep_elf_print_private_bfd_data (bfd * abfd, void * ptr) 854{ 855 FILE * file = (FILE *) ptr; 856 flagword flags, partial_flags; 857 858 BFD_ASSERT (abfd != NULL && ptr != NULL); 859 860 /* Print normal ELF private data. */ 861 _bfd_elf_print_private_bfd_data (abfd, ptr); 862 863 flags = elf_elfheader (abfd)->e_flags; 864 fprintf (file, _("private flags = 0x%lx"), (long)flags); 865 866 partial_flags = (flags & EF_MEP_CPU_MASK) >> 24; 867 if (partial_flags < ARRAY_SIZE (core_names)) 868 fprintf (file, " core: %s", core_names[(long)partial_flags]); 869 870 partial_flags = flags & EF_MEP_INDEX_MASK; 871 if (partial_flags < ARRAY_SIZE (config_names)) 872 fprintf (file, " me_module: %s", config_names[(long)partial_flags]); 873 874 fputc ('\n', file); 875 876 return TRUE; 877} 878 879/* Return the machine subcode from the ELF e_flags header. */ 880 881static int 882elf32_mep_machine (bfd * abfd) 883{ 884 switch (elf_elfheader (abfd)->e_flags & EF_MEP_CPU_MASK) 885 { 886 default: break; 887 case EF_MEP_CPU_C2: return bfd_mach_mep; 888 case EF_MEP_CPU_C3: return bfd_mach_mep; 889 case EF_MEP_CPU_C4: return bfd_mach_mep; 890 case EF_MEP_CPU_H1: return bfd_mach_mep_h1; 891 } 892 893 return bfd_mach_mep; 894} 895 896static bfd_boolean 897mep_elf_object_p (bfd * abfd) 898{ 899 /* Irix 5 and 6 is broken. Object file symbol tables are not always 900 sorted correctly such that local symbols preceed global symbols, 901 and the sh_info field in the symbol table is not always right. */ 902 /* This is needed for the RELC support code. */ 903 elf_bad_symtab (abfd) = TRUE; 904 bfd_default_set_arch_mach (abfd, bfd_arch_mep, elf32_mep_machine (abfd)); 905 return TRUE; 906} 907 908static bfd_boolean 909mep_elf_section_flags (flagword * flags, const Elf_Internal_Shdr * hdr) 910{ 911 if (hdr->sh_flags & SHF_MEP_VLIW) 912 * flags |= SEC_MEP_VLIW; 913 return TRUE; 914} 915 916static bfd_boolean 917mep_elf_fake_sections (bfd * abfd ATTRIBUTE_UNUSED, 918 Elf_Internal_Shdr * hdr, 919 asection * sec) 920{ 921 if (sec->flags & SEC_MEP_VLIW) 922 hdr->sh_flags |= SHF_MEP_VLIW; 923 return TRUE; 924} 925 926 927#define ELF_ARCH bfd_arch_mep 928#define ELF_MACHINE_CODE EM_CYGNUS_MEP 929#define ELF_MAXPAGESIZE 0x1000 930 931#define TARGET_BIG_SYM bfd_elf32_mep_vec 932#define TARGET_BIG_NAME "elf32-mep" 933 934#define TARGET_LITTLE_SYM bfd_elf32_mep_little_vec 935#define TARGET_LITTLE_NAME "elf32-mep-little" 936 937#define elf_info_to_howto_rel NULL 938#define elf_info_to_howto mep_info_to_howto_rela 939#define elf_backend_relocate_section mep_elf_relocate_section 940#define elf_backend_gc_mark_hook mep_elf_gc_mark_hook 941#define elf_backend_gc_sweep_hook mep_elf_gc_sweep_hook 942#define elf_backend_check_relocs mep_elf_check_relocs 943#define elf_backend_object_p mep_elf_object_p 944#define elf_backend_section_flags mep_elf_section_flags 945#define elf_backend_fake_sections mep_elf_fake_sections 946 947#define elf_backend_can_gc_sections 1 948 949#define bfd_elf32_bfd_reloc_type_lookup mep_reloc_type_lookup 950#define bfd_elf32_bfd_reloc_name_lookup mep_reloc_name_lookup 951#define bfd_elf32_bfd_set_private_flags mep_elf_set_private_flags 952#define bfd_elf32_bfd_copy_private_bfd_data mep_elf_copy_private_bfd_data 953#define bfd_elf32_bfd_merge_private_bfd_data mep_elf_merge_private_bfd_data 954#define bfd_elf32_bfd_print_private_bfd_data mep_elf_print_private_bfd_data 955 956/* We use only the RELA entries. */ 957#define USE_RELA 958 959#include "elf32-target.h" 960