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