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