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 #include "bfd.h"
00026 #include "sysdep.h"
00027 #include "libbfd.h"
00028 #include "elf-bfd.h"
00029
00030 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
00031 PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
00032 static void mn10200_info_to_howto
00033 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
00034 static bfd_boolean mn10200_elf_relax_delete_bytes
00035 PARAMS ((bfd *, asection *, bfd_vma, int));
00036 static bfd_boolean mn10200_elf_symbol_address_p
00037 PARAMS ((bfd *, asection *, Elf_Internal_Sym *, bfd_vma));
00038 static bfd_reloc_status_type mn10200_elf_final_link_relocate
00039 PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *,
00040 bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
00041 struct bfd_link_info *, asection *, int));
00042 static bfd_boolean mn10200_elf_relocate_section
00043 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *,
00044 bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *,
00045 asection **));
00046 static bfd_boolean mn10200_elf_relax_section
00047 PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
00048 static bfd_byte * mn10200_elf_get_relocated_section_contents
00049 PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
00050 bfd_byte *, bfd_boolean, asymbol **));
00051
00052 enum reloc_type {
00053 R_MN10200_NONE = 0,
00054 R_MN10200_32,
00055 R_MN10200_16,
00056 R_MN10200_8,
00057 R_MN10200_24,
00058 R_MN10200_PCREL8,
00059 R_MN10200_PCREL16,
00060 R_MN10200_PCREL24,
00061 R_MN10200_MAX
00062 };
00063
00064 static reloc_howto_type elf_mn10200_howto_table[] = {
00065
00066 HOWTO (R_MN10200_NONE,
00067 0,
00068 2,
00069 16,
00070 FALSE,
00071 0,
00072 complain_overflow_bitfield,
00073 bfd_elf_generic_reloc,
00074 "R_MN10200_NONE",
00075 FALSE,
00076 0,
00077 0,
00078 FALSE),
00079
00080 HOWTO (R_MN10200_32,
00081 0,
00082 2,
00083 32,
00084 FALSE,
00085 0,
00086 complain_overflow_bitfield,
00087 bfd_elf_generic_reloc,
00088 "R_MN10200_32",
00089 FALSE,
00090 0xffffffff,
00091 0xffffffff,
00092 FALSE),
00093
00094 HOWTO (R_MN10200_16,
00095 0,
00096 1,
00097 16,
00098 FALSE,
00099 0,
00100 complain_overflow_bitfield,
00101 bfd_elf_generic_reloc,
00102 "R_MN10200_16",
00103 FALSE,
00104 0xffff,
00105 0xffff,
00106 FALSE),
00107
00108 HOWTO (R_MN10200_8,
00109 0,
00110 0,
00111 8,
00112 FALSE,
00113 0,
00114 complain_overflow_bitfield,
00115 bfd_elf_generic_reloc,
00116 "R_MN10200_8",
00117 FALSE,
00118 0xff,
00119 0xff,
00120 FALSE),
00121
00122 HOWTO (R_MN10200_24,
00123 0,
00124 2,
00125 24,
00126 FALSE,
00127 0,
00128 complain_overflow_bitfield,
00129 bfd_elf_generic_reloc,
00130 "R_MN10200_24",
00131 FALSE,
00132 0xffffff,
00133 0xffffff,
00134 FALSE),
00135
00136 HOWTO (R_MN10200_PCREL8,
00137 0,
00138 0,
00139 8,
00140 TRUE,
00141 0,
00142 complain_overflow_bitfield,
00143 bfd_elf_generic_reloc,
00144 "R_MN10200_PCREL8",
00145 FALSE,
00146 0xff,
00147 0xff,
00148 TRUE),
00149
00150 HOWTO (R_MN10200_PCREL16,
00151 0,
00152 1,
00153 16,
00154 TRUE,
00155 0,
00156 complain_overflow_bitfield,
00157 bfd_elf_generic_reloc,
00158 "R_MN10200_PCREL16",
00159 FALSE,
00160 0xffff,
00161 0xffff,
00162 TRUE),
00163
00164
00165 HOWTO (R_MN10200_PCREL24,
00166 0,
00167 2,
00168 24,
00169 TRUE,
00170 0,
00171 complain_overflow_bitfield,
00172 bfd_elf_generic_reloc,
00173 "R_MN10200_PCREL24",
00174 FALSE,
00175 0xffffff,
00176 0xffffff,
00177 TRUE),
00178 };
00179
00180 struct mn10200_reloc_map {
00181 bfd_reloc_code_real_type bfd_reloc_val;
00182 unsigned char elf_reloc_val;
00183 };
00184
00185 static const struct mn10200_reloc_map mn10200_reloc_map[] = {
00186 { BFD_RELOC_NONE , R_MN10200_NONE , },
00187 { BFD_RELOC_32 , R_MN10200_32 , },
00188 { BFD_RELOC_16 , R_MN10200_16 , },
00189 { BFD_RELOC_8 , R_MN10200_8 , },
00190 { BFD_RELOC_24 , R_MN10200_24 , },
00191 { BFD_RELOC_8_PCREL , R_MN10200_PCREL8 , },
00192 { BFD_RELOC_16_PCREL, R_MN10200_PCREL16, },
00193 { BFD_RELOC_24_PCREL, R_MN10200_PCREL24, },
00194 };
00195
00196 static reloc_howto_type *
00197 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
00198 bfd *abfd ATTRIBUTE_UNUSED;
00199 bfd_reloc_code_real_type code;
00200 {
00201 unsigned int i;
00202
00203 for (i = 0;
00204 i < sizeof (mn10200_reloc_map) / sizeof (struct mn10200_reloc_map);
00205 i++)
00206 {
00207 if (mn10200_reloc_map[i].bfd_reloc_val == code)
00208 return &elf_mn10200_howto_table[mn10200_reloc_map[i].elf_reloc_val];
00209 }
00210
00211 return NULL;
00212 }
00213
00214
00215
00216 static void
00217 mn10200_info_to_howto (abfd, cache_ptr, dst)
00218 bfd *abfd ATTRIBUTE_UNUSED;
00219 arelent *cache_ptr;
00220 Elf_Internal_Rela *dst;
00221 {
00222 unsigned int r_type;
00223
00224 r_type = ELF32_R_TYPE (dst->r_info);
00225 BFD_ASSERT (r_type < (unsigned int) R_MN10200_MAX);
00226 cache_ptr->howto = &elf_mn10200_howto_table[r_type];
00227 }
00228
00229
00230
00231 static bfd_reloc_status_type
00232 mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
00233 input_section, contents, offset, value,
00234 addend, info, sym_sec, is_local)
00235 reloc_howto_type *howto;
00236 bfd *input_bfd;
00237 bfd *output_bfd ATTRIBUTE_UNUSED;
00238 asection *input_section;
00239 bfd_byte *contents;
00240 bfd_vma offset;
00241 bfd_vma value;
00242 bfd_vma addend;
00243 struct bfd_link_info *info ATTRIBUTE_UNUSED;
00244 asection *sym_sec ATTRIBUTE_UNUSED;
00245 int is_local ATTRIBUTE_UNUSED;
00246 {
00247 unsigned long r_type = howto->type;
00248 bfd_byte *hit_data = contents + offset;
00249
00250 switch (r_type)
00251 {
00252
00253 case R_MN10200_NONE:
00254 return bfd_reloc_ok;
00255
00256 case R_MN10200_32:
00257 value += addend;
00258 bfd_put_32 (input_bfd, value, hit_data);
00259 return bfd_reloc_ok;
00260
00261 case R_MN10200_16:
00262 value += addend;
00263
00264 if ((long) value > 0x7fff || (long) value < -0x8000)
00265 return bfd_reloc_overflow;
00266
00267 bfd_put_16 (input_bfd, value, hit_data);
00268 return bfd_reloc_ok;
00269
00270 case R_MN10200_8:
00271 value += addend;
00272
00273 if ((long) value > 0x7f || (long) value < -0x80)
00274 return bfd_reloc_overflow;
00275
00276 bfd_put_8 (input_bfd, value, hit_data);
00277 return bfd_reloc_ok;
00278
00279 case R_MN10200_24:
00280 value += addend;
00281
00282 if ((long) value > 0x7fffff || (long) value < -0x800000)
00283 return bfd_reloc_overflow;
00284
00285 value &= 0xffffff;
00286 value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
00287 bfd_put_32 (input_bfd, value, hit_data);
00288 return bfd_reloc_ok;
00289
00290 case R_MN10200_PCREL8:
00291 value -= (input_section->output_section->vma
00292 + input_section->output_offset);
00293 value -= (offset + 1);
00294 value += addend;
00295
00296 if ((long) value > 0xff || (long) value < -0x100)
00297 return bfd_reloc_overflow;
00298
00299 bfd_put_8 (input_bfd, value, hit_data);
00300 return bfd_reloc_ok;
00301
00302 case R_MN10200_PCREL16:
00303 value -= (input_section->output_section->vma
00304 + input_section->output_offset);
00305 value -= (offset + 2);
00306 value += addend;
00307
00308 if ((long) value > 0xffff || (long) value < -0x10000)
00309 return bfd_reloc_overflow;
00310
00311 bfd_put_16 (input_bfd, value, hit_data);
00312 return bfd_reloc_ok;
00313
00314 case R_MN10200_PCREL24:
00315 value -= (input_section->output_section->vma
00316 + input_section->output_offset);
00317 value -= (offset + 3);
00318 value += addend;
00319
00320 if ((long) value > 0xffffff || (long) value < -0x1000000)
00321 return bfd_reloc_overflow;
00322
00323 value &= 0xffffff;
00324 value |= (bfd_get_32 (input_bfd, hit_data) & 0xff000000);
00325 bfd_put_32 (input_bfd, value, hit_data);
00326 return bfd_reloc_ok;
00327
00328 default:
00329 return bfd_reloc_notsupported;
00330 }
00331 }
00332
00333
00334 static bfd_boolean
00335 mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section,
00336 contents, relocs, local_syms, local_sections)
00337 bfd *output_bfd;
00338 struct bfd_link_info *info;
00339 bfd *input_bfd;
00340 asection *input_section;
00341 bfd_byte *contents;
00342 Elf_Internal_Rela *relocs;
00343 Elf_Internal_Sym *local_syms;
00344 asection **local_sections;
00345 {
00346 Elf_Internal_Shdr *symtab_hdr;
00347 struct elf_link_hash_entry **sym_hashes;
00348 Elf_Internal_Rela *rel, *relend;
00349
00350 if (info->relocatable)
00351 return TRUE;
00352
00353 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
00354 sym_hashes = elf_sym_hashes (input_bfd);
00355
00356 rel = relocs;
00357 relend = relocs + input_section->reloc_count;
00358 for (; rel < relend; rel++)
00359 {
00360 int r_type;
00361 reloc_howto_type *howto;
00362 unsigned long r_symndx;
00363 Elf_Internal_Sym *sym;
00364 asection *sec;
00365 struct elf_link_hash_entry *h;
00366 bfd_vma relocation;
00367 bfd_reloc_status_type r;
00368
00369 r_symndx = ELF32_R_SYM (rel->r_info);
00370 r_type = ELF32_R_TYPE (rel->r_info);
00371 howto = elf_mn10200_howto_table + r_type;
00372
00373 h = NULL;
00374 sym = NULL;
00375 sec = NULL;
00376 if (r_symndx < symtab_hdr->sh_info)
00377 {
00378 sym = local_syms + r_symndx;
00379 sec = local_sections[r_symndx];
00380 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
00381 }
00382 else
00383 {
00384 bfd_boolean unresolved_reloc, warned;
00385
00386 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
00387 r_symndx, symtab_hdr, sym_hashes,
00388 h, sec, relocation,
00389 unresolved_reloc, warned);
00390 }
00391
00392 r = mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
00393 input_section,
00394 contents, rel->r_offset,
00395 relocation, rel->r_addend,
00396 info, sec, h == NULL);
00397
00398 if (r != bfd_reloc_ok)
00399 {
00400 const char *name;
00401 const char *msg = (const char *) 0;
00402
00403 if (h != NULL)
00404 name = h->root.root.string;
00405 else
00406 {
00407 name = (bfd_elf_string_from_elf_section
00408 (input_bfd, symtab_hdr->sh_link, sym->st_name));
00409 if (name == NULL || *name == '\0')
00410 name = bfd_section_name (input_bfd, sec);
00411 }
00412
00413 switch (r)
00414 {
00415 case bfd_reloc_overflow:
00416 if (! ((*info->callbacks->reloc_overflow)
00417 (info, (h ? &h->root : NULL), name, howto->name,
00418 (bfd_vma) 0, input_bfd, input_section,
00419 rel->r_offset)))
00420 return FALSE;
00421 break;
00422
00423 case bfd_reloc_undefined:
00424 if (! ((*info->callbacks->undefined_symbol)
00425 (info, name, input_bfd, input_section,
00426 rel->r_offset, TRUE)))
00427 return FALSE;
00428 break;
00429
00430 case bfd_reloc_outofrange:
00431 msg = _("internal error: out of range error");
00432 goto common_error;
00433
00434 case bfd_reloc_notsupported:
00435 msg = _("internal error: unsupported relocation error");
00436 goto common_error;
00437
00438 case bfd_reloc_dangerous:
00439 msg = _("internal error: dangerous error");
00440 goto common_error;
00441
00442 default:
00443 msg = _("internal error: unknown error");
00444
00445
00446 common_error:
00447 if (!((*info->callbacks->warning)
00448 (info, msg, name, input_bfd, input_section,
00449 rel->r_offset)))
00450 return FALSE;
00451 break;
00452 }
00453 }
00454 }
00455
00456 return TRUE;
00457 }
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488 static bfd_boolean
00489 mn10200_elf_relax_section (abfd, sec, link_info, again)
00490 bfd *abfd;
00491 asection *sec;
00492 struct bfd_link_info *link_info;
00493 bfd_boolean *again;
00494 {
00495 Elf_Internal_Shdr *symtab_hdr;
00496 Elf_Internal_Rela *internal_relocs;
00497 Elf_Internal_Rela *irel, *irelend;
00498 bfd_byte *contents = NULL;
00499 Elf_Internal_Sym *isymbuf = NULL;
00500
00501
00502 *again = FALSE;
00503
00504
00505
00506
00507 if (link_info->relocatable
00508 || (sec->flags & SEC_RELOC) == 0
00509 || sec->reloc_count == 0
00510 || (sec->flags & SEC_CODE) == 0)
00511 return TRUE;
00512
00513 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
00514
00515
00516 internal_relocs = (_bfd_elf_link_read_relocs
00517 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
00518 link_info->keep_memory));
00519 if (internal_relocs == NULL)
00520 goto error_return;
00521
00522
00523 irelend = internal_relocs + sec->reloc_count;
00524 for (irel = internal_relocs; irel < irelend; irel++)
00525 {
00526 bfd_vma symval;
00527
00528
00529
00530 if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_NONE
00531 || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_8
00532 || ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_MAX)
00533 continue;
00534
00535
00536 if (contents == NULL)
00537 {
00538
00539 if (elf_section_data (sec)->this_hdr.contents != NULL)
00540 contents = elf_section_data (sec)->this_hdr.contents;
00541 else
00542 {
00543
00544 if (!bfd_malloc_and_get_section (abfd, sec, &contents))
00545 goto error_return;
00546 }
00547 }
00548
00549
00550 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
00551 {
00552 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
00553 if (isymbuf == NULL)
00554 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
00555 symtab_hdr->sh_info, 0,
00556 NULL, NULL, NULL);
00557 if (isymbuf == NULL)
00558 goto error_return;
00559 }
00560
00561
00562 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
00563 {
00564
00565 Elf_Internal_Sym *isym;
00566 asection *sym_sec;
00567
00568 isym = isymbuf + ELF32_R_SYM (irel->r_info);
00569 if (isym->st_shndx == SHN_UNDEF)
00570 sym_sec = bfd_und_section_ptr;
00571 else if (isym->st_shndx == SHN_ABS)
00572 sym_sec = bfd_abs_section_ptr;
00573 else if (isym->st_shndx == SHN_COMMON)
00574 sym_sec = bfd_com_section_ptr;
00575 else
00576 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
00577 symval = (isym->st_value
00578 + sym_sec->output_section->vma
00579 + sym_sec->output_offset);
00580 }
00581 else
00582 {
00583 unsigned long indx;
00584 struct elf_link_hash_entry *h;
00585
00586
00587 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
00588 h = elf_sym_hashes (abfd)[indx];
00589 BFD_ASSERT (h != NULL);
00590 if (h->root.type != bfd_link_hash_defined
00591 && h->root.type != bfd_link_hash_defweak)
00592 {
00593
00594
00595
00596 continue;
00597 }
00598
00599 symval = (h->root.u.def.value
00600 + h->root.u.def.section->output_section->vma
00601 + h->root.u.def.section->output_offset);
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614 if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL24)
00615 {
00616 bfd_vma value = symval;
00617
00618
00619 value -= (sec->output_section->vma + sec->output_offset);
00620 value -= (irel->r_offset + 3);
00621 value += irel->r_addend;
00622
00623
00624
00625
00626 if ((long) value < 0x8001 && (long) value > -0x8000)
00627 {
00628 unsigned char code;
00629
00630
00631 code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
00632
00633 if (code != 0xe0 && code != 0xe1)
00634 continue;
00635
00636
00637 elf_section_data (sec)->relocs = internal_relocs;
00638 elf_section_data (sec)->this_hdr.contents = contents;
00639 symtab_hdr->contents = (unsigned char *) isymbuf;
00640
00641
00642 if (code == 0xe0)
00643 bfd_put_8 (abfd, 0xfc, contents + irel->r_offset - 2);
00644 else if (code == 0xe1)
00645 bfd_put_8 (abfd, 0xfd, contents + irel->r_offset - 2);
00646
00647
00648 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
00649 R_MN10200_PCREL16);
00650
00651
00652 irel->r_offset -= 1;
00653
00654
00655 if (!mn10200_elf_relax_delete_bytes (abfd, sec,
00656 irel->r_offset + 1, 2))
00657 goto error_return;
00658
00659
00660
00661 *again = TRUE;
00662 }
00663 }
00664
00665
00666
00667 if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL16)
00668 {
00669 bfd_vma value = symval;
00670
00671
00672 value -= (sec->output_section->vma + sec->output_offset);
00673 value -= (irel->r_offset + 2);
00674 value += irel->r_addend;
00675
00676
00677
00678
00679 if ((long) value < 0x80 && (long) value > -0x80)
00680 {
00681 unsigned char code;
00682
00683
00684 code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
00685
00686 if (code != 0xfc)
00687 continue;
00688
00689
00690 elf_section_data (sec)->relocs = internal_relocs;
00691 elf_section_data (sec)->this_hdr.contents = contents;
00692 symtab_hdr->contents = (unsigned char *) isymbuf;
00693
00694
00695 bfd_put_8 (abfd, 0xea, contents + irel->r_offset - 1);
00696
00697
00698 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
00699 R_MN10200_PCREL8);
00700
00701
00702 if (!mn10200_elf_relax_delete_bytes (abfd, sec,
00703 irel->r_offset + 1, 1))
00704 goto error_return;
00705
00706
00707
00708 *again = TRUE;
00709 }
00710 }
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723 if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_PCREL8)
00724 {
00725 Elf_Internal_Rela *nrel;
00726 bfd_vma value = symval;
00727 unsigned char code;
00728
00729
00730 value -= (sec->output_section->vma + sec->output_offset);
00731 value -= (irel->r_offset + 1);
00732 value += irel->r_addend;
00733
00734
00735 if (irel->r_offset == sec->size)
00736 continue;
00737
00738
00739
00740
00741 code = bfd_get_8 (abfd, contents + irel->r_offset + 1);
00742 if (code != 0xea)
00743 continue;
00744
00745
00746
00747 nrel = irel + 1;
00748 if (nrel == irelend
00749 || irel->r_offset + 2 != nrel->r_offset
00750 || ELF32_R_TYPE (nrel->r_info) != (int) R_MN10200_PCREL8)
00751 continue;
00752
00753
00754
00755 if (symval != (sec->output_section->vma + sec->output_offset
00756 + irel->r_offset + 3))
00757 continue;
00758
00759
00760
00761
00762
00763
00764
00765
00766 code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
00767 if (code != 0xe0 && code != 0xe1 && code != 0xe2
00768 && code != 0xe3 && code != 0xe4 && code != 0xe5
00769 && code != 0xe6 && code != 0xe7 && code != 0xe8
00770 && code != 0xe9 && code != 0xec && code != 0xed
00771 && code != 0xee && code != 0xef && code != 0xfc
00772 && code != 0xfd && code != 0xfe && code != 0xff)
00773 continue;
00774
00775
00776
00777 if (mn10200_elf_symbol_address_p (abfd, sec, isymbuf,
00778 irel->r_offset + 1))
00779 continue;
00780
00781
00782 elf_section_data (sec)->relocs = internal_relocs;
00783 elf_section_data (sec)->this_hdr.contents = contents;
00784 symtab_hdr->contents = (unsigned char *) isymbuf;
00785
00786
00787 switch (code)
00788 {
00789 case 0xfc:
00790 code = 0xfd;
00791 break;
00792 case 0xfd:
00793 code = 0xfc;
00794 break;
00795 case 0xfe:
00796 code = 0xff;
00797 break;
00798 case 0xff:
00799 code = 0xfe;
00800 break;
00801 case 0xe8:
00802 code = 0xe9;
00803 break;
00804 case 0xe9:
00805 code = 0xe8;
00806 break;
00807 case 0xe0:
00808 code = 0xe2;
00809 break;
00810 case 0xe2:
00811 code = 0xe0;
00812 break;
00813 case 0xe3:
00814 code = 0xe1;
00815 break;
00816 case 0xe1:
00817 code = 0xe3;
00818 break;
00819 case 0xe4:
00820 code = 0xe6;
00821 break;
00822 case 0xe6:
00823 code = 0xe4;
00824 break;
00825 case 0xe7:
00826 code = 0xe5;
00827 break;
00828 case 0xe5:
00829 code = 0xe7;
00830 break;
00831 case 0xec:
00832 code = 0xed;
00833 break;
00834 case 0xed:
00835 code = 0xec;
00836 break;
00837 case 0xee:
00838 code = 0xef;
00839 break;
00840 case 0xef:
00841 code = 0xee;
00842 break;
00843 }
00844 bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
00845
00846
00847
00848 irel->r_info = nrel->r_info;
00849
00850
00851 nrel->r_info = ELF32_R_INFO (ELF32_R_SYM (nrel->r_info),
00852 R_MN10200_NONE);
00853
00854
00855 if (!mn10200_elf_relax_delete_bytes (abfd, sec,
00856 irel->r_offset + 1, 2))
00857 goto error_return;
00858
00859
00860
00861 *again = TRUE;
00862 }
00863
00864
00865
00866 if (ELF32_R_TYPE (irel->r_info) == (int) R_MN10200_24)
00867 {
00868 bfd_vma value = symval;
00869
00870
00871
00872
00873 if ((long) value < 0x7fff && (long) value > -0x8000)
00874 {
00875 unsigned char code;
00876
00877
00878
00879
00880
00881
00882 code = bfd_get_8 (abfd, contents + irel->r_offset - 2);
00883
00884 if (code != 0xf4)
00885 continue;
00886
00887
00888 code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
00889
00890 switch (code & 0xfc)
00891 {
00892
00893 case 0x70:
00894
00895
00896
00897 if (value & 0x8000)
00898 continue;
00899
00900
00901 elf_section_data (sec)->relocs = internal_relocs;
00902 elf_section_data (sec)->this_hdr.contents = contents;
00903 symtab_hdr->contents = (unsigned char *) isymbuf;
00904
00905
00906 bfd_put_8 (abfd, 0xf8 + (code & 0x03),
00907 contents + irel->r_offset - 2);
00908
00909
00910 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
00911 R_MN10200_16);
00912
00913
00914
00915 irel->r_offset -= 1;
00916
00917
00918 if (!mn10200_elf_relax_delete_bytes (abfd, sec,
00919 irel->r_offset + 1, 2))
00920 goto error_return;
00921
00922
00923
00924 *again = TRUE;
00925 break;
00926
00927
00928
00929
00930
00931
00932
00933 case 0x74:
00934 case 0x7c:
00935 case 0xc0:
00936 case 0x40:
00937 case 0x44:
00938 case 0xc8:
00939
00940 elf_section_data (sec)->relocs = internal_relocs;
00941 elf_section_data (sec)->this_hdr.contents = contents;
00942 symtab_hdr->contents = (unsigned char *) isymbuf;
00943
00944 if ((code & 0xfc) == 0x74)
00945 code = 0xdc + (code & 0x03);
00946 else if ((code & 0xfc) == 0x7c)
00947 code = 0xec + (code & 0x03);
00948 else if ((code & 0xfc) == 0xc0)
00949 code = 0xc8 + (code & 0x03);
00950 else if ((code & 0xfc) == 0x40)
00951 code = 0xc0 + (code & 0x03);
00952 else if ((code & 0xfc) == 0x44)
00953 code = 0xc4 + (code & 0x03);
00954 else if ((code & 0xfc) == 0xc8)
00955 code = 0xcc + (code & 0x03);
00956
00957
00958 bfd_put_8 (abfd, code, contents + irel->r_offset - 2);
00959
00960
00961 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
00962 R_MN10200_16);
00963
00964
00965
00966 irel->r_offset -= 1;
00967
00968
00969 if (!mn10200_elf_relax_delete_bytes (abfd, sec,
00970 irel->r_offset + 1, 2))
00971 goto error_return;
00972
00973
00974
00975 *again = TRUE;
00976 break;
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986 case 0x78:
00987 case 0xd0:
00988 case 0x50:
00989 case 0x60:
00990 case 0x64:
00991 case 0x68:
00992 case 0x6c:
00993 case 0x80:
00994 case 0xf0:
00995 case 0x00:
00996 case 0x10:
00997 case 0xb0:
00998 case 0x30:
00999 case 0xa0:
01000 case 0x20:
01001 case 0x90:
01002
01003
01004
01005 if (((code & 0xfc) == 0x78
01006 || (code & 0xfc) == 0x60
01007 || (code & 0xfc) == 0x64
01008 || (code & 0xfc) == 0x68
01009 || (code & 0xfc) == 0x6c
01010 || (code & 0xfc) == 0x80
01011 || (code & 0xfc) == 0xf0
01012 || (code & 0xfc) == 0x00
01013 || (code & 0xfc) == 0x10
01014 || (code & 0xfc) == 0xb0
01015 || (code & 0xfc) == 0x30
01016 || (code & 0xfc) == 0xa0
01017 || (code & 0xfc) == 0x20
01018 || (code & 0xfc) == 0x90)
01019 && (value & 0x8000) != 0)
01020 continue;
01021
01022
01023 elf_section_data (sec)->relocs = internal_relocs;
01024 elf_section_data (sec)->this_hdr.contents = contents;
01025 symtab_hdr->contents = (unsigned char *) isymbuf;
01026
01027
01028 bfd_put_8 (abfd, 0xf7, contents + irel->r_offset - 2);
01029
01030 if ((code & 0xfc) == 0x78)
01031 code = 0x48 + (code & 0x03);
01032 else if ((code & 0xfc) == 0xd0)
01033 code = 0x30 + (code & 0x03);
01034 else if ((code & 0xfc) == 0x50)
01035 code = 0x20 + (code & 0x03);
01036 else if ((code & 0xfc) == 0x60)
01037 code = 0x18 + (code & 0x03);
01038 else if ((code & 0xfc) == 0x64)
01039 code = 0x08 + (code & 0x03);
01040 else if ((code & 0xfc) == 0x68)
01041 code = 0x1c + (code & 0x03);
01042 else if ((code & 0xfc) == 0x6c)
01043 code = 0x0c + (code & 0x03);
01044 else if ((code & 0xfc) == 0x80)
01045 code = 0xc0 + (code & 0x07);
01046 else if ((code & 0xfc) == 0xf0)
01047 code = 0xb0 + (code & 0x07);
01048 else if ((code & 0xfc) == 0x00)
01049 code = 0x80 + (code & 0x07);
01050 else if ((code & 0xfc) == 0x10)
01051 code = 0xa0 + (code & 0x07);
01052 else if ((code & 0xfc) == 0xb0)
01053 code = 0x70 + (code & 0x07);
01054 else if ((code & 0xfc) == 0x30)
01055 code = 0x60 + (code & 0x07);
01056 else if ((code & 0xfc) == 0xa0)
01057 code = 0xd0 + (code & 0x07);
01058 else if ((code & 0xfc) == 0x20)
01059 code = 0x90 + (code & 0x07);
01060 else if ((code & 0xfc) == 0x90)
01061 code = 0x50 + (code & 0x07);
01062
01063 bfd_put_8 (abfd, code, contents + irel->r_offset - 1);
01064
01065
01066 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
01067 R_MN10200_16);
01068
01069
01070 if (!mn10200_elf_relax_delete_bytes (abfd, sec,
01071 irel->r_offset + 2, 1))
01072 goto error_return;
01073
01074
01075
01076 *again = TRUE;
01077 break;
01078
01079
01080 case 0xc4:
01081
01082 elf_section_data (sec)->relocs = internal_relocs;
01083 elf_section_data (sec)->this_hdr.contents = contents;
01084 symtab_hdr->contents = (unsigned char *) isymbuf;
01085
01086 bfd_put_8 (abfd, 0xcc + (code & 0x03),
01087 contents + irel->r_offset - 2);
01088
01089 bfd_put_8 (abfd, 0xb8 + (code & 0x03),
01090 contents + irel->r_offset - 1);
01091
01092
01093 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
01094 R_MN10200_16);
01095
01096
01097
01098 irel->r_offset -= 1;
01099
01100
01101 if (!mn10200_elf_relax_delete_bytes (abfd, sec,
01102 irel->r_offset + 2, 1))
01103 goto error_return;
01104
01105
01106
01107 *again = TRUE;
01108 break;
01109 }
01110 }
01111 }
01112 }
01113
01114 if (isymbuf != NULL
01115 && symtab_hdr->contents != (unsigned char *) isymbuf)
01116 {
01117 if (! link_info->keep_memory)
01118 free (isymbuf);
01119 else
01120 {
01121
01122 symtab_hdr->contents = (unsigned char *) isymbuf;
01123 }
01124 }
01125
01126 if (contents != NULL
01127 && elf_section_data (sec)->this_hdr.contents != contents)
01128 {
01129 if (! link_info->keep_memory)
01130 free (contents);
01131 else
01132 {
01133
01134 elf_section_data (sec)->this_hdr.contents = contents;
01135 }
01136 }
01137
01138 if (internal_relocs != NULL
01139 && elf_section_data (sec)->relocs != internal_relocs)
01140 free (internal_relocs);
01141
01142 return TRUE;
01143
01144 error_return:
01145 if (isymbuf != NULL
01146 && symtab_hdr->contents != (unsigned char *) isymbuf)
01147 free (isymbuf);
01148 if (contents != NULL
01149 && elf_section_data (sec)->this_hdr.contents != contents)
01150 free (contents);
01151 if (internal_relocs != NULL
01152 && elf_section_data (sec)->relocs != internal_relocs)
01153 free (internal_relocs);
01154
01155 return FALSE;
01156 }
01157
01158
01159
01160 static bfd_boolean
01161 mn10200_elf_relax_delete_bytes (abfd, sec, addr, count)
01162 bfd *abfd;
01163 asection *sec;
01164 bfd_vma addr;
01165 int count;
01166 {
01167 Elf_Internal_Shdr *symtab_hdr;
01168 unsigned int sec_shndx;
01169 bfd_byte *contents;
01170 Elf_Internal_Rela *irel, *irelend;
01171 Elf_Internal_Rela *irelalign;
01172 bfd_vma toaddr;
01173 Elf_Internal_Sym *isym;
01174 Elf_Internal_Sym *isymend;
01175 struct elf_link_hash_entry **sym_hashes;
01176 struct elf_link_hash_entry **end_hashes;
01177 unsigned int symcount;
01178
01179 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
01180
01181 contents = elf_section_data (sec)->this_hdr.contents;
01182
01183
01184
01185
01186 irelalign = NULL;
01187 toaddr = sec->size;
01188
01189 irel = elf_section_data (sec)->relocs;
01190 irelend = irel + sec->reloc_count;
01191
01192
01193 memmove (contents + addr, contents + addr + count,
01194 (size_t) (toaddr - addr - count));
01195 sec->size -= count;
01196
01197
01198 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
01199 {
01200
01201 if ((irel->r_offset > addr
01202 && irel->r_offset < toaddr))
01203 irel->r_offset -= count;
01204 }
01205
01206
01207 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
01208 isym = (Elf_Internal_Sym *) symtab_hdr->contents;
01209 for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
01210 {
01211 if (isym->st_shndx == sec_shndx
01212 && isym->st_value > addr
01213 && isym->st_value < toaddr)
01214 isym->st_value -= count;
01215 }
01216
01217
01218 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
01219 - symtab_hdr->sh_info);
01220 sym_hashes = elf_sym_hashes (abfd);
01221 end_hashes = sym_hashes + symcount;
01222 for (; sym_hashes < end_hashes; sym_hashes++)
01223 {
01224 struct elf_link_hash_entry *sym_hash = *sym_hashes;
01225 if ((sym_hash->root.type == bfd_link_hash_defined
01226 || sym_hash->root.type == bfd_link_hash_defweak)
01227 && sym_hash->root.u.def.section == sec
01228 && sym_hash->root.u.def.value > addr
01229 && sym_hash->root.u.def.value < toaddr)
01230 {
01231 sym_hash->root.u.def.value -= count;
01232 }
01233 }
01234
01235 return TRUE;
01236 }
01237
01238
01239
01240 static bfd_boolean
01241 mn10200_elf_symbol_address_p (abfd, sec, isym, addr)
01242 bfd *abfd;
01243 asection *sec;
01244 Elf_Internal_Sym *isym;
01245 bfd_vma addr;
01246 {
01247 Elf_Internal_Shdr *symtab_hdr;
01248 unsigned int sec_shndx;
01249 Elf_Internal_Sym *isymend;
01250 struct elf_link_hash_entry **sym_hashes;
01251 struct elf_link_hash_entry **end_hashes;
01252 unsigned int symcount;
01253
01254 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
01255
01256
01257 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
01258 for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
01259 {
01260 if (isym->st_shndx == sec_shndx
01261 && isym->st_value == addr)
01262 return TRUE;
01263 }
01264
01265 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
01266 - symtab_hdr->sh_info);
01267 sym_hashes = elf_sym_hashes (abfd);
01268 end_hashes = sym_hashes + symcount;
01269 for (; sym_hashes < end_hashes; sym_hashes++)
01270 {
01271 struct elf_link_hash_entry *sym_hash = *sym_hashes;
01272 if ((sym_hash->root.type == bfd_link_hash_defined
01273 || sym_hash->root.type == bfd_link_hash_defweak)
01274 && sym_hash->root.u.def.section == sec
01275 && sym_hash->root.u.def.value == addr)
01276 return TRUE;
01277 }
01278
01279 return FALSE;
01280 }
01281
01282
01283
01284
01285 static bfd_byte *
01286 mn10200_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
01287 data, relocatable, symbols)
01288 bfd *output_bfd;
01289 struct bfd_link_info *link_info;
01290 struct bfd_link_order *link_order;
01291 bfd_byte *data;
01292 bfd_boolean relocatable;
01293 asymbol **symbols;
01294 {
01295 Elf_Internal_Shdr *symtab_hdr;
01296 asection *input_section = link_order->u.indirect.section;
01297 bfd *input_bfd = input_section->owner;
01298 asection **sections = NULL;
01299 Elf_Internal_Rela *internal_relocs = NULL;
01300 Elf_Internal_Sym *isymbuf = NULL;
01301
01302
01303
01304 if (relocatable
01305 || elf_section_data (input_section)->this_hdr.contents == NULL)
01306 return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
01307 link_order, data,
01308 relocatable,
01309 symbols);
01310
01311 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
01312
01313 memcpy (data, elf_section_data (input_section)->this_hdr.contents,
01314 (size_t) input_section->size);
01315
01316 if ((input_section->flags & SEC_RELOC) != 0
01317 && input_section->reloc_count > 0)
01318 {
01319 Elf_Internal_Sym *isym;
01320 Elf_Internal_Sym *isymend;
01321 asection **secpp;
01322 bfd_size_type amt;
01323
01324 internal_relocs = (_bfd_elf_link_read_relocs
01325 (input_bfd, input_section, (PTR) NULL,
01326 (Elf_Internal_Rela *) NULL, FALSE));
01327 if (internal_relocs == NULL)
01328 goto error_return;
01329
01330 if (symtab_hdr->sh_info != 0)
01331 {
01332 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
01333 if (isymbuf == NULL)
01334 isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
01335 symtab_hdr->sh_info, 0,
01336 NULL, NULL, NULL);
01337 if (isymbuf == NULL)
01338 goto error_return;
01339 }
01340
01341 amt = symtab_hdr->sh_info;
01342 amt *= sizeof (asection *);
01343 sections = (asection **) bfd_malloc (amt);
01344 if (sections == NULL && amt != 0)
01345 goto error_return;
01346
01347 isymend = isymbuf + symtab_hdr->sh_info;
01348 for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
01349 {
01350 asection *isec;
01351
01352 if (isym->st_shndx == SHN_UNDEF)
01353 isec = bfd_und_section_ptr;
01354 else if (isym->st_shndx == SHN_ABS)
01355 isec = bfd_abs_section_ptr;
01356 else if (isym->st_shndx == SHN_COMMON)
01357 isec = bfd_com_section_ptr;
01358 else
01359 isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
01360
01361 *secpp = isec;
01362 }
01363
01364 if (! mn10200_elf_relocate_section (output_bfd, link_info, input_bfd,
01365 input_section, data, internal_relocs,
01366 isymbuf, sections))
01367 goto error_return;
01368
01369 if (sections != NULL)
01370 free (sections);
01371 if (isymbuf != NULL
01372 && symtab_hdr->contents != (unsigned char *) isymbuf)
01373 free (isymbuf);
01374 if (elf_section_data (input_section)->relocs != internal_relocs)
01375 free (internal_relocs);
01376 }
01377
01378 return data;
01379
01380 error_return:
01381 if (sections != NULL)
01382 free (sections);
01383 if (isymbuf != NULL
01384 && symtab_hdr->contents != (unsigned char *) isymbuf)
01385 free (isymbuf);
01386 if (internal_relocs != NULL
01387 && elf_section_data (input_section)->relocs != internal_relocs)
01388 free (internal_relocs);
01389 return NULL;
01390 }
01391
01392 #define TARGET_LITTLE_SYM bfd_elf32_mn10200_vec
01393 #define TARGET_LITTLE_NAME "elf32-mn10200"
01394 #define ELF_ARCH bfd_arch_mn10200
01395 #define ELF_MACHINE_CODE EM_MN10200
01396 #define ELF_MACHINE_ALT1 EM_CYGNUS_MN10200
01397 #define ELF_MAXPAGESIZE 0x1000
01398
01399 #define elf_backend_rela_normal 1
01400 #define elf_info_to_howto mn10200_info_to_howto
01401 #define elf_info_to_howto_rel 0
01402 #define elf_backend_relocate_section mn10200_elf_relocate_section
01403 #define bfd_elf32_bfd_relax_section mn10200_elf_relax_section
01404 #define bfd_elf32_bfd_get_relocated_section_contents \
01405 mn10200_elf_get_relocated_section_contents
01406
01407 #define elf_symbol_leading_char '_'
01408
01409 #include "elf32-target.h"