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