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