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