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