00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "bfd.h"
00029 #include "sysdep.h"
00030 #include "bfdlink.h"
00031 #include "libbfd.h"
00032 #include "elf-bfd.h"
00033 #include "elf/mcore.h"
00034 #include <assert.h>
00035
00036
00037
00038 static void mcore_elf_howto_init
00039 PARAMS ((void));
00040 static reloc_howto_type * mcore_elf_reloc_type_lookup
00041 PARAMS ((bfd *, bfd_reloc_code_real_type));
00042 static void mcore_elf_info_to_howto
00043 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
00044 static bfd_boolean mcore_elf_set_private_flags
00045 PARAMS ((bfd *, flagword));
00046 static bfd_boolean mcore_elf_merge_private_bfd_data
00047 PARAMS ((bfd *, bfd *));
00048 static bfd_reloc_status_type mcore_elf_unsupported_reloc
00049 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
00050 static bfd_boolean mcore_elf_relocate_section
00051 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
00052 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
00053 static asection * mcore_elf_gc_mark_hook
00054 PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
00055 struct elf_link_hash_entry *, Elf_Internal_Sym *));
00056 static bfd_boolean mcore_elf_gc_sweep_hook
00057 PARAMS ((bfd *, struct bfd_link_info *, asection *,
00058 const Elf_Internal_Rela *));
00059 static bfd_boolean mcore_elf_check_relocs
00060 PARAMS ((bfd *, struct bfd_link_info *, asection *,
00061 const Elf_Internal_Rela *));
00062
00063 static reloc_howto_type * mcore_elf_howto_table [(int) R_MCORE_max];
00064
00065 static reloc_howto_type mcore_elf_howto_raw[] =
00066 {
00067
00068 HOWTO (R_MCORE_NONE,
00069 0,
00070 2,
00071 32,
00072 FALSE,
00073 0,
00074 complain_overflow_bitfield,
00075 NULL,
00076 "R_MCORE_NONE",
00077 FALSE,
00078 0,
00079 0,
00080 FALSE),
00081
00082
00083 HOWTO (R_MCORE_ADDR32,
00084 0,
00085 2,
00086 32,
00087 FALSE,
00088 0,
00089 complain_overflow_bitfield,
00090 bfd_elf_generic_reloc,
00091 "ADDR32",
00092 FALSE,
00093 0x0,
00094 0xffffffff,
00095 FALSE),
00096
00097
00098
00099 HOWTO (R_MCORE_PCRELIMM8BY4,
00100 2,
00101 1,
00102 8,
00103 TRUE,
00104 0,
00105 complain_overflow_bitfield,
00106 mcore_elf_unsupported_reloc,
00107 "R_MCORE_PCRELIMM8BY4",
00108 FALSE,
00109 0,
00110 0,
00111 TRUE),
00112
00113
00114
00115
00116 HOWTO (R_MCORE_PCRELIMM11BY2,
00117 1,
00118 1,
00119 11,
00120 TRUE,
00121 0,
00122 complain_overflow_signed,
00123 bfd_elf_generic_reloc,
00124 "R_MCORE_PCRELIMM11BY2",
00125 FALSE,
00126 0x0,
00127 0x7ff,
00128 TRUE),
00129
00130
00131 HOWTO (R_MCORE_PCRELIMM4BY2,
00132 1,
00133 1,
00134 4,
00135 TRUE,
00136 0,
00137 complain_overflow_bitfield,
00138 mcore_elf_unsupported_reloc,
00139 "R_MCORE_PCRELIMM4BY2",
00140 FALSE,
00141 0,
00142 0,
00143 TRUE),
00144
00145
00146 HOWTO (R_MCORE_PCREL32,
00147 0,
00148 2,
00149 32,
00150 TRUE,
00151 0,
00152 complain_overflow_bitfield,
00153 bfd_elf_generic_reloc,
00154 "R_MCORE_PCREL32",
00155 FALSE,
00156 0x0,
00157 0xffffffff,
00158 TRUE),
00159
00160
00161
00162
00163
00164
00165
00166
00167 HOWTO (R_MCORE_PCRELJSR_IMM11BY2,
00168 1,
00169 1,
00170 11,
00171 TRUE,
00172 0,
00173 complain_overflow_signed,
00174 bfd_elf_generic_reloc,
00175 "R_MCORE_PCRELJSR_IMM11BY2",
00176 FALSE,
00177 0x0,
00178 0x7ff,
00179 TRUE),
00180
00181
00182 HOWTO (R_MCORE_GNU_VTINHERIT,
00183 0,
00184 2,
00185 0,
00186 FALSE,
00187 0,
00188 complain_overflow_dont,
00189 NULL,
00190 "R_MCORE_GNU_VTINHERIT",
00191 FALSE,
00192 0,
00193 0,
00194 FALSE),
00195
00196
00197 HOWTO (R_MCORE_GNU_VTENTRY,
00198 0,
00199 2,
00200 0,
00201 FALSE,
00202 0,
00203 complain_overflow_dont,
00204 _bfd_elf_rel_vtable_reloc_fn,
00205 "R_MCORE_GNU_VTENTRY",
00206 FALSE,
00207 0,
00208 0,
00209 FALSE),
00210
00211 HOWTO (R_MCORE_RELATIVE,
00212 0,
00213 2,
00214 32,
00215 FALSE,
00216 0,
00217 complain_overflow_signed,
00218 NULL,
00219 "R_MCORE_RELATIVE",
00220 TRUE,
00221 0xffffffff,
00222 0xffffffff,
00223 FALSE)
00224 };
00225
00226 #ifndef NUM_ELEM
00227 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
00228 #endif
00229
00230
00231 static void
00232 mcore_elf_howto_init ()
00233 {
00234 unsigned int i;
00235
00236 for (i = NUM_ELEM (mcore_elf_howto_raw); i--;)
00237 {
00238 unsigned int type;
00239
00240 type = mcore_elf_howto_raw[i].type;
00241
00242 BFD_ASSERT (type < NUM_ELEM (mcore_elf_howto_table));
00243
00244 mcore_elf_howto_table [type] = & mcore_elf_howto_raw [i];
00245 }
00246 }
00247
00248 static reloc_howto_type *
00249 mcore_elf_reloc_type_lookup (abfd, code)
00250 bfd * abfd ATTRIBUTE_UNUSED;
00251 bfd_reloc_code_real_type code;
00252 {
00253 enum elf_mcore_reloc_type mcore_reloc = R_MCORE_NONE;
00254
00255 switch (code)
00256 {
00257 case BFD_RELOC_NONE: mcore_reloc = R_MCORE_NONE; break;
00258 case BFD_RELOC_32: mcore_reloc = R_MCORE_ADDR32; break;
00259 case BFD_RELOC_MCORE_PCREL_IMM8BY4: mcore_reloc = R_MCORE_PCRELIMM8BY4; break;
00260 case BFD_RELOC_MCORE_PCREL_IMM11BY2: mcore_reloc = R_MCORE_PCRELIMM11BY2; break;
00261 case BFD_RELOC_MCORE_PCREL_IMM4BY2: mcore_reloc = R_MCORE_PCRELIMM4BY2; break;
00262 case BFD_RELOC_32_PCREL: mcore_reloc = R_MCORE_PCREL32; break;
00263 case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2: mcore_reloc = R_MCORE_PCRELJSR_IMM11BY2; break;
00264 case BFD_RELOC_VTABLE_INHERIT: mcore_reloc = R_MCORE_GNU_VTINHERIT; break;
00265 case BFD_RELOC_VTABLE_ENTRY: mcore_reloc = R_MCORE_GNU_VTENTRY; break;
00266 case BFD_RELOC_RVA: mcore_reloc = R_MCORE_RELATIVE; break;
00267 default:
00268 return (reloc_howto_type *)NULL;
00269 }
00270
00271 if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])
00272 mcore_elf_howto_init ();
00273
00274 return mcore_elf_howto_table [(int) mcore_reloc];
00275 };
00276
00277
00278 static void
00279 mcore_elf_info_to_howto (abfd, cache_ptr, dst)
00280 bfd * abfd ATTRIBUTE_UNUSED;
00281 arelent * cache_ptr;
00282 Elf_Internal_Rela * dst;
00283 {
00284 if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])
00285 mcore_elf_howto_init ();
00286
00287 BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_MCORE_max);
00288
00289 cache_ptr->howto = mcore_elf_howto_table [ELF32_R_TYPE (dst->r_info)];
00290 }
00291
00292
00293 static bfd_boolean
00294 mcore_elf_set_private_flags (abfd, flags)
00295 bfd * abfd;
00296 flagword flags;
00297 {
00298 BFD_ASSERT (! elf_flags_init (abfd)
00299 || elf_elfheader (abfd)->e_flags == flags);
00300
00301 elf_elfheader (abfd)->e_flags = flags;
00302 elf_flags_init (abfd) = TRUE;
00303 return TRUE;
00304 }
00305
00306
00307
00308 static bfd_boolean
00309 mcore_elf_merge_private_bfd_data (ibfd, obfd)
00310 bfd * ibfd;
00311 bfd * obfd;
00312 {
00313 flagword old_flags;
00314 flagword new_flags;
00315
00316
00317 if (! _bfd_generic_verify_endian_match (ibfd, obfd))
00318 return FALSE;
00319
00320 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
00321 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
00322 return TRUE;
00323
00324 new_flags = elf_elfheader (ibfd)->e_flags;
00325 old_flags = elf_elfheader (obfd)->e_flags;
00326
00327 if (! elf_flags_init (obfd))
00328 {
00329 elf_flags_init (obfd) = TRUE;
00330 elf_elfheader (obfd)->e_flags = new_flags;
00331 }
00332 else if (new_flags == old_flags)
00333 ;
00334 else
00335 {
00336
00337 }
00338
00339 return TRUE;
00340 }
00341
00342
00343
00344 static bfd_reloc_status_type
00345 mcore_elf_unsupported_reloc (abfd, reloc_entry, symbol, data, input_section,
00346 output_bfd, error_message)
00347 bfd * abfd;
00348 arelent * reloc_entry;
00349 asymbol * symbol ATTRIBUTE_UNUSED;
00350 PTR data ATTRIBUTE_UNUSED;
00351 asection * input_section ATTRIBUTE_UNUSED;
00352 bfd * output_bfd ATTRIBUTE_UNUSED;
00353 char ** error_message ATTRIBUTE_UNUSED;
00354 {
00355 BFD_ASSERT (reloc_entry->howto != (reloc_howto_type *)0);
00356
00357 _bfd_error_handler (_("%B: Relocation %s (%d) is not currently supported.\n"),
00358 abfd,
00359 reloc_entry->howto->name,
00360 reloc_entry->howto->type);
00361
00362 return bfd_reloc_notsupported;
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 static bfd_boolean
00395 mcore_elf_relocate_section (output_bfd, info, input_bfd, input_section,
00396 contents, relocs, local_syms, local_sections)
00397 bfd * output_bfd;
00398 struct bfd_link_info * info;
00399 bfd * input_bfd;
00400 asection * input_section;
00401 bfd_byte * contents;
00402 Elf_Internal_Rela * relocs;
00403 Elf_Internal_Sym * local_syms;
00404 asection ** local_sections;
00405 {
00406 Elf_Internal_Shdr * symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
00407 struct elf_link_hash_entry ** sym_hashes = elf_sym_hashes (input_bfd);
00408 Elf_Internal_Rela * rel = relocs;
00409 Elf_Internal_Rela * relend = relocs + input_section->reloc_count;
00410 bfd_boolean ret = TRUE;
00411
00412 #ifdef DEBUG
00413 _bfd_error_handler
00414 ("mcore_elf_relocate_section called for %B section %A, %ld relocations%s",
00415 input_bfd,
00416 input_section,
00417 (long) input_section->reloc_count,
00418 (info->relocatable) ? " (relocatable)" : "");
00419 #endif
00420
00421 if (info->relocatable)
00422 return TRUE;
00423
00424 if (! mcore_elf_howto_table [R_MCORE_PCRELIMM8BY4])
00425 mcore_elf_howto_init ();
00426
00427 for (; rel < relend; rel++)
00428 {
00429 enum elf_mcore_reloc_type r_type = (enum elf_mcore_reloc_type) ELF32_R_TYPE (rel->r_info);
00430 bfd_vma offset = rel->r_offset;
00431 bfd_vma addend = rel->r_addend;
00432 bfd_reloc_status_type r = bfd_reloc_other;
00433 asection * sec = (asection *) 0;
00434 reloc_howto_type * howto;
00435 bfd_vma relocation;
00436 Elf_Internal_Sym * sym = (Elf_Internal_Sym *) 0;
00437 unsigned long r_symndx;
00438 struct elf_link_hash_entry * h = (struct elf_link_hash_entry *) 0;
00439 unsigned short oldinst = 0;
00440
00441
00442 if ((unsigned) r_type >= (unsigned) R_MCORE_max
00443 || ! mcore_elf_howto_table [(int)r_type])
00444 {
00445 _bfd_error_handler (_("%B: Unknown relocation type %d\n"),
00446 input_bfd, (int) r_type);
00447
00448 bfd_set_error (bfd_error_bad_value);
00449 ret = FALSE;
00450 continue;
00451 }
00452
00453 howto = mcore_elf_howto_table [(int) r_type];
00454 r_symndx = ELF32_R_SYM (rel->r_info);
00455
00456
00457 if (howto->special_function == mcore_elf_unsupported_reloc)
00458 {
00459 _bfd_error_handler (_("%B: Relocation %s (%d) is not currently supported.\n"),
00460 input_bfd,
00461 howto->name,
00462 (int)r_type);
00463
00464 bfd_set_error (bfd_error_bad_value);
00465 ret = FALSE;
00466 continue;
00467 }
00468
00469 if (r_symndx < symtab_hdr->sh_info)
00470 {
00471 sym = local_syms + r_symndx;
00472 sec = local_sections [r_symndx];
00473 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
00474 addend = rel->r_addend;
00475 }
00476 else
00477 {
00478 bfd_boolean unresolved_reloc, warned;
00479
00480 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
00481 r_symndx, symtab_hdr, sym_hashes,
00482 h, sec, relocation,
00483 unresolved_reloc, warned);
00484 }
00485
00486 switch (r_type)
00487 {
00488 default:
00489 break;
00490
00491 case R_MCORE_PCRELJSR_IMM11BY2:
00492 oldinst = bfd_get_16 (input_bfd, contents + offset);
00493 #define MCORE_INST_BSR 0xF800
00494 bfd_put_16 (input_bfd, (bfd_vma) MCORE_INST_BSR, contents + offset);
00495 break;
00496 }
00497
00498 #ifdef DEBUG
00499 fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n",
00500 howto->name, r_type, r_symndx, (long) offset, (long) addend);
00501 #endif
00502
00503 r = _bfd_final_link_relocate
00504 (howto, input_bfd, input_section, contents, offset, relocation, addend);
00505
00506 if (r != bfd_reloc_ok && r_type == R_MCORE_PCRELJSR_IMM11BY2)
00507 {
00508
00509 bfd_put_16 (input_bfd, (bfd_vma) oldinst, contents + offset);
00510 r = bfd_reloc_ok;
00511 }
00512
00513 if (r != bfd_reloc_ok)
00514 {
00515 ret = FALSE;
00516
00517 switch (r)
00518 {
00519 default:
00520 break;
00521
00522 case bfd_reloc_overflow:
00523 {
00524 const char * name;
00525
00526 if (h != NULL)
00527 name = NULL;
00528 else
00529 {
00530 name = bfd_elf_string_from_elf_section
00531 (input_bfd, symtab_hdr->sh_link, sym->st_name);
00532
00533 if (name == NULL)
00534 break;
00535
00536 if (* name == '\0')
00537 name = bfd_section_name (input_bfd, sec);
00538 }
00539
00540 (*info->callbacks->reloc_overflow)
00541 (info, (h ? &h->root : NULL), name, howto->name,
00542 (bfd_vma) 0, input_bfd, input_section, offset);
00543 }
00544 break;
00545 }
00546 }
00547 }
00548
00549 #ifdef DEBUG
00550 fprintf (stderr, "\n");
00551 #endif
00552
00553 return ret;
00554 }
00555
00556
00557
00558
00559 static asection *
00560 mcore_elf_gc_mark_hook (sec, info, rel, h, sym)
00561 asection * sec;
00562 struct bfd_link_info * info ATTRIBUTE_UNUSED;
00563 Elf_Internal_Rela * rel;
00564 struct elf_link_hash_entry * h;
00565 Elf_Internal_Sym * sym;
00566 {
00567 if (h != NULL)
00568 {
00569 switch (ELF32_R_TYPE (rel->r_info))
00570 {
00571 case R_MCORE_GNU_VTINHERIT:
00572 case R_MCORE_GNU_VTENTRY:
00573 break;
00574
00575 default:
00576 switch (h->root.type)
00577 {
00578 case bfd_link_hash_defined:
00579 case bfd_link_hash_defweak:
00580 return h->root.u.def.section;
00581
00582 case bfd_link_hash_common:
00583 return h->root.u.c.p->section;
00584
00585 default:
00586 break;
00587 }
00588 }
00589 }
00590 else
00591 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
00592
00593 return NULL;
00594 }
00595
00596
00597
00598 static bfd_boolean
00599 mcore_elf_gc_sweep_hook (abfd, info, sec, relocs)
00600 bfd * abfd ATTRIBUTE_UNUSED;
00601 struct bfd_link_info * info ATTRIBUTE_UNUSED;
00602 asection * sec ATTRIBUTE_UNUSED;
00603 const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED;
00604 {
00605 return TRUE;
00606 }
00607
00608
00609
00610
00611
00612 static bfd_boolean
00613 mcore_elf_check_relocs (abfd, info, sec, relocs)
00614 bfd * abfd;
00615 struct bfd_link_info * info;
00616 asection * sec;
00617 const Elf_Internal_Rela * relocs;
00618 {
00619 Elf_Internal_Shdr * symtab_hdr;
00620 struct elf_link_hash_entry ** sym_hashes;
00621 struct elf_link_hash_entry ** sym_hashes_end;
00622 const Elf_Internal_Rela * rel;
00623 const Elf_Internal_Rela * rel_end;
00624
00625 if (info->relocatable)
00626 return TRUE;
00627
00628 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
00629 sym_hashes = elf_sym_hashes (abfd);
00630 sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
00631 if (!elf_bad_symtab (abfd))
00632 sym_hashes_end -= symtab_hdr->sh_info;
00633
00634 rel_end = relocs + sec->reloc_count;
00635
00636 for (rel = relocs; rel < rel_end; rel++)
00637 {
00638 struct elf_link_hash_entry * h;
00639 unsigned long r_symndx;
00640
00641 r_symndx = ELF32_R_SYM (rel->r_info);
00642
00643 if (r_symndx < symtab_hdr->sh_info)
00644 h = NULL;
00645 else
00646 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
00647
00648 switch (ELF32_R_TYPE (rel->r_info))
00649 {
00650
00651
00652 case R_MCORE_GNU_VTINHERIT:
00653 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
00654 return FALSE;
00655 break;
00656
00657
00658
00659 case R_MCORE_GNU_VTENTRY:
00660 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
00661 return FALSE;
00662 break;
00663 }
00664 }
00665
00666 return TRUE;
00667 }
00668
00669 static struct bfd_elf_special_section const mcore_elf_special_sections[]=
00670 {
00671 { ".ctors", 6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
00672 { ".dtors", 6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
00673 { NULL, 0, 0, 0, 0 }
00674 };
00675
00676 #define TARGET_BIG_SYM bfd_elf32_mcore_big_vec
00677 #define TARGET_BIG_NAME "elf32-mcore-big"
00678 #define TARGET_LITTLE_SYM bfd_elf32_mcore_little_vec
00679 #define TARGET_LITTLE_NAME "elf32-mcore-little"
00680
00681 #define ELF_ARCH bfd_arch_mcore
00682 #define ELF_MACHINE_CODE EM_MCORE
00683 #define ELF_MAXPAGESIZE 0x1000
00684 #define elf_info_to_howto mcore_elf_info_to_howto
00685 #define elf_info_to_howto_rel NULL
00686
00687 #define bfd_elf32_bfd_merge_private_bfd_data mcore_elf_merge_private_bfd_data
00688 #define bfd_elf32_bfd_set_private_flags mcore_elf_set_private_flags
00689 #define bfd_elf32_bfd_reloc_type_lookup mcore_elf_reloc_type_lookup
00690 #define elf_backend_relocate_section mcore_elf_relocate_section
00691 #define elf_backend_gc_mark_hook mcore_elf_gc_mark_hook
00692 #define elf_backend_gc_sweep_hook mcore_elf_gc_sweep_hook
00693 #define elf_backend_check_relocs mcore_elf_check_relocs
00694 #define elf_backend_special_sections mcore_elf_special_sections
00695
00696 #define elf_backend_can_gc_sections 1
00697 #define elf_backend_rela_normal 1
00698
00699 #include "elf32-target.h"