00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "bfd.h"
00025 #include "sysdep.h"
00026 #include "libbfd.h"
00027 #include "elf-bfd.h"
00028 #include "elf/frv.h"
00029 #include "elf/dwarf2.h"
00030 #include "hashtab.h"
00031
00032
00033 static bfd_reloc_status_type elf32_frv_relocate_lo16
00034 PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
00035 static bfd_reloc_status_type elf32_frv_relocate_hi16
00036 PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
00037 static bfd_reloc_status_type elf32_frv_relocate_label24
00038 PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
00039 static bfd_reloc_status_type elf32_frv_relocate_gprel12
00040 PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *,
00041 bfd_byte *, bfd_vma));
00042 static bfd_reloc_status_type elf32_frv_relocate_gprelu12
00043 PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *,
00044 bfd_byte *, bfd_vma));
00045 static bfd_reloc_status_type elf32_frv_relocate_gprello
00046 PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *,
00047 bfd_byte *, bfd_vma));
00048 static bfd_reloc_status_type elf32_frv_relocate_gprelhi
00049 PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *,
00050 bfd_byte *, bfd_vma));
00051 static reloc_howto_type *frv_reloc_type_lookup
00052 PARAMS ((bfd *, bfd_reloc_code_real_type));
00053 static void frv_info_to_howto_rela
00054 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
00055 static bfd_boolean elf32_frv_relocate_section
00056 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
00057 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
00058 static bfd_boolean elf32_frv_add_symbol_hook
00059 PARAMS (( bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
00060 const char **, flagword *, asection **, bfd_vma *));
00061 static bfd_reloc_status_type frv_final_link_relocate
00062 PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
00063 Elf_Internal_Rela *, bfd_vma));
00064 static bfd_boolean elf32_frv_gc_sweep_hook
00065 PARAMS ((bfd *, struct bfd_link_info *, asection *, const
00066 Elf_Internal_Rela *));
00067 static asection * elf32_frv_gc_mark_hook
00068 PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
00069 struct elf_link_hash_entry *, Elf_Internal_Sym *));
00070 static bfd_boolean elf32_frv_check_relocs
00071 PARAMS ((bfd *, struct bfd_link_info *, asection *,
00072 const Elf_Internal_Rela *));
00073 static int elf32_frv_machine
00074 PARAMS ((bfd *));
00075 static bfd_boolean elf32_frv_object_p
00076 PARAMS ((bfd *));
00077 static bfd_boolean frv_elf_set_private_flags
00078 PARAMS ((bfd *, flagword));
00079 static bfd_boolean frv_elf_copy_private_bfd_data
00080 PARAMS ((bfd *, bfd *));
00081 static bfd_boolean frv_elf_merge_private_bfd_data
00082 PARAMS ((bfd *, bfd *));
00083 static bfd_boolean frv_elf_print_private_bfd_data
00084 PARAMS ((bfd *, PTR));
00085
00086 static reloc_howto_type elf32_frv_howto_table [] =
00087 {
00088
00089 HOWTO (R_FRV_NONE,
00090 0,
00091 2,
00092 32,
00093 FALSE,
00094 0,
00095 complain_overflow_bitfield,
00096 bfd_elf_generic_reloc,
00097 "R_FRV_NONE",
00098 FALSE,
00099 0,
00100 0,
00101 FALSE),
00102
00103
00104 HOWTO (R_FRV_32,
00105 0,
00106 2,
00107 32,
00108 FALSE,
00109 0,
00110 complain_overflow_bitfield,
00111 bfd_elf_generic_reloc,
00112 "R_FRV_32",
00113 FALSE,
00114 0xffffffff,
00115 0xffffffff,
00116 FALSE),
00117
00118
00119 HOWTO (R_FRV_LABEL16,
00120 2,
00121 2,
00122 16,
00123 TRUE,
00124 0,
00125 complain_overflow_signed,
00126 bfd_elf_generic_reloc,
00127 "R_FRV_LABEL16",
00128 FALSE,
00129 0xffff,
00130 0xffff,
00131 TRUE),
00132
00133
00134 HOWTO (R_FRV_LABEL24,
00135 2,
00136 2,
00137 26,
00138 TRUE,
00139 0,
00140 complain_overflow_bitfield,
00141 bfd_elf_generic_reloc,
00142 "R_FRV_LABEL24",
00143 FALSE,
00144 0x7e03ffff,
00145 0x7e03ffff,
00146 TRUE),
00147
00148 HOWTO (R_FRV_LO16,
00149 0,
00150 2,
00151 16,
00152 FALSE,
00153 0,
00154 complain_overflow_dont,
00155 bfd_elf_generic_reloc,
00156 "R_FRV_LO16",
00157 FALSE,
00158 0xffff,
00159 0xffff,
00160 FALSE),
00161
00162 HOWTO (R_FRV_HI16,
00163 0,
00164 2,
00165 16,
00166 FALSE,
00167 0,
00168 complain_overflow_dont,
00169 bfd_elf_generic_reloc,
00170 "R_FRV_HI16",
00171 FALSE,
00172 0xffff,
00173 0xffff,
00174 FALSE),
00175
00176 HOWTO (R_FRV_GPREL12,
00177 0,
00178 2,
00179 12,
00180 FALSE,
00181 0,
00182 complain_overflow_dont,
00183 bfd_elf_generic_reloc,
00184 "R_FRV_GPREL12",
00185 FALSE,
00186 0xfff,
00187 0xfff,
00188 FALSE),
00189
00190 HOWTO (R_FRV_GPRELU12,
00191 0,
00192 2,
00193 12,
00194 FALSE,
00195 0,
00196 complain_overflow_dont,
00197 bfd_elf_generic_reloc,
00198 "R_FRV_GPRELU12",
00199 FALSE,
00200 0xfff,
00201 0x3f03f,
00202 FALSE),
00203
00204 HOWTO (R_FRV_GPREL32,
00205 0,
00206 2,
00207 32,
00208 FALSE,
00209 0,
00210 complain_overflow_dont,
00211 bfd_elf_generic_reloc,
00212 "R_FRV_GPREL32",
00213 FALSE,
00214 0xffffffff,
00215 0xffffffff,
00216 FALSE),
00217
00218 HOWTO (R_FRV_GPRELHI,
00219 0,
00220 2,
00221 16,
00222 FALSE,
00223 0,
00224 complain_overflow_dont,
00225 bfd_elf_generic_reloc,
00226 "R_FRV_GPRELHI",
00227 FALSE,
00228 0xffff,
00229 0xffff,
00230 FALSE),
00231
00232 HOWTO (R_FRV_GPRELLO,
00233 0,
00234 2,
00235 16,
00236 FALSE,
00237 0,
00238 complain_overflow_dont,
00239 bfd_elf_generic_reloc,
00240 "R_FRV_GPRELLO",
00241 FALSE,
00242 0xffff,
00243 0xffff,
00244 FALSE),
00245
00246
00247
00248 HOWTO (R_FRV_GOT12,
00249 0,
00250 2,
00251 12,
00252 FALSE,
00253 0,
00254 complain_overflow_signed,
00255 bfd_elf_generic_reloc,
00256 "R_FRV_GOT12",
00257 FALSE,
00258 0xfff,
00259 0xfff,
00260 FALSE),
00261
00262
00263
00264 HOWTO (R_FRV_GOTHI,
00265 0,
00266 2,
00267 16,
00268 FALSE,
00269 0,
00270 complain_overflow_dont,
00271 bfd_elf_generic_reloc,
00272 "R_FRV_GOTHI",
00273 FALSE,
00274 0xffff,
00275 0xffff,
00276 FALSE),
00277
00278
00279
00280 HOWTO (R_FRV_GOTLO,
00281 0,
00282 2,
00283 16,
00284 FALSE,
00285 0,
00286 complain_overflow_dont,
00287 bfd_elf_generic_reloc,
00288 "R_FRV_GOTLO",
00289 FALSE,
00290 0xffff,
00291 0xffff,
00292 FALSE),
00293
00294
00295 HOWTO (R_FRV_FUNCDESC,
00296 0,
00297 2,
00298 32,
00299 FALSE,
00300 0,
00301 complain_overflow_bitfield,
00302 bfd_elf_generic_reloc,
00303 "R_FRV_FUNCDESC",
00304 FALSE,
00305 0xffffffff,
00306 0xffffffff,
00307 FALSE),
00308
00309
00310
00311 HOWTO (R_FRV_FUNCDESC_GOT12,
00312 0,
00313 2,
00314 12,
00315 FALSE,
00316 0,
00317 complain_overflow_signed,
00318 bfd_elf_generic_reloc,
00319 "R_FRV_FUNCDESC_GOT12",
00320 FALSE,
00321 0xfff,
00322 0xfff,
00323 FALSE),
00324
00325
00326
00327 HOWTO (R_FRV_FUNCDESC_GOTHI,
00328 0,
00329 2,
00330 16,
00331 FALSE,
00332 0,
00333 complain_overflow_dont,
00334 bfd_elf_generic_reloc,
00335 "R_FRV_FUNCDESC_GOTHI",
00336 FALSE,
00337 0xffff,
00338 0xffff,
00339 FALSE),
00340
00341
00342
00343 HOWTO (R_FRV_FUNCDESC_GOTLO,
00344 0,
00345 2,
00346 16,
00347 FALSE,
00348 0,
00349 complain_overflow_dont,
00350 bfd_elf_generic_reloc,
00351 "R_FRV_FUNCDESC_GOTLO",
00352 FALSE,
00353 0xffff,
00354 0xffff,
00355 FALSE),
00356
00357
00358 HOWTO (R_FRV_FUNCDESC_VALUE,
00359 0,
00360 2,
00361 64,
00362 FALSE,
00363 0,
00364 complain_overflow_bitfield,
00365 bfd_elf_generic_reloc,
00366 "R_FRV_FUNCDESC_VALUE",
00367 FALSE,
00368 0xffffffff,
00369 0xffffffff,
00370 FALSE),
00371
00372
00373
00374 HOWTO (R_FRV_FUNCDESC_GOTOFF12,
00375 0,
00376 2,
00377 12,
00378 FALSE,
00379 0,
00380 complain_overflow_signed,
00381 bfd_elf_generic_reloc,
00382 "R_FRV_FUNCDESC_GOTOFF12",
00383 FALSE,
00384 0xfff,
00385 0xfff,
00386 FALSE),
00387
00388
00389
00390 HOWTO (R_FRV_FUNCDESC_GOTOFFHI,
00391 0,
00392 2,
00393 16,
00394 FALSE,
00395 0,
00396 complain_overflow_dont,
00397 bfd_elf_generic_reloc,
00398 "R_FRV_FUNCDESC_GOTOFFHI",
00399 FALSE,
00400 0xffff,
00401 0xffff,
00402 FALSE),
00403
00404
00405
00406 HOWTO (R_FRV_FUNCDESC_GOTOFFLO,
00407 0,
00408 2,
00409 16,
00410 FALSE,
00411 0,
00412 complain_overflow_dont,
00413 bfd_elf_generic_reloc,
00414 "R_FRV_FUNCDESC_GOTOFFLO",
00415 FALSE,
00416 0xffff,
00417 0xffff,
00418 FALSE),
00419
00420
00421
00422 HOWTO (R_FRV_GOTOFF12,
00423 0,
00424 2,
00425 12,
00426 FALSE,
00427 0,
00428 complain_overflow_signed,
00429 bfd_elf_generic_reloc,
00430 "R_FRV_GOTOFF12",
00431 FALSE,
00432 0xfff,
00433 0xfff,
00434 FALSE),
00435
00436
00437
00438 HOWTO (R_FRV_GOTOFFHI,
00439 0,
00440 2,
00441 16,
00442 FALSE,
00443 0,
00444 complain_overflow_dont,
00445 bfd_elf_generic_reloc,
00446 "R_FRV_GOTOFFHI",
00447 FALSE,
00448 0xffff,
00449 0xffff,
00450 FALSE),
00451
00452
00453
00454 HOWTO (R_FRV_GOTOFFLO,
00455 0,
00456 2,
00457 16,
00458 FALSE,
00459 0,
00460 complain_overflow_dont,
00461 bfd_elf_generic_reloc,
00462 "R_FRV_GOTOFFLO",
00463 FALSE,
00464 0xffff,
00465 0xffff,
00466 FALSE),
00467
00468
00469
00470
00471 HOWTO (R_FRV_GETTLSOFF,
00472 2,
00473 2,
00474 26,
00475 TRUE,
00476 0,
00477 complain_overflow_bitfield,
00478 bfd_elf_generic_reloc,
00479 "R_FRV_GETTLSOFF",
00480 FALSE,
00481 0x7e03ffff,
00482 0x7e03ffff,
00483 TRUE),
00484
00485
00486
00487 HOWTO (R_FRV_TLSDESC_VALUE,
00488 0,
00489 2,
00490 64,
00491 FALSE,
00492 0,
00493 complain_overflow_bitfield,
00494 bfd_elf_generic_reloc,
00495 "R_FRV_TLSDESC_VALUE",
00496 FALSE,
00497 0xffffffff,
00498 0xffffffff,
00499 FALSE),
00500
00501
00502
00503 HOWTO (R_FRV_GOTTLSDESC12,
00504 0,
00505 2,
00506 12,
00507 FALSE,
00508 0,
00509 complain_overflow_signed,
00510 bfd_elf_generic_reloc,
00511 "R_FRV_GOTTLSDESC12",
00512 FALSE,
00513 0xfff,
00514 0xfff,
00515 FALSE),
00516
00517
00518
00519 HOWTO (R_FRV_GOTTLSDESCHI,
00520 0,
00521 2,
00522 16,
00523 FALSE,
00524 0,
00525 complain_overflow_dont,
00526 bfd_elf_generic_reloc,
00527 "R_FRV_GOTTLSDESCHI",
00528 FALSE,
00529 0xffff,
00530 0xffff,
00531 FALSE),
00532
00533
00534
00535 HOWTO (R_FRV_GOTTLSDESCLO,
00536 0,
00537 2,
00538 16,
00539 FALSE,
00540 0,
00541 complain_overflow_dont,
00542 bfd_elf_generic_reloc,
00543 "R_FRV_GOTTLSDESCLO",
00544 FALSE,
00545 0xffff,
00546 0xffff,
00547 FALSE),
00548
00549
00550
00551 HOWTO (R_FRV_TLSMOFF12,
00552 0,
00553 2,
00554 12,
00555 FALSE,
00556 0,
00557 complain_overflow_signed,
00558 bfd_elf_generic_reloc,
00559 "R_FRV_TLSMOFF12",
00560 FALSE,
00561 0xfff,
00562 0xfff,
00563 FALSE),
00564
00565
00566
00567 HOWTO (R_FRV_TLSMOFFHI,
00568 0,
00569 2,
00570 16,
00571 FALSE,
00572 0,
00573 complain_overflow_dont,
00574 bfd_elf_generic_reloc,
00575 "R_FRV_TLSMOFFHI",
00576 FALSE,
00577 0xffff,
00578 0xffff,
00579 FALSE),
00580
00581
00582
00583 HOWTO (R_FRV_TLSMOFFLO,
00584 0,
00585 2,
00586 16,
00587 FALSE,
00588 0,
00589 complain_overflow_dont,
00590 bfd_elf_generic_reloc,
00591 "R_FRV_TLSMOFFLO",
00592 FALSE,
00593 0xffff,
00594 0xffff,
00595 FALSE),
00596
00597
00598
00599 HOWTO (R_FRV_GOTTLSOFF12,
00600 0,
00601 2,
00602 12,
00603 FALSE,
00604 0,
00605 complain_overflow_signed,
00606 bfd_elf_generic_reloc,
00607 "R_FRV_GOTTLSOFF12",
00608 FALSE,
00609 0xfff,
00610 0xfff,
00611 FALSE),
00612
00613
00614
00615 HOWTO (R_FRV_GOTTLSOFFHI,
00616 0,
00617 2,
00618 16,
00619 FALSE,
00620 0,
00621 complain_overflow_dont,
00622 bfd_elf_generic_reloc,
00623 "R_FRV_GOTTLSOFFHI",
00624 FALSE,
00625 0xffff,
00626 0xffff,
00627 FALSE),
00628
00629
00630
00631 HOWTO (R_FRV_GOTTLSOFFLO,
00632 0,
00633 2,
00634 16,
00635 FALSE,
00636 0,
00637 complain_overflow_dont,
00638 bfd_elf_generic_reloc,
00639 "R_FRV_GOTTLSOFFLO",
00640 FALSE,
00641 0xffff,
00642 0xffff,
00643 FALSE),
00644
00645
00646
00647 HOWTO (R_FRV_TLSOFF,
00648 0,
00649 2,
00650 32,
00651 FALSE,
00652 0,
00653 complain_overflow_dont,
00654 bfd_elf_generic_reloc,
00655 "R_FRV_TLSOFF",
00656 FALSE,
00657 0xffffffff,
00658 0xffffffff,
00659 FALSE),
00660
00661
00662
00663
00664 HOWTO (R_FRV_TLSDESC_RELAX,
00665 0,
00666 2,
00667 0,
00668 FALSE,
00669 0,
00670 complain_overflow_dont,
00671 bfd_elf_generic_reloc,
00672 "R_FRV_TLSDESC_RELAX",
00673 FALSE,
00674 0,
00675 0,
00676 FALSE),
00677
00678
00679
00680
00681 HOWTO (R_FRV_GETTLSOFF_RELAX,
00682 0,
00683 2,
00684 0,
00685 FALSE,
00686 0,
00687 complain_overflow_dont,
00688 bfd_elf_generic_reloc,
00689 "R_FRV_GETTLSOFF_RELAX",
00690 FALSE,
00691 0,
00692 0,
00693 FALSE),
00694
00695
00696
00697
00698 HOWTO (R_FRV_TLSOFF_RELAX,
00699 0,
00700 2,
00701 0,
00702 FALSE,
00703 0,
00704 complain_overflow_bitfield,
00705 bfd_elf_generic_reloc,
00706 "R_FRV_TLSOFF_RELAX",
00707 FALSE,
00708 0,
00709 0,
00710 FALSE),
00711
00712
00713
00714 HOWTO (R_FRV_TLSMOFF,
00715 0,
00716 2,
00717 32,
00718 FALSE,
00719 0,
00720 complain_overflow_dont,
00721 bfd_elf_generic_reloc,
00722 "R_FRV_TLSMOFF",
00723 FALSE,
00724 0xffffffff,
00725 0xffffffff,
00726 FALSE),
00727 };
00728
00729
00730 static reloc_howto_type elf32_frv_vtinherit_howto =
00731 HOWTO (R_FRV_GNU_VTINHERIT,
00732 0,
00733 2,
00734 0,
00735 FALSE,
00736 0,
00737 complain_overflow_dont,
00738 NULL,
00739 "R_FRV_GNU_VTINHERIT",
00740 FALSE,
00741 0,
00742 0,
00743 FALSE);
00744
00745
00746 static reloc_howto_type elf32_frv_vtentry_howto =
00747 HOWTO (R_FRV_GNU_VTENTRY,
00748 0,
00749 2,
00750 0,
00751 FALSE,
00752 0,
00753 complain_overflow_dont,
00754 _bfd_elf_rel_vtable_reloc_fn,
00755 "R_FRV_GNU_VTENTRY",
00756 FALSE,
00757 0,
00758 0,
00759 FALSE);
00760
00761
00762
00763 static reloc_howto_type elf32_frv_rel_32_howto =
00764 HOWTO (R_FRV_32,
00765 0,
00766 2,
00767 32,
00768 FALSE,
00769 0,
00770 complain_overflow_bitfield,
00771 bfd_elf_generic_reloc,
00772 "R_FRV_32",
00773 TRUE,
00774 0xffffffff,
00775 0xffffffff,
00776 FALSE);
00777
00778 static reloc_howto_type elf32_frv_rel_funcdesc_howto =
00779 HOWTO (R_FRV_FUNCDESC,
00780 0,
00781 2,
00782 32,
00783 FALSE,
00784 0,
00785 complain_overflow_bitfield,
00786 bfd_elf_generic_reloc,
00787 "R_FRV_FUNCDESC",
00788 TRUE,
00789 0xffffffff,
00790 0xffffffff,
00791 FALSE);
00792
00793 static reloc_howto_type elf32_frv_rel_funcdesc_value_howto =
00794 HOWTO (R_FRV_FUNCDESC_VALUE,
00795 0,
00796 2,
00797 64,
00798 FALSE,
00799 0,
00800 complain_overflow_bitfield,
00801 bfd_elf_generic_reloc,
00802 "R_FRV_FUNCDESC_VALUE",
00803 TRUE,
00804 0xffffffff,
00805 0xffffffff,
00806 FALSE);
00807
00808 static reloc_howto_type elf32_frv_rel_tlsdesc_value_howto =
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820 HOWTO (R_FRV_TLSDESC_VALUE,
00821 0,
00822 2,
00823 64,
00824 FALSE,
00825 0,
00826 complain_overflow_bitfield,
00827 bfd_elf_generic_reloc,
00828 "R_FRV_TLSDESC_VALUE",
00829 TRUE,
00830 0xffffffff,
00831 0xffffffff,
00832 FALSE);
00833
00834 static reloc_howto_type elf32_frv_rel_tlsoff_howto =
00835
00836
00837 HOWTO (R_FRV_TLSOFF,
00838 0,
00839 2,
00840 32,
00841 FALSE,
00842 0,
00843 complain_overflow_bitfield,
00844 bfd_elf_generic_reloc,
00845 "R_FRV_TLSOFF",
00846 TRUE,
00847 0xffffffff,
00848 0xffffffff,
00849 FALSE);
00850
00851
00852
00853 extern const bfd_target bfd_elf32_frvfdpic_vec;
00854 #define IS_FDPIC(bfd) ((bfd)->xvec == &bfd_elf32_frvfdpic_vec)
00855
00856
00857
00858 struct frvfdpic_elf_link_hash_table
00859 {
00860 struct elf_link_hash_table elf;
00861
00862
00863 asection *sgot;
00864
00865 asection *sgotrel;
00866
00867 asection *sgotfixup;
00868
00869 asection *splt;
00870
00871 asection *spltrel;
00872
00873 bfd_vma got0;
00874
00875
00876
00877
00878 bfd_vma plt0;
00879
00880
00881 struct htab *relocs_info;
00882
00883
00884 struct _frvfdpic_dynamic_got_info *g;
00885 };
00886
00887
00888
00889 #define frvfdpic_hash_table(info) \
00890 ((struct frvfdpic_elf_link_hash_table *) ((info)->hash))
00891
00892 #define frvfdpic_got_section(info) \
00893 (frvfdpic_hash_table (info)->sgot)
00894 #define frvfdpic_gotrel_section(info) \
00895 (frvfdpic_hash_table (info)->sgotrel)
00896 #define frvfdpic_gotfixup_section(info) \
00897 (frvfdpic_hash_table (info)->sgotfixup)
00898 #define frvfdpic_plt_section(info) \
00899 (frvfdpic_hash_table (info)->splt)
00900 #define frvfdpic_pltrel_section(info) \
00901 (frvfdpic_hash_table (info)->spltrel)
00902 #define frvfdpic_relocs_info(info) \
00903 (frvfdpic_hash_table (info)->relocs_info)
00904 #define frvfdpic_got_initial_offset(info) \
00905 (frvfdpic_hash_table (info)->got0)
00906 #define frvfdpic_plt_initial_offset(info) \
00907 (frvfdpic_hash_table (info)->plt0)
00908 #define frvfdpic_dynamic_got_plt_info(info) \
00909 (frvfdpic_hash_table (info)->g)
00910
00911
00912
00913
00914
00915
00916
00917 #define frvfdpic_plt_tls_ret_offset(info) \
00918 (frvfdpic_plt_initial_offset (info))
00919
00920
00921
00922
00923 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
00924
00925 #define DEFAULT_STACK_SIZE 0x20000
00926
00927
00928
00929 struct _frvfdpic_dynamic_got_info
00930 {
00931
00932 struct bfd_link_info *info;
00933
00934
00935 bfd_vma got12, gotlos, gothilo;
00936
00937
00938 bfd_vma fd12, fdlos, fdhilo;
00939
00940
00941
00942 bfd_vma fdplt;
00943
00944 bfd_vma lzplt;
00945
00946
00947 bfd_vma tlsd12, tlsdlos, tlsdhilo;
00948
00949
00950
00951 bfd_vma tlsdplt;
00952
00953 bfd_vma tlslzplt;
00954
00955 unsigned long relocs;
00956
00957 unsigned long fixups;
00958
00959
00960 unsigned long tls_ret_refs;
00961 };
00962
00963
00964
00965
00966 struct _frvfdpic_dynamic_got_plt_info
00967 {
00968
00969 struct _frvfdpic_dynamic_got_info g;
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991 struct _frvfdpic_dynamic_got_alloc_data
00992 {
00993 bfd_signed_vma max, cur, odd, fdcur, min;
00994 bfd_signed_vma tmax, tcur, tmin;
00995 bfd_vma fdplt, tlsdplt;
00996 } got12, gotlos, gothilo;
00997 };
00998
00999
01000
01001 static struct bfd_link_hash_table *
01002 frvfdpic_elf_link_hash_table_create (bfd *abfd)
01003 {
01004 struct frvfdpic_elf_link_hash_table *ret;
01005 bfd_size_type amt = sizeof (struct frvfdpic_elf_link_hash_table);
01006
01007 ret = bfd_zalloc (abfd, amt);
01008 if (ret == NULL)
01009 return NULL;
01010
01011 if (! _bfd_elf_link_hash_table_init (&ret->elf, abfd,
01012 _bfd_elf_link_hash_newfunc))
01013 {
01014 free (ret);
01015 return NULL;
01016 }
01017
01018 return &ret->elf.root;
01019 }
01020
01021
01022
01023
01024 #define FRVFDPIC_SYM_LOCAL(INFO, H) \
01025 (_bfd_elf_symbol_refs_local_p ((H), (INFO), 1) \
01026 || ! elf_hash_table (INFO)->dynamic_sections_created)
01027 #define FRVFDPIC_FUNCDESC_LOCAL(INFO, H) \
01028 ((H)->dynindx == -1 || ! elf_hash_table (INFO)->dynamic_sections_created)
01029
01030
01031
01032
01033 struct frvfdpic_relocs_info
01034 {
01035
01036
01037 long symndx;
01038 union
01039 {
01040
01041
01042 bfd *abfd;
01043
01044
01045
01046 struct elf_link_hash_entry *h;
01047 } d;
01048
01049 bfd_vma addend;
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059 unsigned got12:1;
01060 unsigned gotlos:1;
01061 unsigned gothilo:1;
01062
01063 unsigned fd:1;
01064
01065 unsigned fdgot12:1;
01066 unsigned fdgotlos:1;
01067 unsigned fdgothilo:1;
01068
01069 unsigned fdgoff12:1;
01070 unsigned fdgofflos:1;
01071 unsigned fdgoffhilo:1;
01072
01073 unsigned tlsplt:1;
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083 unsigned tlsdesc12:1;
01084 unsigned tlsdesclos:1;
01085 unsigned tlsdeschilo:1;
01086
01087 unsigned tlsoff12:1;
01088 unsigned tlsofflos:1;
01089 unsigned tlsoffhilo:1;
01090
01091
01092
01093
01094 unsigned gotoff:1;
01095
01096 unsigned call:1;
01097
01098
01099 unsigned sym:1;
01100
01101
01102
01103 unsigned plt:1;
01104
01105
01106
01107
01108
01109 unsigned privfd:1;
01110
01111
01112
01113
01114 unsigned lazyplt:1;
01115
01116
01117 unsigned done:1;
01118
01119
01120
01121
01122 unsigned relocs32, relocsfd, relocsfdv, relocstlsd, relocstlsoff;
01123
01124
01125
01126 unsigned fixups, dynrelocs;
01127
01128
01129
01130
01131
01132
01133 bfd_signed_vma got_entry, fdgot_entry, fd_entry;
01134
01135
01136
01137 bfd_vma plt_entry, lzplt_entry;
01138
01139 bfd_signed_vma tlsoff_entry, tlsdesc_entry;
01140
01141 bfd_vma tlsplt_entry;
01142 };
01143
01144
01145 static hashval_t
01146 frvfdpic_relocs_info_hash (const void *entry_)
01147 {
01148 const struct frvfdpic_relocs_info *entry = entry_;
01149
01150 return (entry->symndx == -1
01151 ? (long) entry->d.h->root.root.hash
01152 : entry->symndx + (long) entry->d.abfd->id * 257) + entry->addend;
01153 }
01154
01155
01156
01157 static int
01158 frvfdpic_relocs_info_eq (const void *entry1, const void *entry2)
01159 {
01160 const struct frvfdpic_relocs_info *e1 = entry1;
01161 const struct frvfdpic_relocs_info *e2 = entry2;
01162
01163 return e1->symndx == e2->symndx && e1->addend == e2->addend
01164 && (e1->symndx == -1 ? e1->d.h == e2->d.h : e1->d.abfd == e2->d.abfd);
01165 }
01166
01167
01168
01169
01170 static struct frvfdpic_relocs_info *
01171 frvfdpic_relocs_info_find (struct htab *ht,
01172 bfd *abfd,
01173 const struct frvfdpic_relocs_info *entry,
01174 enum insert_option insert)
01175 {
01176 struct frvfdpic_relocs_info **loc =
01177 (struct frvfdpic_relocs_info **) htab_find_slot (ht, entry, insert);
01178
01179 if (! loc)
01180 return NULL;
01181
01182 if (*loc)
01183 return *loc;
01184
01185 *loc = bfd_zalloc (abfd, sizeof (**loc));
01186
01187 if (! *loc)
01188 return *loc;
01189
01190 (*loc)->symndx = entry->symndx;
01191 (*loc)->d = entry->d;
01192 (*loc)->addend = entry->addend;
01193 (*loc)->plt_entry = (bfd_vma)-1;
01194 (*loc)->lzplt_entry = (bfd_vma)-1;
01195 (*loc)->tlsplt_entry = (bfd_vma)-1;
01196
01197 return *loc;
01198 }
01199
01200
01201
01202
01203 inline static struct frvfdpic_relocs_info *
01204 frvfdpic_relocs_info_for_global (struct htab *ht,
01205 bfd *abfd,
01206 struct elf_link_hash_entry *h,
01207 bfd_vma addend,
01208 enum insert_option insert)
01209 {
01210 struct frvfdpic_relocs_info entry;
01211
01212 entry.symndx = -1;
01213 entry.d.h = h;
01214 entry.addend = addend;
01215
01216 return frvfdpic_relocs_info_find (ht, abfd, &entry, insert);
01217 }
01218
01219
01220
01221
01222 inline static struct frvfdpic_relocs_info *
01223 frvfdpic_relocs_info_for_local (struct htab *ht,
01224 bfd *abfd,
01225 long symndx,
01226 bfd_vma addend,
01227 enum insert_option insert)
01228 {
01229 struct frvfdpic_relocs_info entry;
01230
01231 entry.symndx = symndx;
01232 entry.d.abfd = abfd;
01233 entry.addend = addend;
01234
01235 return frvfdpic_relocs_info_find (ht, abfd, &entry, insert);
01236 }
01237
01238
01239
01240
01241 inline static void
01242 frvfdpic_pic_merge_early_relocs_info (struct frvfdpic_relocs_info *e2,
01243 struct frvfdpic_relocs_info const *e1)
01244 {
01245 e2->got12 |= e1->got12;
01246 e2->gotlos |= e1->gotlos;
01247 e2->gothilo |= e1->gothilo;
01248 e2->fd |= e1->fd;
01249 e2->fdgot12 |= e1->fdgot12;
01250 e2->fdgotlos |= e1->fdgotlos;
01251 e2->fdgothilo |= e1->fdgothilo;
01252 e2->fdgoff12 |= e1->fdgoff12;
01253 e2->fdgofflos |= e1->fdgofflos;
01254 e2->fdgoffhilo |= e1->fdgoffhilo;
01255 e2->tlsplt |= e1->tlsplt;
01256 e2->tlsdesc12 |= e1->tlsdesc12;
01257 e2->tlsdesclos |= e1->tlsdesclos;
01258 e2->tlsdeschilo |= e1->tlsdeschilo;
01259 e2->tlsoff12 |= e1->tlsoff12;
01260 e2->tlsofflos |= e1->tlsofflos;
01261 e2->tlsoffhilo |= e1->tlsoffhilo;
01262 e2->gotoff |= e1->gotoff;
01263 e2->call |= e1->call;
01264 e2->sym |= e1->sym;
01265 }
01266
01267
01268
01269
01270
01271
01272 #define FRVFDPIC_LZPLT_BLOCK_SIZE ((bfd_vma) 8 * 65535 + 4)
01273 #define FRVFDPIC_LZPLT_RESOLV_LOC (8 * 32767)
01274
01275
01276
01277 inline static bfd_vma
01278 _frvfdpic_add_dyn_reloc (bfd *output_bfd, asection *sreloc, bfd_vma offset,
01279 int reloc_type, long dynindx, bfd_vma addend,
01280 struct frvfdpic_relocs_info *entry)
01281 {
01282 Elf_Internal_Rela outrel;
01283 bfd_vma reloc_offset;
01284
01285 outrel.r_offset = offset;
01286 outrel.r_info = ELF32_R_INFO (dynindx, reloc_type);
01287 outrel.r_addend = addend;
01288
01289 reloc_offset = sreloc->reloc_count * sizeof (Elf32_External_Rel);
01290 BFD_ASSERT (reloc_offset < sreloc->size);
01291 bfd_elf32_swap_reloc_out (output_bfd, &outrel,
01292 sreloc->contents + reloc_offset);
01293 sreloc->reloc_count++;
01294
01295
01296
01297
01298
01299
01300
01301
01302 if (entry->symndx)
01303 {
01304 BFD_ASSERT (entry->dynrelocs > 0);
01305 entry->dynrelocs--;
01306 }
01307
01308 return reloc_offset;
01309 }
01310
01311
01312
01313 static bfd_vma
01314 _frvfdpic_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset,
01315 struct frvfdpic_relocs_info *entry)
01316 {
01317 bfd_vma fixup_offset;
01318
01319 if (rofixup->flags & SEC_EXCLUDE)
01320 return -1;
01321
01322 fixup_offset = rofixup->reloc_count * 4;
01323 if (rofixup->contents)
01324 {
01325 BFD_ASSERT (fixup_offset < rofixup->size);
01326 bfd_put_32 (output_bfd, offset, rofixup->contents + fixup_offset);
01327 }
01328 rofixup->reloc_count++;
01329
01330 if (entry && entry->symndx)
01331 {
01332
01333
01334 BFD_ASSERT (entry->fixups > 0);
01335 entry->fixups--;
01336 }
01337
01338 return fixup_offset;
01339 }
01340
01341
01342
01343
01344 static unsigned
01345 _frvfdpic_osec_to_segment (bfd *output_bfd, asection *osec)
01346 {
01347 struct elf_segment_map *m;
01348 Elf_Internal_Phdr *p;
01349
01350
01351 for (m = elf_tdata (output_bfd)->segment_map,
01352 p = elf_tdata (output_bfd)->phdr;
01353 m != NULL;
01354 m = m->next, p++)
01355 {
01356 int i;
01357
01358 for (i = m->count - 1; i >= 0; i--)
01359 if (m->sections[i] == osec)
01360 break;
01361
01362 if (i >= 0)
01363 break;
01364 }
01365
01366 return p - elf_tdata (output_bfd)->phdr;
01367 }
01368
01369 inline static bfd_boolean
01370 _frvfdpic_osec_readonly_p (bfd *output_bfd, asection *osec)
01371 {
01372 unsigned seg = _frvfdpic_osec_to_segment (output_bfd, osec);
01373
01374 return ! (elf_tdata (output_bfd)->phdr[seg].p_flags & PF_W);
01375 }
01376
01377 #define FRVFDPIC_TLS_BIAS (2048 - 16)
01378
01379
01380
01381
01382
01383 static bfd_vma
01384 tls_biased_base (struct bfd_link_info *info)
01385 {
01386
01387 if (elf_hash_table (info)->tls_sec == NULL)
01388 return FRVFDPIC_TLS_BIAS;
01389 return elf_hash_table (info)->tls_sec->vma + FRVFDPIC_TLS_BIAS;
01390 }
01391
01392
01393
01394
01395 inline static bfd_boolean
01396 _frvfdpic_emit_got_relocs_plt_entries (struct frvfdpic_relocs_info *entry,
01397 bfd *output_bfd,
01398 struct bfd_link_info *info,
01399 asection *sec,
01400 Elf_Internal_Sym *sym,
01401 bfd_vma addend)
01402
01403 {
01404 bfd_vma fd_lazy_rel_offset = (bfd_vma)-1;
01405 int dynindx = -1;
01406
01407 if (entry->done)
01408 return TRUE;
01409 entry->done = 1;
01410
01411 if (entry->got_entry || entry->fdgot_entry || entry->fd_entry
01412 || entry->tlsoff_entry || entry->tlsdesc_entry)
01413 {
01414
01415
01416 if (entry->symndx == -1 && entry->d.h->dynindx != -1)
01417 dynindx = entry->d.h->dynindx;
01418 else
01419 {
01420 if (sec->output_section
01421 && ! bfd_is_abs_section (sec->output_section)
01422 && ! bfd_is_und_section (sec->output_section))
01423 dynindx = elf_section_data (sec->output_section)->dynindx;
01424 else
01425 dynindx = 0;
01426 }
01427 }
01428
01429
01430 if (entry->got_entry)
01431 {
01432 int idx = dynindx;
01433 bfd_vma ad = addend;
01434
01435
01436
01437 if (sec && (entry->symndx != -1
01438 || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
01439 {
01440 if (entry->symndx == -1)
01441 ad += entry->d.h->root.u.def.value;
01442 else
01443 ad += sym->st_value;
01444 ad += sec->output_offset;
01445 if (sec->output_section && elf_section_data (sec->output_section))
01446 idx = elf_section_data (sec->output_section)->dynindx;
01447 else
01448 idx = 0;
01449 }
01450
01451
01452
01453
01454 if (info->executable && !info->pie
01455 && (entry->symndx != -1
01456 || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
01457 {
01458 if (sec)
01459 ad += sec->output_section->vma;
01460 if (entry->symndx != -1
01461 || entry->d.h->root.type != bfd_link_hash_undefweak)
01462 _frvfdpic_add_rofixup (output_bfd,
01463 frvfdpic_gotfixup_section (info),
01464 frvfdpic_got_section (info)->output_section
01465 ->vma
01466 + frvfdpic_got_section (info)->output_offset
01467 + frvfdpic_got_initial_offset (info)
01468 + entry->got_entry, entry);
01469 }
01470 else
01471 _frvfdpic_add_dyn_reloc (output_bfd, frvfdpic_gotrel_section (info),
01472 _bfd_elf_section_offset
01473 (output_bfd, info,
01474 frvfdpic_got_section (info),
01475 frvfdpic_got_initial_offset (info)
01476 + entry->got_entry)
01477 + frvfdpic_got_section (info)
01478 ->output_section->vma
01479 + frvfdpic_got_section (info)->output_offset,
01480 R_FRV_32, idx, ad, entry);
01481
01482 bfd_put_32 (output_bfd, ad,
01483 frvfdpic_got_section (info)->contents
01484 + frvfdpic_got_initial_offset (info)
01485 + entry->got_entry);
01486 }
01487
01488
01489
01490 if (entry->fdgot_entry)
01491 {
01492 int reloc, idx;
01493 bfd_vma ad = 0;
01494
01495 if (! (entry->symndx == -1
01496 && entry->d.h->root.type == bfd_link_hash_undefweak
01497 && FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
01498 {
01499
01500
01501
01502
01503
01504
01505
01506 if (entry->symndx == -1
01507 && ! FRVFDPIC_FUNCDESC_LOCAL (info, entry->d.h)
01508 && FRVFDPIC_SYM_LOCAL (info, entry->d.h)
01509 && !(info->executable && !info->pie))
01510 {
01511 reloc = R_FRV_FUNCDESC;
01512 idx = elf_section_data (entry->d.h->root.u.def.section
01513 ->output_section)->dynindx;
01514 ad = entry->d.h->root.u.def.section->output_offset
01515 + entry->d.h->root.u.def.value;
01516 }
01517 else if (entry->symndx == -1
01518 && ! FRVFDPIC_FUNCDESC_LOCAL (info, entry->d.h))
01519 {
01520 reloc = R_FRV_FUNCDESC;
01521 idx = dynindx;
01522 ad = addend;
01523 if (ad)
01524 {
01525 (*info->callbacks->reloc_dangerous)
01526 (info, _("relocation requires zero addend"),
01527 elf_hash_table (info)->dynobj,
01528 frvfdpic_got_section (info),
01529 entry->fdgot_entry);
01530 return FALSE;
01531 }
01532 }
01533 else
01534 {
01535
01536
01537 if (elf_hash_table (info)->dynamic_sections_created)
01538 BFD_ASSERT (entry->privfd);
01539 reloc = R_FRV_32;
01540 idx = elf_section_data (frvfdpic_got_section (info)
01541 ->output_section)->dynindx;
01542 ad = frvfdpic_got_section (info)->output_offset
01543 + frvfdpic_got_initial_offset (info) + entry->fd_entry;
01544 }
01545
01546
01547
01548
01549
01550
01551
01552 if (info->executable && !info->pie
01553 && (entry->symndx != -1
01554 || FRVFDPIC_FUNCDESC_LOCAL (info, entry->d.h)))
01555 {
01556 ad += frvfdpic_got_section (info)->output_section->vma;
01557 _frvfdpic_add_rofixup (output_bfd,
01558 frvfdpic_gotfixup_section (info),
01559 frvfdpic_got_section (info)
01560 ->output_section->vma
01561 + frvfdpic_got_section (info)
01562 ->output_offset
01563 + frvfdpic_got_initial_offset (info)
01564 + entry->fdgot_entry, entry);
01565 }
01566 else
01567 _frvfdpic_add_dyn_reloc (output_bfd,
01568 frvfdpic_gotrel_section (info),
01569 _bfd_elf_section_offset
01570 (output_bfd, info,
01571 frvfdpic_got_section (info),
01572 frvfdpic_got_initial_offset (info)
01573 + entry->fdgot_entry)
01574 + frvfdpic_got_section (info)
01575 ->output_section->vma
01576 + frvfdpic_got_section (info)
01577 ->output_offset,
01578 reloc, idx, ad, entry);
01579 }
01580
01581 bfd_put_32 (output_bfd, ad,
01582 frvfdpic_got_section (info)->contents
01583 + frvfdpic_got_initial_offset (info)
01584 + entry->fdgot_entry);
01585 }
01586
01587
01588
01589 if (entry->fd_entry)
01590 {
01591 int idx = dynindx;
01592 bfd_vma ad = addend;
01593 bfd_vma ofst;
01594 long lowword, highword;
01595
01596
01597
01598 if (sec && (entry->symndx != -1
01599 || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
01600 {
01601 if (entry->symndx == -1)
01602 ad += entry->d.h->root.u.def.value;
01603 else
01604 ad += sym->st_value;
01605 ad += sec->output_offset;
01606 if (sec->output_section && elf_section_data (sec->output_section))
01607 idx = elf_section_data (sec->output_section)->dynindx;
01608 else
01609 idx = 0;
01610 }
01611
01612
01613
01614
01615 if (info->executable && !info->pie
01616 && (entry->symndx != -1 || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
01617 {
01618 if (sec)
01619 ad += sec->output_section->vma;
01620 ofst = 0;
01621 if (entry->symndx != -1
01622 || entry->d.h->root.type != bfd_link_hash_undefweak)
01623 {
01624 _frvfdpic_add_rofixup (output_bfd,
01625 frvfdpic_gotfixup_section (info),
01626 frvfdpic_got_section (info)
01627 ->output_section->vma
01628 + frvfdpic_got_section (info)
01629 ->output_offset
01630 + frvfdpic_got_initial_offset (info)
01631 + entry->fd_entry, entry);
01632 _frvfdpic_add_rofixup (output_bfd,
01633 frvfdpic_gotfixup_section (info),
01634 frvfdpic_got_section (info)
01635 ->output_section->vma
01636 + frvfdpic_got_section (info)
01637 ->output_offset
01638 + frvfdpic_got_initial_offset (info)
01639 + entry->fd_entry + 4, entry);
01640 }
01641 }
01642 else
01643 {
01644 ofst =
01645 _frvfdpic_add_dyn_reloc (output_bfd,
01646 entry->lazyplt
01647 ? frvfdpic_pltrel_section (info)
01648 : frvfdpic_gotrel_section (info),
01649 _bfd_elf_section_offset
01650 (output_bfd, info,
01651 frvfdpic_got_section (info),
01652 frvfdpic_got_initial_offset (info)
01653 + entry->fd_entry)
01654 + frvfdpic_got_section (info)
01655 ->output_section->vma
01656 + frvfdpic_got_section (info)
01657 ->output_offset,
01658 R_FRV_FUNCDESC_VALUE, idx, ad, entry);
01659 }
01660
01661
01662
01663 if (info->executable && !info->pie && sec && sec->output_section)
01664 {
01665 lowword = ad;
01666 highword = frvfdpic_got_section (info)->output_section->vma
01667 + frvfdpic_got_section (info)->output_offset
01668 + frvfdpic_got_initial_offset (info);
01669 }
01670 else if (entry->lazyplt)
01671 {
01672 if (ad)
01673 {
01674 (*info->callbacks->reloc_dangerous)
01675 (info, _("relocation requires zero addend"),
01676 elf_hash_table (info)->dynobj,
01677 frvfdpic_got_section (info),
01678 entry->fd_entry);
01679 return FALSE;
01680 }
01681
01682 fd_lazy_rel_offset = ofst;
01683
01684
01685
01686
01687
01688
01689
01690 lowword = entry->lzplt_entry + 4
01691 + frvfdpic_plt_section (info)->output_offset
01692 + frvfdpic_plt_section (info)->output_section->vma;
01693 highword = _frvfdpic_osec_to_segment
01694 (output_bfd, frvfdpic_plt_section (info)->output_section);
01695 }
01696 else
01697 {
01698
01699
01700
01701 lowword = ad;
01702 if (entry->symndx == -1 && entry->d.h->dynindx != -1
01703 && entry->d.h->dynindx == idx)
01704 highword = 0;
01705 else
01706 highword = _frvfdpic_osec_to_segment
01707 (output_bfd, sec->output_section);
01708 }
01709
01710 bfd_put_32 (output_bfd, lowword,
01711 frvfdpic_got_section (info)->contents
01712 + frvfdpic_got_initial_offset (info)
01713 + entry->fd_entry);
01714 bfd_put_32 (output_bfd, highword,
01715 frvfdpic_got_section (info)->contents
01716 + frvfdpic_got_initial_offset (info)
01717 + entry->fd_entry + 4);
01718 }
01719
01720
01721 if (entry->plt_entry != (bfd_vma) -1)
01722 {
01723 bfd_byte *plt_code = frvfdpic_plt_section (info)->contents
01724 + entry->plt_entry;
01725
01726 BFD_ASSERT (entry->fd_entry);
01727
01728
01729
01730 if (entry->fd_entry >= -(1 << (12 - 1))
01731 && entry->fd_entry < (1 << (12 - 1)))
01732 {
01733
01734 bfd_put_32 (output_bfd,
01735 0x9cccf000 | (entry->fd_entry & ((1 << 12) - 1)),
01736 plt_code);
01737 plt_code += 4;
01738 }
01739 else
01740 {
01741 if (entry->fd_entry >= -(1 << (16 - 1))
01742 && entry->fd_entry < (1 << (16 - 1)))
01743 {
01744
01745 bfd_put_32 (output_bfd,
01746 0x9cfc0000
01747 | (entry->fd_entry & (((bfd_vma)1 << 16) - 1)),
01748 plt_code);
01749 plt_code += 4;
01750 }
01751 else
01752 {
01753
01754
01755 bfd_put_32 (output_bfd,
01756 0x1cf80000
01757 | ((entry->fd_entry >> 16)
01758 & (((bfd_vma)1 << 16) - 1)),
01759 plt_code);
01760 plt_code += 4;
01761 bfd_put_32 (output_bfd,
01762 0x9cf40000
01763 | (entry->fd_entry & (((bfd_vma)1 << 16) - 1)),
01764 plt_code);
01765 plt_code += 4;
01766 }
01767
01768 bfd_put_32 (output_bfd, 0x9c08e14f, plt_code);
01769 plt_code += 4;
01770 }
01771
01772 bfd_put_32 (output_bfd, 0x8030e000, plt_code);
01773 }
01774
01775
01776 if (entry->lzplt_entry != (bfd_vma) -1)
01777 {
01778 bfd_byte *lzplt_code = frvfdpic_plt_section (info)->contents
01779 + entry->lzplt_entry;
01780 bfd_vma resolverStub_addr;
01781
01782 bfd_put_32 (output_bfd, fd_lazy_rel_offset, lzplt_code);
01783 lzplt_code += 4;
01784
01785 resolverStub_addr = entry->lzplt_entry / FRVFDPIC_LZPLT_BLOCK_SIZE
01786 * FRVFDPIC_LZPLT_BLOCK_SIZE + FRVFDPIC_LZPLT_RESOLV_LOC;
01787 if (resolverStub_addr >= frvfdpic_plt_initial_offset (info))
01788 resolverStub_addr = frvfdpic_plt_initial_offset (info) - 12;
01789
01790 if (entry->lzplt_entry == resolverStub_addr)
01791 {
01792
01793
01794
01795 bfd_put_32 (output_bfd, 0x8808f140, lzplt_code);
01796 bfd_put_32 (output_bfd, 0x80304000, lzplt_code + 4);
01797 }
01798 else
01799 {
01800
01801 bfd_put_32 (output_bfd,
01802 0xc01a0000
01803 | (((resolverStub_addr - entry->lzplt_entry)
01804 / 4) & (((bfd_vma)1 << 16) - 1)),
01805 lzplt_code);
01806 }
01807 }
01808
01809
01810 if (entry->tlsoff_entry)
01811 {
01812 int idx = dynindx;
01813 bfd_vma ad = addend;
01814
01815 if (entry->symndx != -1
01816 || FRVFDPIC_SYM_LOCAL (info, entry->d.h))
01817 {
01818
01819
01820 if (sec)
01821 {
01822 if (entry->symndx == -1)
01823 ad += entry->d.h->root.u.def.value;
01824 else
01825 ad += sym->st_value;
01826 ad += sec->output_offset;
01827 if (sec->output_section
01828 && elf_section_data (sec->output_section))
01829 idx = elf_section_data (sec->output_section)->dynindx;
01830 else
01831 idx = 0;
01832 }
01833 }
01834
01835
01836
01837 if (info->executable
01838 && idx == 0
01839 && (bfd_is_abs_section (sec)
01840 || bfd_is_und_section (sec)))
01841 ;
01842
01843
01844 else if (info->executable
01845 && (entry->symndx != -1
01846 || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
01847 {
01848 if (sec)
01849 ad += sec->output_section->vma - tls_biased_base (info);
01850 }
01851 else
01852 {
01853 if (idx == 0
01854 && (bfd_is_abs_section (sec)
01855 || bfd_is_und_section (sec)))
01856 {
01857 if (! elf_hash_table (info)->tls_sec)
01858 {
01859 (*info->callbacks->undefined_symbol)
01860 (info, "TLS section", elf_hash_table (info)->dynobj,
01861 frvfdpic_got_section (info), entry->tlsoff_entry, TRUE);
01862 return FALSE;
01863 }
01864 idx = elf_section_data (elf_hash_table (info)->tls_sec)->dynindx;
01865 ad += FRVFDPIC_TLS_BIAS;
01866 }
01867 _frvfdpic_add_dyn_reloc (output_bfd, frvfdpic_gotrel_section (info),
01868 _bfd_elf_section_offset
01869 (output_bfd, info,
01870 frvfdpic_got_section (info),
01871 frvfdpic_got_initial_offset (info)
01872 + entry->tlsoff_entry)
01873 + frvfdpic_got_section (info)
01874 ->output_section->vma
01875 + frvfdpic_got_section (info)
01876 ->output_offset,
01877 R_FRV_TLSOFF, idx, ad, entry);
01878 }
01879
01880 bfd_put_32 (output_bfd, ad,
01881 frvfdpic_got_section (info)->contents
01882 + frvfdpic_got_initial_offset (info)
01883 + entry->tlsoff_entry);
01884 }
01885
01886 if (entry->tlsdesc_entry)
01887 {
01888 int idx = dynindx;
01889 bfd_vma ad = addend;
01890
01891
01892
01893 if (sec && (entry->symndx != -1
01894 || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
01895 {
01896 if (entry->symndx == -1)
01897 ad += entry->d.h->root.u.def.value;
01898 else
01899 ad += sym->st_value;
01900 ad += sec->output_offset;
01901 if (sec->output_section && elf_section_data (sec->output_section))
01902 idx = elf_section_data (sec->output_section)->dynindx;
01903 else
01904 idx = 0;
01905 }
01906
01907
01908
01909
01910 if (info->executable && ! entry->tlsoff_entry)
01911 entry->tlsoff_entry = entry->tlsdesc_entry + 4;
01912
01913 if (info->executable && !info->pie
01914 && ((idx == 0
01915 && (bfd_is_abs_section (sec)
01916 || bfd_is_und_section (sec)))
01917 || entry->symndx != -1
01918 || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
01919 {
01920
01921
01922
01923 if (idx == 0
01924 && (bfd_is_abs_section (sec)
01925 || bfd_is_und_section (sec)))
01926 ;
01927
01928
01929 else if (sec)
01930 ad += sec->output_section->vma - tls_biased_base (info);
01931
01932 bfd_put_32 (output_bfd,
01933 frvfdpic_plt_section (info)->output_section->vma
01934 + frvfdpic_plt_section (info)->output_offset
01935 + frvfdpic_plt_tls_ret_offset (info),
01936 frvfdpic_got_section (info)->contents
01937 + frvfdpic_got_initial_offset (info)
01938 + entry->tlsdesc_entry);
01939
01940 _frvfdpic_add_rofixup (output_bfd,
01941 frvfdpic_gotfixup_section (info),
01942 frvfdpic_got_section (info)
01943 ->output_section->vma
01944 + frvfdpic_got_section (info)
01945 ->output_offset
01946 + frvfdpic_got_initial_offset (info)
01947 + entry->tlsdesc_entry, entry);
01948
01949 BFD_ASSERT (frvfdpic_dynamic_got_plt_info (info)->tls_ret_refs);
01950
01951
01952
01953
01954 frvfdpic_dynamic_got_plt_info (info)->tls_ret_refs--;
01955
01956
01957
01958
01959
01960
01961 bfd_put_32 (output_bfd, 0xc03a4000,
01962 frvfdpic_plt_section (info)->contents
01963 + frvfdpic_plt_tls_ret_offset (info));
01964 }
01965 else
01966 {
01967 if (idx == 0
01968 && (bfd_is_abs_section (sec)
01969 || bfd_is_und_section (sec)))
01970 {
01971 if (! elf_hash_table (info)->tls_sec)
01972 {
01973 (*info->callbacks->undefined_symbol)
01974 (info, "TLS section", elf_hash_table (info)->dynobj,
01975 frvfdpic_got_section (info), entry->tlsdesc_entry, TRUE);
01976 return FALSE;
01977 }
01978 idx = elf_section_data (elf_hash_table (info)->tls_sec)->dynindx;
01979 ad += FRVFDPIC_TLS_BIAS;
01980 }
01981
01982 _frvfdpic_add_dyn_reloc (output_bfd, frvfdpic_gotrel_section (info),
01983 _bfd_elf_section_offset
01984 (output_bfd, info,
01985 frvfdpic_got_section (info),
01986 frvfdpic_got_initial_offset (info)
01987 + entry->tlsdesc_entry)
01988 + frvfdpic_got_section (info)
01989 ->output_section->vma
01990 + frvfdpic_got_section (info)
01991 ->output_offset,
01992 R_FRV_TLSDESC_VALUE, idx, ad, entry);
01993
01994 bfd_put_32 (output_bfd, 0,
01995 frvfdpic_got_section (info)->contents
01996 + frvfdpic_got_initial_offset (info)
01997 + entry->tlsdesc_entry);
01998 }
01999
02000 bfd_put_32 (output_bfd, ad,
02001 frvfdpic_got_section (info)->contents
02002 + frvfdpic_got_initial_offset (info)
02003 + entry->tlsdesc_entry + 4);
02004 }
02005
02006
02007 if (entry->tlsplt_entry != (bfd_vma) -1)
02008 {
02009 bfd_byte *plt_code = frvfdpic_plt_section (info)->contents
02010 + entry->tlsplt_entry;
02011
02012 if (info->executable
02013 && (entry->symndx != -1
02014 || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
02015 {
02016 int idx = dynindx;
02017 bfd_vma ad = addend;
02018
02019
02020
02021 if (!sec)
02022 {
02023 BFD_ASSERT (entry->symndx == -1
02024 && entry->d.h->root.type == bfd_link_hash_undefweak);
02025 }
02026 else
02027 {
02028 if (entry->symndx == -1)
02029 ad += entry->d.h->root.u.def.value;
02030 else
02031 ad += sym->st_value;
02032 ad += sec->output_offset;
02033 if (sec->output_section
02034 && elf_section_data (sec->output_section))
02035 idx = elf_section_data (sec->output_section)->dynindx;
02036 else
02037 idx = 0;
02038 }
02039
02040
02041
02042
02043 if (idx == 0
02044 && (bfd_is_abs_section (sec)
02045 || bfd_is_und_section (sec)))
02046 ;
02047
02048
02049 else if (sec)
02050 ad += sec->output_section->vma - tls_biased_base (info);
02051
02052 if ((bfd_signed_vma)ad >= -(1 << (16 - 1))
02053 && (bfd_signed_vma)ad < (1 << (16 - 1)))
02054 {
02055
02056 bfd_put_32 (output_bfd,
02057 0x92fc0000
02058 | (ad
02059 & (((bfd_vma)1 << 16) - 1)),
02060 plt_code);
02061 plt_code += 4;
02062 }
02063 else
02064 {
02065
02066
02067 bfd_put_32 (output_bfd,
02068 0x12f80000
02069 | ((ad >> 16)
02070 & (((bfd_vma)1 << 16) - 1)),
02071 plt_code);
02072 plt_code += 4;
02073 bfd_put_32 (output_bfd,
02074 0x92f40000
02075 | (ad
02076 & (((bfd_vma)1 << 16) - 1)),
02077 plt_code);
02078 plt_code += 4;
02079 }
02080
02081 bfd_put_32 (output_bfd, 0xc03a4000, plt_code);
02082 }
02083 else if (entry->tlsoff_entry)
02084 {
02085
02086
02087 if (entry->tlsoff_entry >= -(1 << (12 - 1))
02088 && entry->tlsoff_entry < (1 << (12 - 1)))
02089 {
02090
02091 bfd_put_32 (output_bfd,
02092 0x92c8f000 | (entry->tlsoff_entry
02093 & ((1 << 12) - 1)),
02094 plt_code);
02095 plt_code += 4;
02096 }
02097 else
02098 {
02099 if (entry->tlsoff_entry >= -(1 << (16 - 1))
02100 && entry->tlsoff_entry < (1 << (16 - 1)))
02101 {
02102
02103 bfd_put_32 (output_bfd,
02104 0x90fc0000
02105 | (entry->tlsoff_entry
02106 & (((bfd_vma)1 << 16) - 1)),
02107 plt_code);
02108 plt_code += 4;
02109 }
02110 else
02111 {
02112
02113
02114 bfd_put_32 (output_bfd,
02115 0x10f80000
02116 | ((entry->tlsoff_entry >> 16)
02117 & (((bfd_vma)1 << 16) - 1)),
02118 plt_code);
02119 plt_code += 4;
02120 bfd_put_32 (output_bfd,
02121 0x90f40000
02122 | (entry->tlsoff_entry
02123 & (((bfd_vma)1 << 16) - 1)),
02124 plt_code);
02125 plt_code += 4;
02126 }
02127
02128 bfd_put_32 (output_bfd, 0x9008f108, plt_code);
02129 plt_code += 4;
02130 }
02131
02132 bfd_put_32 (output_bfd, 0xc03a4000, plt_code);
02133 }
02134 else
02135 {
02136 BFD_ASSERT (entry->tlsdesc_entry);
02137
02138
02139
02140 if (entry->tlsdesc_entry >= -(1 << (12 - 1))
02141 && entry->tlsdesc_entry < (1 << (12 - 1)))
02142 {
02143
02144 bfd_put_32 (output_bfd,
02145 0x90ccf000 | (entry->tlsdesc_entry
02146 & ((1 << 12) - 1)),
02147 plt_code);
02148 plt_code += 4;
02149 }
02150 else
02151 {
02152 if (entry->tlsdesc_entry >= -(1 << (16 - 1))
02153 && entry->tlsdesc_entry < (1 << (16 - 1)))
02154 {
02155
02156 bfd_put_32 (output_bfd,
02157 0x90fc0000
02158 | (entry->tlsdesc_entry
02159 & (((bfd_vma)1 << 16) - 1)),
02160 plt_code);
02161 plt_code += 4;
02162 }
02163 else
02164 {
02165
02166
02167 bfd_put_32 (output_bfd,
02168 0x10f80000
02169 | ((entry->tlsdesc_entry >> 16)
02170 & (((bfd_vma)1 << 16) - 1)),
02171 plt_code);
02172 plt_code += 4;
02173 bfd_put_32 (output_bfd,
02174 0x90f40000
02175 | (entry->tlsdesc_entry
02176 & (((bfd_vma)1 << 16) - 1)),
02177 plt_code);
02178 plt_code += 4;
02179 }
02180
02181 bfd_put_32 (output_bfd, 0x9008f148, plt_code);
02182 plt_code += 4;
02183 }
02184
02185 bfd_put_32 (output_bfd, 0x80308000, plt_code);
02186 }
02187 }
02188
02189 return TRUE;
02190 }
02191
02192
02193
02194 static bfd_reloc_status_type
02195 elf32_frv_relocate_gprel12 (info, input_bfd, input_section, relocation,
02196 contents, value)
02197 struct bfd_link_info *info;
02198 bfd *input_bfd;
02199 asection *input_section;
02200 Elf_Internal_Rela *relocation;
02201 bfd_byte *contents;
02202 bfd_vma value;
02203 {
02204 bfd_vma insn;
02205 bfd_vma gp;
02206 struct bfd_link_hash_entry *h;
02207
02208 h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
02209
02210 gp = (h->u.def.value
02211 + h->u.def.section->output_section->vma
02212 + h->u.def.section->output_offset);
02213
02214 value -= input_section->output_section->vma;
02215 value -= (gp - input_section->output_section->vma);
02216
02217 insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
02218
02219 value += relocation->r_addend;
02220
02221 if ((long) value > 0x7ff || (long) value < -0x800)
02222 return bfd_reloc_overflow;
02223
02224 bfd_put_32 (input_bfd,
02225 (insn & 0xfffff000) | (value & 0xfff),
02226 contents + relocation->r_offset);
02227
02228 return bfd_reloc_ok;
02229 }
02230
02231
02232
02233 static bfd_reloc_status_type
02234 elf32_frv_relocate_gprelu12 (info, input_bfd, input_section, relocation,
02235 contents, value)
02236 struct bfd_link_info *info;
02237 bfd *input_bfd;
02238 asection *input_section;
02239 Elf_Internal_Rela *relocation;
02240 bfd_byte *contents;
02241 bfd_vma value;
02242 {
02243 bfd_vma insn;
02244 bfd_vma gp;
02245 struct bfd_link_hash_entry *h;
02246 bfd_vma mask;
02247
02248 h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
02249
02250 gp = (h->u.def.value
02251 + h->u.def.section->output_section->vma
02252 + h->u.def.section->output_offset);
02253
02254 value -= input_section->output_section->vma;
02255 value -= (gp - input_section->output_section->vma);
02256
02257 insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
02258
02259 value += relocation->r_addend;
02260
02261 if ((long) value > 0x7ff || (long) value < -0x800)
02262 return bfd_reloc_overflow;
02263
02264
02265 mask = 0x3f03f;
02266 insn = (insn & ~mask) | ((value & 0xfc0) << 12) | (value & 0x3f);
02267
02268 bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
02269
02270 return bfd_reloc_ok;
02271 }
02272
02273
02274
02275 static bfd_reloc_status_type
02276 elf32_frv_relocate_hi16 (input_bfd, relhi, contents, value)
02277 bfd *input_bfd;
02278 Elf_Internal_Rela *relhi;
02279 bfd_byte *contents;
02280 bfd_vma value;
02281 {
02282 bfd_vma insn;
02283
02284 insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
02285
02286 value += relhi->r_addend;
02287 value = ((value >> 16) & 0xffff);
02288
02289 insn = (insn & 0xffff0000) | value;
02290
02291 if ((long) value > 0xffff || (long) value < -0x10000)
02292 return bfd_reloc_overflow;
02293
02294 bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
02295 return bfd_reloc_ok;
02296
02297 }
02298 static bfd_reloc_status_type
02299 elf32_frv_relocate_lo16 (input_bfd, rello, contents, value)
02300 bfd *input_bfd;
02301 Elf_Internal_Rela *rello;
02302 bfd_byte *contents;
02303 bfd_vma value;
02304 {
02305 bfd_vma insn;
02306
02307 insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
02308
02309 value += rello->r_addend;
02310 value = value & 0xffff;
02311
02312 insn = (insn & 0xffff0000) | value;
02313
02314 if ((long) value > 0xffff || (long) value < -0x10000)
02315 return bfd_reloc_overflow;
02316
02317 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
02318 return bfd_reloc_ok;
02319 }
02320
02321
02322
02323 static bfd_reloc_status_type
02324 elf32_frv_relocate_label24 (input_bfd, input_section, rello, contents, value)
02325 bfd *input_bfd;
02326 asection *input_section;
02327 Elf_Internal_Rela *rello;
02328 bfd_byte *contents;
02329 bfd_vma value;
02330 {
02331 bfd_vma insn;
02332 bfd_vma label6;
02333 bfd_vma label18;
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344 insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
02345
02346 value -= input_section->output_section->vma + input_section->output_offset;
02347 value -= rello->r_offset;
02348 value += rello->r_addend;
02349
02350 value = value >> 2;
02351
02352 label6 = value & 0xfc0000;
02353 label6 = label6 << 7;
02354
02355 label18 = value & 0x3ffff;
02356
02357 insn = insn & 0x803c0000;
02358 insn = insn | label6;
02359 insn = insn | label18;
02360
02361 bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
02362
02363 return bfd_reloc_ok;
02364 }
02365
02366 static bfd_reloc_status_type
02367 elf32_frv_relocate_gprelhi (info, input_bfd, input_section, relocation,
02368 contents, value)
02369 struct bfd_link_info *info;
02370 bfd *input_bfd;
02371 asection *input_section;
02372 Elf_Internal_Rela *relocation;
02373 bfd_byte *contents;
02374 bfd_vma value;
02375 {
02376 bfd_vma insn;
02377 bfd_vma gp;
02378 struct bfd_link_hash_entry *h;
02379
02380 h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
02381
02382 gp = (h->u.def.value
02383 + h->u.def.section->output_section->vma
02384 + h->u.def.section->output_offset);
02385
02386 value -= input_section->output_section->vma;
02387 value -= (gp - input_section->output_section->vma);
02388 value += relocation->r_addend;
02389 value = ((value >> 16) & 0xffff);
02390
02391 if ((long) value > 0xffff || (long) value < -0x10000)
02392 return bfd_reloc_overflow;
02393
02394 insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
02395 insn = (insn & 0xffff0000) | value;
02396
02397 bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
02398 return bfd_reloc_ok;
02399 }
02400
02401 static bfd_reloc_status_type
02402 elf32_frv_relocate_gprello (info, input_bfd, input_section, relocation,
02403 contents, value)
02404 struct bfd_link_info *info;
02405 bfd *input_bfd;
02406 asection *input_section;
02407 Elf_Internal_Rela *relocation;
02408 bfd_byte *contents;
02409 bfd_vma value;
02410 {
02411 bfd_vma insn;
02412 bfd_vma gp;
02413 struct bfd_link_hash_entry *h;
02414
02415 h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
02416
02417 gp = (h->u.def.value
02418 + h->u.def.section->output_section->vma
02419 + h->u.def.section->output_offset);
02420
02421 value -= input_section->output_section->vma;
02422 value -= (gp - input_section->output_section->vma);
02423 value += relocation->r_addend;
02424 value = value & 0xffff;
02425
02426 if ((long) value > 0xffff || (long) value < -0x10000)
02427 return bfd_reloc_overflow;
02428
02429 insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
02430 insn = (insn & 0xffff0000) | value;
02431
02432 bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
02433
02434 return bfd_reloc_ok;
02435 }
02436
02437 static reloc_howto_type *
02438 frv_reloc_type_lookup (abfd, code)
02439 bfd *abfd ATTRIBUTE_UNUSED;
02440 bfd_reloc_code_real_type code;
02441 {
02442 switch (code)
02443 {
02444 default:
02445 break;
02446
02447 case BFD_RELOC_NONE:
02448 return &elf32_frv_howto_table[ (int) R_FRV_NONE];
02449
02450 case BFD_RELOC_32:
02451 if (elf_elfheader (abfd)->e_type == ET_EXEC
02452 || elf_elfheader (abfd)->e_type == ET_DYN)
02453 return &elf32_frv_rel_32_howto;
02454
02455 case BFD_RELOC_CTOR:
02456 return &elf32_frv_howto_table[ (int) R_FRV_32];
02457
02458 case BFD_RELOC_FRV_LABEL16:
02459 return &elf32_frv_howto_table[ (int) R_FRV_LABEL16];
02460
02461 case BFD_RELOC_FRV_LABEL24:
02462 return &elf32_frv_howto_table[ (int) R_FRV_LABEL24];
02463
02464 case BFD_RELOC_FRV_LO16:
02465 return &elf32_frv_howto_table[ (int) R_FRV_LO16];
02466
02467 case BFD_RELOC_FRV_HI16:
02468 return &elf32_frv_howto_table[ (int) R_FRV_HI16];
02469
02470 case BFD_RELOC_FRV_GPREL12:
02471 return &elf32_frv_howto_table[ (int) R_FRV_GPREL12];
02472
02473 case BFD_RELOC_FRV_GPRELU12:
02474 return &elf32_frv_howto_table[ (int) R_FRV_GPRELU12];
02475
02476 case BFD_RELOC_FRV_GPREL32:
02477 return &elf32_frv_howto_table[ (int) R_FRV_GPREL32];
02478
02479 case BFD_RELOC_FRV_GPRELHI:
02480 return &elf32_frv_howto_table[ (int) R_FRV_GPRELHI];
02481
02482 case BFD_RELOC_FRV_GPRELLO:
02483 return &elf32_frv_howto_table[ (int) R_FRV_GPRELLO];
02484
02485 case BFD_RELOC_FRV_GOT12:
02486 return &elf32_frv_howto_table[ (int) R_FRV_GOT12];
02487
02488 case BFD_RELOC_FRV_GOTHI:
02489 return &elf32_frv_howto_table[ (int) R_FRV_GOTHI];
02490
02491 case BFD_RELOC_FRV_GOTLO:
02492 return &elf32_frv_howto_table[ (int) R_FRV_GOTLO];
02493
02494 case BFD_RELOC_FRV_FUNCDESC:
02495 if (elf_elfheader (abfd)->e_type == ET_EXEC
02496 || elf_elfheader (abfd)->e_type == ET_DYN)
02497 return &elf32_frv_rel_funcdesc_howto;
02498 return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC];
02499
02500 case BFD_RELOC_FRV_FUNCDESC_GOT12:
02501 return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOT12];
02502
02503 case BFD_RELOC_FRV_FUNCDESC_GOTHI:
02504 return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOTHI];
02505
02506 case BFD_RELOC_FRV_FUNCDESC_GOTLO:
02507 return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOTLO];
02508
02509 case BFD_RELOC_FRV_FUNCDESC_VALUE:
02510 if (elf_elfheader (abfd)->e_type == ET_EXEC
02511 || elf_elfheader (abfd)->e_type == ET_DYN)
02512 return &elf32_frv_rel_funcdesc_value_howto;
02513 return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_VALUE];
02514
02515 case BFD_RELOC_FRV_FUNCDESC_GOTOFF12:
02516 return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOTOFF12];
02517
02518 case BFD_RELOC_FRV_FUNCDESC_GOTOFFHI:
02519 return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOTOFFHI];
02520
02521 case BFD_RELOC_FRV_FUNCDESC_GOTOFFLO:
02522 return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOTOFFLO];
02523
02524 case BFD_RELOC_FRV_GOTOFF12:
02525 return &elf32_frv_howto_table[ (int) R_FRV_GOTOFF12];
02526
02527 case BFD_RELOC_FRV_GOTOFFHI:
02528 return &elf32_frv_howto_table[ (int) R_FRV_GOTOFFHI];
02529
02530 case BFD_RELOC_FRV_GOTOFFLO:
02531 return &elf32_frv_howto_table[ (int) R_FRV_GOTOFFLO];
02532
02533 case BFD_RELOC_FRV_GETTLSOFF:
02534 return &elf32_frv_howto_table[ (int) R_FRV_GETTLSOFF];
02535
02536 case BFD_RELOC_FRV_TLSDESC_VALUE:
02537 if (elf_elfheader (abfd)->e_type == ET_EXEC
02538 || elf_elfheader (abfd)->e_type == ET_DYN)
02539 return &elf32_frv_rel_tlsdesc_value_howto;
02540 return &elf32_frv_howto_table[ (int) R_FRV_TLSDESC_VALUE];
02541
02542 case BFD_RELOC_FRV_GOTTLSDESC12:
02543 return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSDESC12];
02544
02545 case BFD_RELOC_FRV_GOTTLSDESCHI:
02546 return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSDESCHI];
02547
02548 case BFD_RELOC_FRV_GOTTLSDESCLO:
02549 return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSDESCLO];
02550
02551 case BFD_RELOC_FRV_TLSMOFF12:
02552 return &elf32_frv_howto_table[ (int) R_FRV_TLSMOFF12];
02553
02554 case BFD_RELOC_FRV_TLSMOFFHI:
02555 return &elf32_frv_howto_table[ (int) R_FRV_TLSMOFFHI];
02556
02557 case BFD_RELOC_FRV_TLSMOFFLO:
02558 return &elf32_frv_howto_table[ (int) R_FRV_TLSMOFFLO];
02559
02560 case BFD_RELOC_FRV_GOTTLSOFF12:
02561 return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSOFF12];
02562
02563 case BFD_RELOC_FRV_GOTTLSOFFHI:
02564 return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSOFFHI];
02565
02566 case BFD_RELOC_FRV_GOTTLSOFFLO:
02567 return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSOFFLO];
02568
02569 case BFD_RELOC_FRV_TLSOFF:
02570 if (elf_elfheader (abfd)->e_type == ET_EXEC
02571 || elf_elfheader (abfd)->e_type == ET_DYN)
02572 return &elf32_frv_rel_tlsoff_howto;
02573 return &elf32_frv_howto_table[ (int) R_FRV_TLSOFF];
02574
02575 case BFD_RELOC_FRV_TLSDESC_RELAX:
02576 return &elf32_frv_howto_table[ (int) R_FRV_TLSDESC_RELAX];
02577
02578 case BFD_RELOC_FRV_GETTLSOFF_RELAX:
02579 return &elf32_frv_howto_table[ (int) R_FRV_GETTLSOFF_RELAX];
02580
02581 case BFD_RELOC_FRV_TLSOFF_RELAX:
02582 return &elf32_frv_howto_table[ (int) R_FRV_TLSOFF_RELAX];
02583
02584 case BFD_RELOC_FRV_TLSMOFF:
02585 return &elf32_frv_howto_table[ (int) R_FRV_TLSMOFF];
02586
02587 case BFD_RELOC_VTABLE_INHERIT:
02588 return &elf32_frv_vtinherit_howto;
02589
02590 case BFD_RELOC_VTABLE_ENTRY:
02591 return &elf32_frv_vtentry_howto;
02592 }
02593
02594 return NULL;
02595 }
02596
02597
02598
02599 static void
02600 frv_info_to_howto_rela (abfd, cache_ptr, dst)
02601 bfd *abfd ATTRIBUTE_UNUSED;
02602 arelent *cache_ptr;
02603 Elf_Internal_Rela *dst;
02604 {
02605 unsigned int r_type;
02606
02607 r_type = ELF32_R_TYPE (dst->r_info);
02608 switch (r_type)
02609 {
02610 case R_FRV_GNU_VTINHERIT:
02611 cache_ptr->howto = &elf32_frv_vtinherit_howto;
02612 break;
02613
02614 case R_FRV_GNU_VTENTRY:
02615 cache_ptr->howto = &elf32_frv_vtentry_howto;
02616 break;
02617
02618 default:
02619 cache_ptr->howto = & elf32_frv_howto_table [r_type];
02620 break;
02621 }
02622 }
02623
02624
02625 static void
02626 frvfdpic_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
02627 arelent *cache_ptr, Elf_Internal_Rela *dst)
02628 {
02629 unsigned int r_type;
02630
02631 r_type = ELF32_R_TYPE (dst->r_info);
02632 switch (r_type)
02633 {
02634 case R_FRV_32:
02635 cache_ptr->howto = &elf32_frv_rel_32_howto;
02636 break;
02637
02638 case R_FRV_FUNCDESC:
02639 cache_ptr->howto = &elf32_frv_rel_funcdesc_howto;
02640 break;
02641
02642 case R_FRV_FUNCDESC_VALUE:
02643 cache_ptr->howto = &elf32_frv_rel_funcdesc_value_howto;
02644 break;
02645
02646 case R_FRV_TLSDESC_VALUE:
02647 cache_ptr->howto = &elf32_frv_rel_tlsdesc_value_howto;
02648 break;
02649
02650 case R_FRV_TLSOFF:
02651 cache_ptr->howto = &elf32_frv_rel_tlsoff_howto;
02652 break;
02653
02654 default:
02655 cache_ptr->howto = NULL;
02656 break;
02657 }
02658 }
02659
02660
02661
02662
02663 static bfd_reloc_status_type
02664 frv_final_link_relocate (howto, input_bfd, input_section, contents, rel,
02665 relocation)
02666 reloc_howto_type *howto;
02667 bfd *input_bfd;
02668 asection *input_section;
02669 bfd_byte *contents;
02670 Elf_Internal_Rela *rel;
02671 bfd_vma relocation;
02672 {
02673 return _bfd_final_link_relocate (howto, input_bfd, input_section,
02674 contents, rel->r_offset, relocation,
02675 rel->r_addend);
02676 }
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709 static bfd_boolean
02710 elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
02711 contents, relocs, local_syms, local_sections)
02712 bfd *output_bfd ATTRIBUTE_UNUSED;
02713 struct bfd_link_info *info;
02714 bfd *input_bfd;
02715 asection *input_section;
02716 bfd_byte *contents;
02717 Elf_Internal_Rela *relocs;
02718 Elf_Internal_Sym *local_syms;
02719 asection **local_sections;
02720 {
02721 Elf_Internal_Shdr *symtab_hdr;
02722 struct elf_link_hash_entry **sym_hashes;
02723 Elf_Internal_Rela *rel;
02724 Elf_Internal_Rela *relend;
02725 unsigned isec_segment, got_segment, plt_segment, gprel_segment, tls_segment,
02726 check_segment[2];
02727 int silence_segment_error = !(info->shared || info->pie);
02728 unsigned long insn;
02729
02730 if (info->relocatable)
02731 return TRUE;
02732
02733 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
02734 sym_hashes = elf_sym_hashes (input_bfd);
02735 relend = relocs + input_section->reloc_count;
02736
02737 isec_segment = _frvfdpic_osec_to_segment (output_bfd,
02738 input_section->output_section);
02739 if (IS_FDPIC (output_bfd) && frvfdpic_got_section (info))
02740 got_segment = _frvfdpic_osec_to_segment (output_bfd,
02741 frvfdpic_got_section (info)
02742 ->output_section);
02743 else
02744 got_segment = -1;
02745 if (IS_FDPIC (output_bfd) && frvfdpic_gotfixup_section (info))
02746 gprel_segment = _frvfdpic_osec_to_segment (output_bfd,
02747 frvfdpic_gotfixup_section (info)
02748 ->output_section);
02749 else
02750 gprel_segment = -1;
02751 if (IS_FDPIC (output_bfd) && frvfdpic_plt_section (info))
02752 plt_segment = _frvfdpic_osec_to_segment (output_bfd,
02753 frvfdpic_plt_section (info)
02754 ->output_section);
02755 else
02756 plt_segment = -1;
02757 if (elf_hash_table (info)->tls_sec)
02758 tls_segment = _frvfdpic_osec_to_segment (output_bfd,
02759 elf_hash_table (info)->tls_sec);
02760 else
02761 tls_segment = -1;
02762
02763 for (rel = relocs; rel < relend; rel ++)
02764 {
02765 reloc_howto_type *howto;
02766 unsigned long r_symndx;
02767 Elf_Internal_Sym *sym;
02768 asection *sec;
02769 struct elf_link_hash_entry *h;
02770 bfd_vma relocation;
02771 bfd_reloc_status_type r;
02772 const char * name = NULL;
02773 int r_type;
02774 asection *osec;
02775 struct frvfdpic_relocs_info *picrel;
02776 bfd_vma orig_addend = rel->r_addend;
02777
02778 r_type = ELF32_R_TYPE (rel->r_info);
02779
02780 if ( r_type == R_FRV_GNU_VTINHERIT
02781 || r_type == R_FRV_GNU_VTENTRY)
02782 continue;
02783
02784
02785 r_symndx = ELF32_R_SYM (rel->r_info);
02786 howto = elf32_frv_howto_table + ELF32_R_TYPE (rel->r_info);
02787 h = NULL;
02788 sym = NULL;
02789 sec = NULL;
02790
02791 if (r_symndx < symtab_hdr->sh_info)
02792 {
02793 sym = local_syms + r_symndx;
02794 osec = sec = local_sections [r_symndx];
02795 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
02796
02797 name = bfd_elf_string_from_elf_section
02798 (input_bfd, symtab_hdr->sh_link, sym->st_name);
02799 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
02800 }
02801 else
02802 {
02803 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
02804
02805 while (h->root.type == bfd_link_hash_indirect
02806 || h->root.type == bfd_link_hash_warning)
02807 h = (struct elf_link_hash_entry *) h->root.u.i.link;
02808
02809 name = h->root.root.string;
02810
02811 if ((h->root.type == bfd_link_hash_defined
02812 || h->root.type == bfd_link_hash_defweak))
02813 {
02814 if (
02815 r_type != R_FRV_TLSMOFF
02816 && ! FRVFDPIC_SYM_LOCAL (info, h))
02817 {
02818 sec = NULL;
02819 relocation = 0;
02820 }
02821 else
02822 {
02823 sec = h->root.u.def.section;
02824 relocation = (h->root.u.def.value
02825 + sec->output_section->vma
02826 + sec->output_offset);
02827 }
02828 }
02829 else if (h->root.type == bfd_link_hash_undefweak)
02830 {
02831 relocation = 0;
02832 }
02833 else if (info->unresolved_syms_in_objects == RM_IGNORE
02834 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
02835 relocation = 0;
02836 else
02837 {
02838 if (! ((*info->callbacks->undefined_symbol)
02839 (info, h->root.root.string, input_bfd,
02840 input_section, rel->r_offset,
02841 (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
02842 || ELF_ST_VISIBILITY (h->other)))))
02843 return FALSE;
02844 relocation = 0;
02845 }
02846 osec = sec;
02847 }
02848
02849 switch (r_type)
02850 {
02851 case R_FRV_LABEL24:
02852 case R_FRV_32:
02853 if (! IS_FDPIC (output_bfd))
02854 goto non_fdpic;
02855
02856 case R_FRV_GOT12:
02857 case R_FRV_GOTHI:
02858 case R_FRV_GOTLO:
02859 case R_FRV_FUNCDESC_GOT12:
02860 case R_FRV_FUNCDESC_GOTHI:
02861 case R_FRV_FUNCDESC_GOTLO:
02862 case R_FRV_GOTOFF12:
02863 case R_FRV_GOTOFFHI:
02864 case R_FRV_GOTOFFLO:
02865 case R_FRV_FUNCDESC_GOTOFF12:
02866 case R_FRV_FUNCDESC_GOTOFFHI:
02867 case R_FRV_FUNCDESC_GOTOFFLO:
02868 case R_FRV_FUNCDESC:
02869 case R_FRV_FUNCDESC_VALUE:
02870 case R_FRV_GETTLSOFF:
02871 case R_FRV_TLSDESC_VALUE:
02872 case R_FRV_GOTTLSDESC12:
02873 case R_FRV_GOTTLSDESCHI:
02874 case R_FRV_GOTTLSDESCLO:
02875 case R_FRV_TLSMOFF12:
02876 case R_FRV_TLSMOFFHI:
02877 case R_FRV_TLSMOFFLO:
02878 case R_FRV_GOTTLSOFF12:
02879 case R_FRV_GOTTLSOFFHI:
02880 case R_FRV_GOTTLSOFFLO:
02881 case R_FRV_TLSOFF:
02882 case R_FRV_TLSDESC_RELAX:
02883 case R_FRV_GETTLSOFF_RELAX:
02884 case R_FRV_TLSOFF_RELAX:
02885 case R_FRV_TLSMOFF:
02886 if (h != NULL)
02887 picrel = frvfdpic_relocs_info_for_global (frvfdpic_relocs_info
02888 (info), input_bfd, h,
02889 orig_addend, INSERT);
02890 else
02891
02892
02893
02894 picrel = frvfdpic_relocs_info_for_local (frvfdpic_relocs_info
02895 (info), input_bfd, r_symndx,
02896 orig_addend, INSERT);
02897 if (! picrel)
02898 return FALSE;
02899
02900 if (!_frvfdpic_emit_got_relocs_plt_entries (picrel, output_bfd, info,
02901 osec, sym,
02902 rel->r_addend))
02903 {
02904 (*_bfd_error_handler)
02905 (_("%B(%A+0x%x): relocation to `%s+%x' may have caused the error above"),
02906 input_bfd, input_section, rel->r_offset, name, rel->r_addend);
02907 return FALSE;
02908 }
02909
02910 break;
02911
02912 default:
02913 non_fdpic:
02914 picrel = NULL;
02915 if (h && ! FRVFDPIC_SYM_LOCAL (info, h))
02916 {
02917 info->callbacks->warning
02918 (info, _("relocation references symbol not defined in the module"),
02919 name, input_bfd, input_section, rel->r_offset);
02920 return FALSE;
02921 }
02922 break;
02923 }
02924
02925 switch (r_type)
02926 {
02927 case R_FRV_GETTLSOFF:
02928 case R_FRV_TLSDESC_VALUE:
02929 case R_FRV_GOTTLSDESC12:
02930 case R_FRV_GOTTLSDESCHI:
02931 case R_FRV_GOTTLSDESCLO:
02932 case R_FRV_TLSMOFF12:
02933 case R_FRV_TLSMOFFHI:
02934 case R_FRV_TLSMOFFLO:
02935 case R_FRV_GOTTLSOFF12:
02936 case R_FRV_GOTTLSOFFHI:
02937 case R_FRV_GOTTLSOFFLO:
02938 case R_FRV_TLSOFF:
02939 case R_FRV_TLSDESC_RELAX:
02940 case R_FRV_GETTLSOFF_RELAX:
02941 case R_FRV_TLSOFF_RELAX:
02942 case R_FRV_TLSMOFF:
02943 if (sec && (bfd_is_abs_section (sec) || bfd_is_und_section (sec)))
02944 relocation += tls_biased_base (info);
02945 break;
02946
02947 default:
02948 break;
02949 }
02950
02951
02952 if (1)
02953 switch (r_type)
02954 {
02955
02956 #define LOCAL_EXEC_P(info, picrel) \
02957 ((info)->executable \
02958 && (picrel->symndx != -1 || FRVFDPIC_SYM_LOCAL ((info), (picrel)->d.h)))
02959 #define INITIAL_EXEC_P(info, picrel) \
02960 (((info)->executable || (info)->flags & DF_STATIC_TLS) \
02961 && (picrel)->tlsoff_entry)
02962
02963 #define IN_RANGE_FOR_OFST12_P(value) \
02964 ((bfd_vma)((value) + 2048) < (bfd_vma)4096)
02965 #define IN_RANGE_FOR_SETLOS_P(value) \
02966 ((bfd_vma)((value) + 32768) < (bfd_vma)65536)
02967 #define TLSMOFF_IN_RANGE_FOR_SETLOS_P(value, info) \
02968 (IN_RANGE_FOR_SETLOS_P ((value) - tls_biased_base (info)))
02969
02970 #define RELAX_GETTLSOFF_LOCAL_EXEC_P(info, picrel, value) \
02971 (LOCAL_EXEC_P ((info), (picrel)) \
02972 && TLSMOFF_IN_RANGE_FOR_SETLOS_P((value), (info)))
02973 #define RELAX_GETTLSOFF_INITIAL_EXEC_P(info, picrel) \
02974 (INITIAL_EXEC_P ((info), (picrel)) \
02975 && IN_RANGE_FOR_OFST12_P ((picrel)->tlsoff_entry))
02976
02977 #define RELAX_TLSDESC_LOCAL_EXEC_P(info, picrel, value) \
02978 (LOCAL_EXEC_P ((info), (picrel)))
02979 #define RELAX_TLSDESC_INITIAL_EXEC_P(info, picrel) \
02980 (INITIAL_EXEC_P ((info), (picrel)))
02981
02982 #define RELAX_GOTTLSOFF_LOCAL_EXEC_P(info, picrel, value) \
02983 (LOCAL_EXEC_P ((info), (picrel)) \
02984 && TLSMOFF_IN_RANGE_FOR_SETLOS_P((value), (info)))
02985
02986 case R_FRV_GETTLSOFF:
02987 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
02988
02989
02990 if ((insn & (unsigned long)0x01fc0000) != 0x003c0000)
02991 {
02992 r = info->callbacks->warning
02993 (info,
02994 _("R_FRV_GETTLSOFF not applied to a call instruction"),
02995 name, input_bfd, input_section, rel->r_offset);
02996 return FALSE;
02997 }
02998
02999 if (RELAX_GETTLSOFF_LOCAL_EXEC_P (info, picrel,
03000 relocation + rel->r_addend))
03001 {
03002
03003
03004 insn &= (unsigned long)0x80000000;
03005 insn |= (unsigned long)0x12fc0000;
03006 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03007
03008 r_type = R_FRV_TLSMOFFLO;
03009 howto = elf32_frv_howto_table + r_type;
03010 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03011 }
03012
03013 else if (RELAX_GETTLSOFF_INITIAL_EXEC_P (info, picrel))
03014 {
03015
03016
03017 insn &= (unsigned long)0x80000000;
03018 insn |= (unsigned long)0x12c8f000;
03019 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03020
03021 r_type = R_FRV_GOTTLSOFF12;
03022 howto = elf32_frv_howto_table + r_type;
03023 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03024 }
03025
03026 break;
03027
03028 case R_FRV_GOTTLSDESC12:
03029 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03030
03031
03032 if ((insn & (unsigned long)0x01fc0000) != 0x00cc0000)
03033 {
03034 r = info->callbacks->warning
03035 (info,
03036 _("R_FRV_GOTTLSDESC12 not applied to an lddi instruction"),
03037 name, input_bfd, input_section, rel->r_offset);
03038 return FALSE;
03039 }
03040
03041 if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
03042 relocation + rel->r_addend)
03043 && TLSMOFF_IN_RANGE_FOR_SETLOS_P (relocation + rel->r_addend,
03044 info))
03045 {
03046
03047
03048
03049 insn = (insn & (unsigned long)0x80000000)
03050 | ((insn + (unsigned long)0x02000000)
03051 & (unsigned long)0x7e000000);
03052 insn |= (unsigned long)0x00fc0000;
03053 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03054
03055 r_type = R_FRV_TLSMOFFLO;
03056 howto = elf32_frv_howto_table + r_type;
03057 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03058 }
03059
03060 else if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
03061 relocation + rel->r_addend))
03062 {
03063
03064
03065
03066 insn = (insn & (unsigned long)0x80000000)
03067 | ((insn + (unsigned long)0x02000000)
03068 & (unsigned long)0x7e000000);
03069 insn |= (unsigned long)0x00f80000;
03070 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03071
03072 r_type = R_FRV_TLSMOFFHI;
03073 howto = elf32_frv_howto_table + r_type;
03074 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03075 }
03076
03077 else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel))
03078 {
03079
03080
03081
03082
03083
03084
03085
03086
03087 insn = (insn & (unsigned long)0x80cbf000)
03088 | ((insn + (unsigned long)0x02000000)
03089 & (unsigned long)0x7e000000);
03090 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03091
03092 r_type = R_FRV_GOTTLSOFF12;
03093 howto = elf32_frv_howto_table + r_type;
03094 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03095 }
03096
03097 break;
03098
03099 case R_FRV_GOTTLSDESCHI:
03100 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03101
03102
03103 if ((insn & (unsigned long)0x01ff0000) != 0x00f80000)
03104 {
03105 r = info->callbacks->warning
03106 (info,
03107 _("R_FRV_GOTTLSDESCHI not applied to a sethi instruction"),
03108 name, input_bfd, input_section, rel->r_offset);
03109 return FALSE;
03110 }
03111
03112 if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
03113 relocation + rel->r_addend)
03114 || (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
03115 && IN_RANGE_FOR_SETLOS_P (picrel->tlsoff_entry)))
03116 {
03117
03118 insn &= (unsigned long)0x80000000;
03119 insn |= (unsigned long)0x00880000;
03120 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03121
03122
03123 continue;
03124 }
03125
03126 else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel))
03127 {
03128
03129 r_type = R_FRV_GOTTLSOFFHI;
03130 howto = elf32_frv_howto_table + r_type;
03131 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03132 }
03133
03134 break;
03135
03136 case R_FRV_GOTTLSDESCLO:
03137 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03138
03139
03140 if ((insn & (unsigned long)0x01f70000) != 0x00f40000)
03141 {
03142 r = info->callbacks->warning
03143 (info,
03144 _("R_FRV_GOTTLSDESCLO"
03145 " not applied to a setlo or setlos instruction"),
03146 name, input_bfd, input_section, rel->r_offset);
03147 return FALSE;
03148 }
03149
03150 if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
03151 relocation + rel->r_addend)
03152 || (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
03153 && IN_RANGE_FOR_OFST12_P (picrel->tlsoff_entry)))
03154 {
03155
03156
03157 insn &= (unsigned long)0x80000000;
03158 insn |= (unsigned long)0x00880000;
03159 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03160
03161
03162 continue;
03163 }
03164
03165 else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel))
03166 {
03167
03168
03169
03170 if (IN_RANGE_FOR_SETLOS_P (picrel->tlsoff_entry))
03171 {
03172 insn |= (unsigned long)0x00080000;
03173 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03174 }
03175
03176
03177 r_type = R_FRV_GOTTLSOFFLO;
03178 howto = elf32_frv_howto_table + r_type;
03179 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03180 }
03181
03182 break;
03183
03184 case R_FRV_TLSDESC_RELAX:
03185 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03186
03187
03188 if ((insn & (unsigned long)0x01fc0fc0) != 0x00080140)
03189 {
03190 r = info->callbacks->warning
03191 (info,
03192 _("R_FRV_TLSDESC_RELAX not applied to an ldd instruction"),
03193 name, input_bfd, input_section, rel->r_offset);
03194 return FALSE;
03195 }
03196
03197 if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
03198 relocation + rel->r_addend)
03199 && TLSMOFF_IN_RANGE_FOR_SETLOS_P (relocation + rel->r_addend,
03200 info))
03201 {
03202
03203
03204
03205 insn = (insn & (unsigned long)0x80000000)
03206 | ((insn + (unsigned long)0x02000000)
03207 & (unsigned long)0x7e000000);
03208 insn |= (unsigned long)0x00fc0000;
03209 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03210
03211 r_type = R_FRV_TLSMOFFLO;
03212 howto = elf32_frv_howto_table + r_type;
03213 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03214 }
03215
03216 else if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
03217 relocation + rel->r_addend))
03218 {
03219
03220
03221
03222 insn = (insn & (unsigned long)0x80000000)
03223 | ((insn + (unsigned long)0x02000000)
03224 & (unsigned long)0x7e000000);
03225 insn |= (unsigned long)0x00f80000;
03226 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03227
03228 r_type = R_FRV_TLSMOFFHI;
03229 howto = elf32_frv_howto_table + r_type;
03230 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03231 }
03232
03233 else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
03234 && IN_RANGE_FOR_OFST12_P (picrel->tlsoff_entry))
03235 {
03236
03237
03238
03239 insn = (insn & (unsigned long)0x8003f000)
03240 | (unsigned long)0x00c80000
03241 | ((insn + (unsigned long)0x02000000)
03242 & (unsigned long)0x7e000000);
03243 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03244
03245 r_type = R_FRV_GOTTLSOFF12;
03246 howto = elf32_frv_howto_table + r_type;
03247 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03248 }
03249
03250 else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel))
03251 {
03252
03253
03254
03255 insn = (insn & (unsigned long)0x81ffffbf)
03256 | ((insn + (unsigned long)0x02000000)
03257 & (unsigned long)0x7e000000);
03258 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03259
03260
03261
03262
03263 continue;
03264 }
03265
03266 break;
03267
03268 case R_FRV_GETTLSOFF_RELAX:
03269 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03270
03271
03272 if ((insn & (unsigned long)0x7ff80fc0) != 0x02300000)
03273 {
03274 r = info->callbacks->warning
03275 (info,
03276 _("R_FRV_GETTLSOFF_RELAX"
03277 " not applied to a calll instruction"),
03278 name, input_bfd, input_section, rel->r_offset);
03279 return FALSE;
03280 }
03281
03282 if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
03283 relocation + rel->r_addend)
03284 && TLSMOFF_IN_RANGE_FOR_SETLOS_P (relocation + rel->r_addend,
03285 info))
03286 {
03287
03288 insn &= (unsigned long)0x80000000;
03289 insn |= (unsigned long)0x00880000;
03290 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03291
03292
03293 continue;
03294 }
03295
03296 else if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
03297 relocation + rel->r_addend))
03298 {
03299
03300
03301 insn &= (unsigned long)0x80000000;
03302 insn |= (unsigned long)0x12f40000;
03303 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03304
03305 r_type = R_FRV_TLSMOFFLO;
03306 howto = elf32_frv_howto_table + r_type;
03307 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03308 }
03309
03310 else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel))
03311 {
03312
03313 insn &= (unsigned long)0x80000000;
03314 insn |= (unsigned long)0x00880000;
03315 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03316
03317
03318 continue;
03319 }
03320
03321 break;
03322
03323 case R_FRV_GOTTLSOFF12:
03324 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03325
03326
03327 if ((insn & (unsigned long)0x01fc0000) != 0x00c80000)
03328 {
03329 r = info->callbacks->warning
03330 (info,
03331 _("R_FRV_GOTTLSOFF12 not applied to an ldi instruction"),
03332 name, input_bfd, input_section, rel->r_offset);
03333 return FALSE;
03334 }
03335
03336 if (RELAX_GOTTLSOFF_LOCAL_EXEC_P (info, picrel,
03337 relocation + rel->r_addend))
03338 {
03339
03340
03341
03342 insn &= (unsigned long)0xfe000000;
03343 insn |= (unsigned long)0x00fc0000;
03344 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03345
03346 r_type = R_FRV_TLSMOFFLO;
03347 howto = elf32_frv_howto_table + r_type;
03348 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03349 }
03350
03351 break;
03352
03353 case R_FRV_GOTTLSOFFHI:
03354 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03355
03356
03357 if ((insn & (unsigned long)0x01ff0000) != 0x00f80000)
03358 {
03359 r = info->callbacks->warning
03360 (info,
03361 _("R_FRV_GOTTLSOFFHI not applied to a sethi instruction"),
03362 name, input_bfd, input_section, rel->r_offset);
03363 return FALSE;
03364 }
03365
03366 if (RELAX_GOTTLSOFF_LOCAL_EXEC_P (info, picrel,
03367 relocation + rel->r_addend)
03368 || (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
03369 && IN_RANGE_FOR_OFST12_P (picrel->tlsoff_entry)))
03370 {
03371
03372 insn &= (unsigned long)0x80000000;
03373 insn |= (unsigned long)0x00880000;
03374 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03375
03376
03377 continue;
03378 }
03379
03380 break;
03381
03382 case R_FRV_GOTTLSOFFLO:
03383 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03384
03385
03386 if ((insn & (unsigned long)0x01f70000) != 0x00f40000)
03387 {
03388 r = info->callbacks->warning
03389 (info,
03390 _("R_FRV_GOTTLSOFFLO"
03391 " not applied to a setlo or setlos instruction"),
03392 name, input_bfd, input_section, rel->r_offset);
03393 return FALSE;
03394 }
03395
03396 if (RELAX_GOTTLSOFF_LOCAL_EXEC_P (info, picrel,
03397 relocation + rel->r_addend)
03398 || (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
03399 && IN_RANGE_FOR_OFST12_P (picrel->tlsoff_entry)))
03400 {
03401
03402
03403 insn &= (unsigned long)0x80000000;
03404 insn |= (unsigned long)0x00880000;
03405 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03406
03407
03408 continue;
03409 }
03410
03411 break;
03412
03413 case R_FRV_TLSOFF_RELAX:
03414 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03415
03416
03417 if ((insn & (unsigned long)0x01fc0fc0) != 0x00080100)
03418 {
03419 r = info->callbacks->warning
03420 (info,
03421 _("R_FRV_TLSOFF_RELAX not applied to an ld instruction"),
03422 name, input_bfd, input_section, rel->r_offset);
03423 return FALSE;
03424 }
03425
03426 if (RELAX_GOTTLSOFF_LOCAL_EXEC_P (info, picrel,
03427 relocation + rel->r_addend))
03428 {
03429
03430
03431
03432 insn &= (unsigned long)0xfe000000;
03433 insn |= (unsigned long)0x00fc0000;
03434 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03435
03436 r_type = R_FRV_TLSMOFFLO;
03437 howto = elf32_frv_howto_table + r_type;
03438 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03439 }
03440
03441 else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
03442 && IN_RANGE_FOR_OFST12_P (picrel->tlsoff_entry))
03443 {
03444
03445
03446
03447 insn = (insn & (unsigned long)0xfe03f000)
03448 | (unsigned long)0x00c80000;;
03449 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03450
03451 r_type = R_FRV_GOTTLSOFF12;
03452 howto = elf32_frv_howto_table + r_type;
03453 rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03454 }
03455
03456 break;
03457
03458 case R_FRV_TLSMOFFHI:
03459 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03460
03461
03462 if ((insn & (unsigned long)0x01ff0000) != 0x00f80000)
03463 {
03464 r = info->callbacks->warning
03465 (info,
03466 _("R_FRV_TLSMOFFHI not applied to a sethi instruction"),
03467 name, input_bfd, input_section, rel->r_offset);
03468 return FALSE;
03469 }
03470
03471 if (TLSMOFF_IN_RANGE_FOR_SETLOS_P (relocation + rel->r_addend,
03472 info))
03473 {
03474
03475 insn &= (unsigned long)0x80000000;
03476 insn |= (unsigned long)0x00880000;
03477 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03478
03479
03480 continue;
03481 }
03482
03483 break;
03484
03485 case R_FRV_TLSMOFFLO:
03486 insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03487
03488
03489 if ((insn & (unsigned long)0x01f70000) != 0x00f40000)
03490 {
03491 r = info->callbacks->warning
03492 (info,
03493 _("R_FRV_TLSMOFFLO"
03494 " not applied to a setlo or setlos instruction"),
03495 name, input_bfd, input_section, rel->r_offset);
03496 return FALSE;
03497 }
03498
03499 if (TLSMOFF_IN_RANGE_FOR_SETLOS_P (relocation + rel->r_addend,
03500 info))
03501
03502
03503
03504 {
03505 insn |= (unsigned long)0x00080000;
03506 bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03507 }
03508
03509 break;
03510
03511
03512
03513
03514
03515
03516
03517
03518
03519
03520
03521 default:
03522 break;
03523 }
03524
03525 switch (r_type)
03526 {
03527 case R_FRV_LABEL24:
03528 check_segment[0] = isec_segment;
03529 if (! IS_FDPIC (output_bfd))
03530 check_segment[1] = isec_segment;
03531 else if (picrel->plt)
03532 {
03533 relocation = frvfdpic_plt_section (info)->output_section->vma
03534 + frvfdpic_plt_section (info)->output_offset
03535 + picrel->plt_entry;
03536 check_segment[1] = plt_segment;
03537 }
03538
03539
03540
03541
03542 else if (picrel->symndx == -1
03543 && picrel->d.h->root.type == bfd_link_hash_undefweak)
03544 check_segment[1] = check_segment[0];
03545 else
03546 check_segment[1] = sec
03547 ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
03548 : (unsigned)-1;
03549 break;
03550
03551 case R_FRV_GOT12:
03552 case R_FRV_GOTHI:
03553 case R_FRV_GOTLO:
03554 relocation = picrel->got_entry;
03555 check_segment[0] = check_segment[1] = got_segment;
03556 break;
03557
03558 case R_FRV_FUNCDESC_GOT12:
03559 case R_FRV_FUNCDESC_GOTHI:
03560 case R_FRV_FUNCDESC_GOTLO:
03561 relocation = picrel->fdgot_entry;
03562 check_segment[0] = check_segment[1] = got_segment;
03563 break;
03564
03565 case R_FRV_GOTOFFHI:
03566 case R_FRV_GOTOFF12:
03567 case R_FRV_GOTOFFLO:
03568 relocation -= frvfdpic_got_section (info)->output_section->vma
03569 + frvfdpic_got_section (info)->output_offset
03570 + frvfdpic_got_initial_offset (info);
03571 check_segment[0] = got_segment;
03572 check_segment[1] = sec
03573 ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
03574 : (unsigned)-1;
03575 break;
03576
03577 case R_FRV_FUNCDESC_GOTOFF12:
03578 case R_FRV_FUNCDESC_GOTOFFHI:
03579 case R_FRV_FUNCDESC_GOTOFFLO:
03580 relocation = picrel->fd_entry;
03581 check_segment[0] = check_segment[1] = got_segment;
03582 break;
03583
03584 case R_FRV_FUNCDESC:
03585 {
03586 int dynindx;
03587 bfd_vma addend = rel->r_addend;
03588
03589 if (! (h && h->root.type == bfd_link_hash_undefweak
03590 && FRVFDPIC_SYM_LOCAL (info, h)))
03591 {
03592
03593
03594
03595
03596
03597
03598
03599
03600 if (h && ! FRVFDPIC_FUNCDESC_LOCAL (info, h)
03601 && FRVFDPIC_SYM_LOCAL (info, h)
03602 && !(info->executable && !info->pie))
03603 {
03604 dynindx = elf_section_data (h->root.u.def.section
03605 ->output_section)->dynindx;
03606 addend += h->root.u.def.section->output_offset
03607 + h->root.u.def.value;
03608 }
03609 else if (h && ! FRVFDPIC_FUNCDESC_LOCAL (info, h))
03610 {
03611 if (addend)
03612 {
03613 info->callbacks->warning
03614 (info, _("R_FRV_FUNCDESC references dynamic symbol with nonzero addend"),
03615 name, input_bfd, input_section, rel->r_offset);
03616 return FALSE;
03617 }
03618 dynindx = h->dynindx;
03619 }
03620 else
03621 {
03622
03623
03624 BFD_ASSERT (picrel->privfd);
03625 r_type = R_FRV_32;
03626 dynindx = elf_section_data (frvfdpic_got_section (info)
03627 ->output_section)->dynindx;
03628 addend = frvfdpic_got_section (info)->output_offset
03629 + frvfdpic_got_initial_offset (info)
03630 + picrel->fd_entry;
03631 }
03632
03633
03634
03635
03636
03637
03638
03639 if (info->executable && !info->pie
03640 && (!h || FRVFDPIC_FUNCDESC_LOCAL (info, h)))
03641 {
03642 addend += frvfdpic_got_section (info)->output_section->vma;
03643 if ((bfd_get_section_flags (output_bfd,
03644 input_section->output_section)
03645 & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
03646 {
03647 if (_frvfdpic_osec_readonly_p (output_bfd,
03648 input_section
03649 ->output_section))
03650 {
03651 info->callbacks->warning
03652 (info,
03653 _("cannot emit fixups in read-only section"),
03654 name, input_bfd, input_section, rel->r_offset);
03655 return FALSE;
03656 }
03657 _frvfdpic_add_rofixup (output_bfd,
03658 frvfdpic_gotfixup_section
03659 (info),
03660 _bfd_elf_section_offset
03661 (output_bfd, info,
03662 input_section, rel->r_offset)
03663 + input_section
03664 ->output_section->vma
03665 + input_section->output_offset,
03666 picrel);
03667 }
03668 }
03669 else if ((bfd_get_section_flags (output_bfd,
03670 input_section->output_section)
03671 & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
03672 {
03673 if (_frvfdpic_osec_readonly_p (output_bfd,
03674 input_section
03675 ->output_section))
03676 {
03677 info->callbacks->warning
03678 (info,
03679 _("cannot emit dynamic relocations in read-only section"),
03680 name, input_bfd, input_section, rel->r_offset);
03681 return FALSE;
03682 }
03683 _frvfdpic_add_dyn_reloc (output_bfd,
03684 frvfdpic_gotrel_section (info),
03685 _bfd_elf_section_offset
03686 (output_bfd, info,
03687 input_section, rel->r_offset)
03688 + input_section
03689 ->output_section->vma
03690 + input_section->output_offset,
03691 r_type, dynindx, addend, picrel);
03692 }
03693 else
03694 addend += frvfdpic_got_section (info)->output_section->vma;
03695 }
03696
03697
03698
03699
03700 relocation = addend - rel->r_addend;
03701 }
03702 check_segment[0] = check_segment[1] = got_segment;
03703 break;
03704
03705 case R_FRV_32:
03706 if (! IS_FDPIC (output_bfd))
03707 {
03708 check_segment[0] = check_segment[1] = -1;
03709 break;
03710 }
03711
03712 case R_FRV_FUNCDESC_VALUE:
03713 {
03714 int dynindx;
03715 bfd_vma addend = rel->r_addend;
03716
03717
03718
03719 if (h && ! FRVFDPIC_SYM_LOCAL (info, h))
03720 {
03721 if (addend && r_type == R_FRV_FUNCDESC_VALUE)
03722 {
03723 info->callbacks->warning
03724 (info, _("R_FRV_FUNCDESC_VALUE references dynamic symbol with nonzero addend"),
03725 name, input_bfd, input_section, rel->r_offset);
03726 return FALSE;
03727 }
03728 dynindx = h->dynindx;
03729 }
03730 else
03731 {
03732 if (h)
03733 addend += h->root.u.def.value;
03734 else
03735 addend += sym->st_value;
03736 if (osec)
03737 addend += osec->output_offset;
03738 if (osec && osec->output_section
03739 && ! bfd_is_abs_section (osec->output_section)
03740 && ! bfd_is_und_section (osec->output_section))
03741 dynindx = elf_section_data (osec->output_section)->dynindx;
03742 else
03743 dynindx = 0;
03744 }
03745
03746
03747
03748
03749
03750 if (info->executable && !info->pie
03751 && (!h || FRVFDPIC_SYM_LOCAL (info, h)))
03752 {
03753 if (osec)
03754 addend += osec->output_section->vma;
03755 if (IS_FDPIC (input_bfd)
03756 && (bfd_get_section_flags (output_bfd,
03757 input_section->output_section)
03758 & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
03759 {
03760 if (_frvfdpic_osec_readonly_p (output_bfd,
03761 input_section
03762 ->output_section))
03763 {
03764 info->callbacks->warning
03765 (info,
03766 _("cannot emit fixups in read-only section"),
03767 name, input_bfd, input_section, rel->r_offset);
03768 return FALSE;
03769 }
03770 if (!h || h->root.type != bfd_link_hash_undefweak)
03771 {
03772 _frvfdpic_add_rofixup (output_bfd,
03773 frvfdpic_gotfixup_section
03774 (info),
03775 _bfd_elf_section_offset
03776 (output_bfd, info,
03777 input_section, rel->r_offset)
03778 + input_section
03779 ->output_section->vma
03780 + input_section->output_offset,
03781 picrel);
03782 if (r_type == R_FRV_FUNCDESC_VALUE)
03783 _frvfdpic_add_rofixup
03784 (output_bfd,
03785 frvfdpic_gotfixup_section (info),
03786 _bfd_elf_section_offset
03787 (output_bfd, info,
03788 input_section, rel->r_offset)
03789 + input_section->output_section->vma
03790 + input_section->output_offset + 4, picrel);
03791 }
03792 }
03793 }
03794 else
03795 {
03796 if ((bfd_get_section_flags (output_bfd,
03797 input_section->output_section)
03798 & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
03799 {
03800 if (_frvfdpic_osec_readonly_p (output_bfd,
03801 input_section
03802 ->output_section))
03803 {
03804 info->callbacks->warning
03805 (info,
03806 _("cannot emit dynamic relocations in read-only section"),
03807 name, input_bfd, input_section, rel->r_offset);
03808 return FALSE;
03809 }
03810 _frvfdpic_add_dyn_reloc (output_bfd,
03811 frvfdpic_gotrel_section (info),
03812 _bfd_elf_section_offset
03813 (output_bfd, info,
03814 input_section, rel->r_offset)
03815 + input_section
03816 ->output_section->vma
03817 + input_section->output_offset,
03818 r_type, dynindx, addend, picrel);
03819 }
03820 else if (osec)
03821 addend += osec->output_section->vma;
03822
03823
03824
03825 relocation = addend - rel->r_addend;
03826 }
03827
03828 if (r_type == R_FRV_FUNCDESC_VALUE)
03829 {
03830
03831
03832
03833 if (info->executable && !info->pie
03834 && (!h || FRVFDPIC_SYM_LOCAL (info, h)))
03835 bfd_put_32 (output_bfd,
03836 frvfdpic_got_section (info)->output_section->vma
03837 + frvfdpic_got_section (info)->output_offset
03838 + frvfdpic_got_initial_offset (info),
03839 contents + rel->r_offset + 4);
03840 else
03841
03842
03843
03844
03845
03846
03847 bfd_put_32 (output_bfd,
03848 h && ! FRVFDPIC_SYM_LOCAL (info, h)
03849 ? 0
03850 : _frvfdpic_osec_to_segment (output_bfd,
03851 sec
03852 ->output_section),
03853 contents + rel->r_offset + 4);
03854 }
03855 }
03856 check_segment[0] = check_segment[1] = got_segment;
03857 break;
03858
03859 case R_FRV_GPREL12:
03860 case R_FRV_GPRELU12:
03861 case R_FRV_GPREL32:
03862 case R_FRV_GPRELHI:
03863 case R_FRV_GPRELLO:
03864 check_segment[0] = gprel_segment;
03865 check_segment[1] = sec
03866 ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
03867 : (unsigned)-1;
03868 break;
03869
03870 case R_FRV_GETTLSOFF:
03871 relocation = frvfdpic_plt_section (info)->output_section->vma
03872 + frvfdpic_plt_section (info)->output_offset
03873 + picrel->tlsplt_entry;
03874 BFD_ASSERT (picrel->tlsplt_entry != (bfd_vma)-1
03875 && picrel->tlsdesc_entry);
03876 check_segment[0] = isec_segment;
03877 check_segment[1] = plt_segment;
03878 break;
03879
03880 case R_FRV_GOTTLSDESC12:
03881 case R_FRV_GOTTLSDESCHI:
03882 case R_FRV_GOTTLSDESCLO:
03883 BFD_ASSERT (picrel->tlsdesc_entry);
03884 relocation = picrel->tlsdesc_entry;
03885 check_segment[0] = tls_segment;
03886 check_segment[1] = sec
03887 && ! bfd_is_abs_section (sec)
03888 && ! bfd_is_und_section (sec)
03889 ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
03890 : tls_segment;
03891 break;
03892
03893 case R_FRV_TLSMOFF12:
03894 case R_FRV_TLSMOFFHI:
03895 case R_FRV_TLSMOFFLO:
03896 case R_FRV_TLSMOFF:
03897 check_segment[0] = tls_segment;
03898 if (! sec)
03899 check_segment[1] = -1;
03900 else if (bfd_is_abs_section (sec)
03901 || bfd_is_und_section (sec))
03902 {
03903 relocation = 0;
03904 check_segment[1] = tls_segment;
03905 }
03906 else if (sec->output_section)
03907 {
03908 relocation -= tls_biased_base (info);
03909 check_segment[1] =
03910 _frvfdpic_osec_to_segment (output_bfd, sec->output_section);
03911 }
03912 else
03913 check_segment[1] = -1;
03914 break;
03915
03916 case R_FRV_GOTTLSOFF12:
03917 case R_FRV_GOTTLSOFFHI:
03918 case R_FRV_GOTTLSOFFLO:
03919 BFD_ASSERT (picrel->tlsoff_entry);
03920 relocation = picrel->tlsoff_entry;
03921 check_segment[0] = tls_segment;
03922 check_segment[1] = sec
03923 && ! bfd_is_abs_section (sec)
03924 && ! bfd_is_und_section (sec)
03925 ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
03926 : tls_segment;
03927 break;
03928
03929 case R_FRV_TLSDESC_VALUE:
03930 case R_FRV_TLSOFF:
03931
03932 check_segment[0] = check_segment[1] = isec_segment;
03933 break;
03934
03935 case R_FRV_TLSDESC_RELAX:
03936 case R_FRV_GETTLSOFF_RELAX:
03937 case R_FRV_TLSOFF_RELAX:
03938
03939
03940 continue;
03941
03942 default:
03943 check_segment[0] = isec_segment;
03944 check_segment[1] = sec
03945 ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
03946 : (unsigned)-1;
03947 break;
03948 }
03949
03950 if (check_segment[0] != check_segment[1] && IS_FDPIC (output_bfd))
03951 {
03952
03953
03954
03955
03956
03957 if (silence_segment_error == 1)
03958 silence_segment_error =
03959 (strlen (input_bfd->filename) == 6
03960 && strcmp (input_bfd->filename, "crt0.o") == 0)
03961 || (strlen (input_bfd->filename) > 6
03962 && strcmp (input_bfd->filename
03963 + strlen (input_bfd->filename) - 7,
03964 "/crt0.o") == 0)
03965 ? -1 : 0;
03966 if (!silence_segment_error
03967
03968
03969 && !(picrel && picrel->symndx == -1
03970 && picrel->d.h->root.type == bfd_link_hash_undefined))
03971 {
03972 if (info->shared || info->pie)
03973 (*_bfd_error_handler)
03974 (_("%B(%A+0x%lx): reloc against `%s': %s"),
03975 input_bfd, input_section, (long)rel->r_offset, name,
03976 _("relocation references a different segment"));
03977 else
03978 info->callbacks->warning
03979 (info,
03980 _("relocation references a different segment"),
03981 name, input_bfd, input_section, rel->r_offset);
03982 }
03983 if (!silence_segment_error && (info->shared || info->pie))
03984 return FALSE;
03985 elf_elfheader (output_bfd)->e_flags |= EF_FRV_PIC;
03986 }
03987
03988 switch (r_type)
03989 {
03990 case R_FRV_GOTOFFHI:
03991 case R_FRV_TLSMOFFHI:
03992
03993
03994 relocation += rel->r_addend;
03995
03996 case R_FRV_GOTHI:
03997 case R_FRV_FUNCDESC_GOTHI:
03998 case R_FRV_FUNCDESC_GOTOFFHI:
03999 case R_FRV_GOTTLSOFFHI:
04000 case R_FRV_GOTTLSDESCHI:
04001 relocation >>= 16;
04002
04003
04004 case R_FRV_GOTLO:
04005 case R_FRV_FUNCDESC_GOTLO:
04006 case R_FRV_GOTOFFLO:
04007 case R_FRV_FUNCDESC_GOTOFFLO:
04008 case R_FRV_GOTTLSOFFLO:
04009 case R_FRV_GOTTLSDESCLO:
04010 case R_FRV_TLSMOFFLO:
04011 relocation &= 0xffff;
04012 break;
04013
04014 default:
04015 break;
04016 }
04017
04018 switch (r_type)
04019 {
04020 case R_FRV_LABEL24:
04021 if (! IS_FDPIC (output_bfd) || ! picrel->plt)
04022 break;
04023
04024
04025
04026
04027
04028
04029
04030 case R_FRV_GOT12:
04031 case R_FRV_GOTHI:
04032 case R_FRV_GOTLO:
04033 case R_FRV_FUNCDESC_GOT12:
04034 case R_FRV_FUNCDESC_GOTHI:
04035 case R_FRV_FUNCDESC_GOTLO:
04036 case R_FRV_FUNCDESC_GOTOFF12:
04037 case R_FRV_FUNCDESC_GOTOFFHI:
04038 case R_FRV_FUNCDESC_GOTOFFLO:
04039 case R_FRV_GETTLSOFF:
04040 case R_FRV_GOTTLSDESC12:
04041 case R_FRV_GOTTLSDESCHI:
04042 case R_FRV_GOTTLSDESCLO:
04043 case R_FRV_GOTTLSOFF12:
04044 case R_FRV_GOTTLSOFFHI:
04045 case R_FRV_GOTTLSOFFLO:
04046
04047
04048
04049
04050 case R_FRV_GOTOFFHI:
04051 case R_FRV_TLSMOFFHI:
04052 relocation -= rel->r_addend;
04053 break;
04054
04055 default:
04056 break;
04057 }
04058
04059 if (r_type == R_FRV_HI16)
04060 r = elf32_frv_relocate_hi16 (input_bfd, rel, contents, relocation);
04061
04062 else if (r_type == R_FRV_LO16)
04063 r = elf32_frv_relocate_lo16 (input_bfd, rel, contents, relocation);
04064
04065 else if (r_type == R_FRV_LABEL24 || r_type == R_FRV_GETTLSOFF)
04066 r = elf32_frv_relocate_label24 (input_bfd, input_section, rel,
04067 contents, relocation);
04068
04069 else if (r_type == R_FRV_GPREL12)
04070 r = elf32_frv_relocate_gprel12 (info, input_bfd, input_section, rel,
04071 contents, relocation);
04072
04073 else if (r_type == R_FRV_GPRELU12)
04074 r = elf32_frv_relocate_gprelu12 (info, input_bfd, input_section, rel,
04075 contents, relocation);
04076
04077 else if (r_type == R_FRV_GPRELLO)
04078 r = elf32_frv_relocate_gprello (info, input_bfd, input_section, rel,
04079 contents, relocation);
04080
04081 else if (r_type == R_FRV_GPRELHI)
04082 r = elf32_frv_relocate_gprelhi (info, input_bfd, input_section, rel,
04083 contents, relocation);
04084
04085 else if (r_type == R_FRV_TLSOFF
04086 || r_type == R_FRV_TLSDESC_VALUE)
04087 r = bfd_reloc_notsupported;
04088
04089 else
04090 r = frv_final_link_relocate (howto, input_bfd, input_section, contents,
04091 rel, relocation);
04092
04093 if (r != bfd_reloc_ok)
04094 {
04095 const char * msg = (const char *) NULL;
04096
04097 switch (r)
04098 {
04099 case bfd_reloc_overflow:
04100 r = info->callbacks->reloc_overflow
04101 (info, (h ? &h->root : NULL), name, howto->name,
04102 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
04103 break;
04104
04105 case bfd_reloc_undefined:
04106 r = info->callbacks->undefined_symbol
04107 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
04108 break;
04109
04110 case bfd_reloc_outofrange:
04111 msg = _("internal error: out of range error");
04112 break;
04113
04114 case bfd_reloc_notsupported:
04115 msg = _("internal error: unsupported relocation error");
04116 break;
04117
04118 case bfd_reloc_dangerous:
04119 msg = _("internal error: dangerous relocation");
04120 break;
04121
04122 default:
04123 msg = _("internal error: unknown error");
04124 break;
04125 }
04126
04127 if (msg)
04128 {
04129 (*_bfd_error_handler)
04130 (_("%B(%A+0x%lx): reloc against `%s': %s"),
04131 input_bfd, input_section, (long)rel->r_offset, name, msg);
04132 return FALSE;
04133 }
04134
04135 if (! r)
04136 return FALSE;
04137 }
04138 }
04139
04140 return TRUE;
04141 }
04142
04143
04144
04145
04146 static asection *
04147 elf32_frv_gc_mark_hook (sec, info, rel, h, sym)
04148 asection *sec;
04149 struct bfd_link_info *info ATTRIBUTE_UNUSED;
04150 Elf_Internal_Rela *rel;
04151 struct elf_link_hash_entry *h;
04152 Elf_Internal_Sym *sym;
04153 {
04154 if (h != NULL)
04155 {
04156 switch (ELF32_R_TYPE (rel->r_info))
04157 {
04158 case R_FRV_GNU_VTINHERIT:
04159 case R_FRV_GNU_VTENTRY:
04160 break;
04161
04162 default:
04163 switch (h->root.type)
04164 {
04165 default:
04166 break;
04167
04168 case bfd_link_hash_defined:
04169 case bfd_link_hash_defweak:
04170 return h->root.u.def.section;
04171
04172 case bfd_link_hash_common:
04173 return h->root.u.c.p->section;
04174 }
04175 }
04176 }
04177 else
04178 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
04179
04180 return NULL;
04181 }
04182
04183
04184
04185 static bfd_boolean
04186 elf32_frv_gc_sweep_hook (abfd, info, sec, relocs)
04187 bfd *abfd ATTRIBUTE_UNUSED;
04188 struct bfd_link_info *info ATTRIBUTE_UNUSED;
04189 asection *sec ATTRIBUTE_UNUSED;
04190 const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
04191 {
04192 return TRUE;
04193 }
04194
04195
04196
04197
04198
04199 static bfd_boolean
04200 elf32_frv_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
04201 bfd *abfd;
04202 struct bfd_link_info *info;
04203 Elf_Internal_Sym *sym;
04204 const char **namep ATTRIBUTE_UNUSED;
04205 flagword *flagsp ATTRIBUTE_UNUSED;
04206 asection **secp;
04207 bfd_vma *valp;
04208 {
04209 if (sym->st_shndx == SHN_COMMON
04210 && !info->relocatable
04211 && (int)sym->st_size <= (int)bfd_get_gp_size (abfd))
04212 {
04213
04214
04215
04216 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
04217
04218 if (scomm == NULL)
04219 {
04220 scomm = bfd_make_section (abfd, ".scommon");
04221 if (scomm == NULL
04222 || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
04223 | SEC_IS_COMMON
04224 | SEC_LINKER_CREATED)))
04225 return FALSE;
04226 }
04227
04228 *secp = scomm;
04229 *valp = sym->st_size;
04230 }
04231
04232 return TRUE;
04233 }
04234
04235
04236
04237 static bfd_boolean
04238 _frvfdpic_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED,
04239 struct bfd_link_info *info
04240 ATTRIBUTE_UNUSED,
04241 asection *p ATTRIBUTE_UNUSED)
04242 {
04243 switch (elf_section_data (p)->this_hdr.sh_type)
04244 {
04245 case SHT_PROGBITS:
04246 case SHT_NOBITS:
04247
04248
04249 case SHT_NULL:
04250 return FALSE;
04251
04252
04253
04254 default:
04255 return TRUE;
04256 }
04257 }
04258
04259
04260
04261
04262
04263 static bfd_boolean
04264 _frv_create_got_section (bfd *abfd, struct bfd_link_info *info)
04265 {
04266 flagword flags, pltflags;
04267 asection *s;
04268 struct elf_link_hash_entry *h;
04269 struct bfd_link_hash_entry *bh;
04270 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
04271 int ptralign;
04272 int offset;
04273
04274
04275 s = bfd_get_section_by_name (abfd, ".got");
04276 if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0)
04277 return TRUE;
04278
04279
04280
04281
04282
04283 ptralign = 3;
04284
04285 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
04286 | SEC_LINKER_CREATED);
04287 pltflags = flags;
04288
04289 s = bfd_make_section (abfd, ".got");
04290 if (s == NULL
04291 || !bfd_set_section_flags (abfd, s, flags)
04292 || !bfd_set_section_alignment (abfd, s, ptralign))
04293 return FALSE;
04294
04295 if (bed->want_got_plt)
04296 {
04297 s = bfd_make_section (abfd, ".got.plt");
04298 if (s == NULL
04299 || !bfd_set_section_flags (abfd, s, flags)
04300 || !bfd_set_section_alignment (abfd, s, ptralign))
04301 return FALSE;
04302 }
04303
04304 if (bed->want_got_sym)
04305 {
04306
04307
04308
04309
04310 bh = NULL;
04311 if (!(_bfd_generic_link_add_one_symbol
04312 (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
04313 bed->got_symbol_offset, (const char *) NULL, FALSE,
04314 bed->collect, &bh)))
04315 return FALSE;
04316 h = (struct elf_link_hash_entry *) bh;
04317 h->def_regular = 1;
04318 h->type = STT_OBJECT;
04319
04320
04321
04322
04323 if (! bfd_elf_link_record_dynamic_symbol (info, h))
04324 return FALSE;
04325
04326 elf_hash_table (info)->hgot = h;
04327 }
04328
04329
04330 s->size += bed->got_header_size + bed->got_symbol_offset;
04331
04332
04333
04334 if (IS_FDPIC (abfd))
04335 {
04336 frvfdpic_got_section (info) = s;
04337 frvfdpic_relocs_info (info) = htab_try_create (1,
04338 frvfdpic_relocs_info_hash,
04339 frvfdpic_relocs_info_eq,
04340 (htab_del) NULL);
04341 if (! frvfdpic_relocs_info (info))
04342 return FALSE;
04343
04344 s = bfd_make_section (abfd, ".rel.got");
04345 if (s == NULL
04346 || ! bfd_set_section_flags (abfd, s, (flags | SEC_READONLY))
04347 || ! bfd_set_section_alignment (abfd, s, 2))
04348 return FALSE;
04349
04350 frvfdpic_gotrel_section (info) = s;
04351
04352
04353 s = bfd_make_section (abfd, ".rofixup");
04354 if (s == NULL
04355 || ! bfd_set_section_flags (abfd, s, (flags | SEC_READONLY))
04356 || ! bfd_set_section_alignment (abfd, s, 2))
04357 return FALSE;
04358
04359 frvfdpic_gotfixup_section (info) = s;
04360 offset = -2048;
04361 flags = BSF_GLOBAL;
04362 }
04363 else
04364 {
04365 offset = 2048;
04366 flags = BSF_GLOBAL | BSF_WEAK;
04367 }
04368
04369
04370
04371
04372 bh = NULL;
04373 if (!(_bfd_generic_link_add_one_symbol
04374 (info, abfd, "_gp", flags, s, offset, (const char *) NULL, FALSE,
04375 bed->collect, &bh)))
04376 return FALSE;
04377 h = (struct elf_link_hash_entry *) bh;
04378 h->def_regular = 1;
04379 h->type = STT_OBJECT;
04380
04381
04382
04383 if (IS_FDPIC (abfd) && ! bfd_elf_link_record_dynamic_symbol (info, h))
04384 return FALSE;
04385
04386 if (!IS_FDPIC (abfd))
04387 return TRUE;
04388
04389
04390
04391
04392
04393
04394
04395 flags = pltflags;
04396 pltflags |= SEC_CODE;
04397 if (bed->plt_not_loaded)
04398 pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS);
04399 if (bed->plt_readonly)
04400 pltflags |= SEC_READONLY;
04401
04402 s = bfd_make_section (abfd, ".plt");
04403 if (s == NULL
04404 || ! bfd_set_section_flags (abfd, s, pltflags)
04405 || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
04406 return FALSE;
04407
04408 frvfdpic_plt_section (info) = s;
04409
04410 if (bed->want_plt_sym)
04411 {
04412
04413
04414 struct elf_link_hash_entry *h;
04415 struct bfd_link_hash_entry *bh = NULL;
04416
04417 if (! (_bfd_generic_link_add_one_symbol
04418 (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s, 0, NULL,
04419 FALSE, get_elf_backend_data (abfd)->collect, &bh)))
04420 return FALSE;
04421 h = (struct elf_link_hash_entry *) bh;
04422 h->def_regular = 1;
04423 h->type = STT_OBJECT;
04424
04425
04426 if (! info->executable
04427 && ! bfd_elf_link_record_dynamic_symbol (info, h))
04428 return FALSE;
04429 }
04430
04431
04432 s = bfd_make_section (abfd, ".rel.plt");
04433 if (s == NULL
04434 || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
04435 || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
04436 return FALSE;
04437
04438 frvfdpic_pltrel_section (info) = s;
04439
04440 return TRUE;
04441 }
04442
04443
04444
04445
04446 static bfd_boolean
04447 elf32_frvfdpic_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
04448 {
04449
04450
04451 flagword flags;
04452 asection *s;
04453 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
04454
04455 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
04456 | SEC_LINKER_CREATED);
04457
04458
04459
04460
04461
04462
04463 if (! _frv_create_got_section (abfd, info))
04464 return FALSE;
04465
04466
04467 BFD_ASSERT (frvfdpic_got_section (info) && frvfdpic_gotrel_section (info)
04468 && frvfdpic_gotfixup_section (info)
04469 && frvfdpic_plt_section (info)
04470 && frvfdpic_pltrel_section (info));
04471
04472 if (bed->want_dynbss)
04473 {
04474
04475
04476
04477
04478
04479
04480 s = bfd_make_section (abfd, ".dynbss");
04481 if (s == NULL
04482 || ! bfd_set_section_flags (abfd, s, SEC_ALLOC | SEC_LINKER_CREATED))
04483 return FALSE;
04484
04485
04486
04487
04488
04489
04490
04491
04492
04493
04494
04495
04496 if (! info->shared)
04497 {
04498 s = bfd_make_section (abfd,
04499 (bed->default_use_rela_p
04500 ? ".rela.bss" : ".rel.bss"));
04501 if (s == NULL
04502 || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
04503 || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
04504 return FALSE;
04505 }
04506 }
04507
04508 return TRUE;
04509 }
04510
04511
04512
04513
04514
04515
04516
04517 static void
04518 _frvfdpic_count_nontls_entries (struct frvfdpic_relocs_info *entry,
04519 struct _frvfdpic_dynamic_got_info *dinfo)
04520 {
04521
04522 if (entry->got12)
04523 dinfo->got12 += 4;
04524 else if (entry->gotlos)
04525 dinfo->gotlos += 4;
04526 else if (entry->gothilo)
04527 dinfo->gothilo += 4;
04528 else
04529 entry->relocs32--;
04530 entry->relocs32++;
04531
04532
04533
04534 if (entry->fdgot12)
04535 dinfo->got12 += 4;
04536 else if (entry->fdgotlos)
04537 dinfo->gotlos += 4;
04538 else if (entry->fdgothilo)
04539 dinfo->gothilo += 4;
04540 else
04541 entry->relocsfd--;
04542 entry->relocsfd++;
04543
04544
04545
04546 entry->plt = entry->call
04547 && entry->symndx == -1 && ! FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
04548 && elf_hash_table (dinfo->info)->dynamic_sections_created;
04549 entry->privfd = entry->plt
04550 || entry->fdgoff12 || entry->fdgofflos || entry->fdgoffhilo
04551 || ((entry->fd || entry->fdgot12 || entry->fdgotlos || entry->fdgothilo)
04552 && (entry->symndx != -1
04553 || FRVFDPIC_FUNCDESC_LOCAL (dinfo->info, entry->d.h)));
04554 entry->lazyplt = entry->privfd
04555 && entry->symndx == -1 && ! FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
04556 && ! (dinfo->info->flags & DF_BIND_NOW)
04557 && elf_hash_table (dinfo->info)->dynamic_sections_created;
04558
04559
04560 if (entry->fdgoff12)
04561 dinfo->fd12 += 8;
04562 else if (entry->fdgofflos)
04563 dinfo->fdlos += 8;
04564 else if (entry->privfd && entry->plt)
04565 dinfo->fdplt += 8;
04566 else if (entry->privfd)
04567 dinfo->fdhilo += 8;
04568 else
04569 entry->relocsfdv--;
04570 entry->relocsfdv++;
04571
04572 if (entry->lazyplt)
04573 dinfo->lzplt += 8;
04574 }
04575
04576
04577
04578
04579
04580
04581 static void
04582 _frvfdpic_count_tls_entries (struct frvfdpic_relocs_info *entry,
04583 struct _frvfdpic_dynamic_got_info *dinfo,
04584 bfd_boolean subtract)
04585 {
04586 const int l = subtract ? -1 : 1;
04587
04588
04589
04590 if (entry->tlsoff12)
04591 dinfo->got12 += 4 * l;
04592 else if (entry->tlsofflos)
04593 dinfo->gotlos += 4 * l;
04594 else if (entry->tlsoffhilo)
04595 dinfo->gothilo += 4 * l;
04596 else
04597 entry->relocstlsoff -= l;
04598 entry->relocstlsoff += l;
04599
04600
04601
04602
04603
04604
04605 if (entry->relocstlsoff)
04606 dinfo->info->flags |= DF_STATIC_TLS;
04607
04608
04609 if (entry->tlsdesc12)
04610 dinfo->tlsd12 += 8 * l;
04611 else if (entry->tlsdesclos)
04612 dinfo->tlsdlos += 8 * l;
04613 else if (entry->tlsplt)
04614 dinfo->tlsdplt += 8 * l;
04615 else if (entry->tlsdeschilo)
04616 dinfo->tlsdhilo += 8 * l;
04617 else
04618 entry->relocstlsd -= l;
04619 entry->relocstlsd += l;
04620 }
04621
04622
04623
04624
04625
04626 static void
04627 _frvfdpic_count_relocs_fixups (struct frvfdpic_relocs_info *entry,
04628 struct _frvfdpic_dynamic_got_info *dinfo,
04629 bfd_boolean subtract)
04630 {
04631 bfd_vma relocs = 0, fixups = 0, tlsrets = 0;
04632
04633 if (!dinfo->info->executable || dinfo->info->pie)
04634 {
04635 relocs = entry->relocs32 + entry->relocsfd + entry->relocsfdv
04636 + entry->relocstlsd;
04637
04638
04639
04640
04641
04642
04643
04644
04645 if (!dinfo->info->executable
04646 || (entry->symndx == -1
04647 && ! FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)))
04648 relocs += entry->relocstlsoff;
04649 }
04650 else
04651 {
04652 if (entry->symndx != -1 || FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h))
04653 {
04654 if (entry->symndx != -1
04655 || entry->d.h->root.type != bfd_link_hash_undefweak)
04656 fixups += entry->relocs32 + 2 * entry->relocsfdv;
04657 fixups += entry->relocstlsd;
04658 tlsrets += entry->relocstlsd;
04659 }
04660 else
04661 {
04662 relocs += entry->relocs32 + entry->relocsfdv
04663 + entry->relocstlsoff + entry->relocstlsd;
04664 }
04665
04666 if (entry->symndx != -1
04667 || FRVFDPIC_FUNCDESC_LOCAL (dinfo->info, entry->d.h))
04668 {
04669 if (entry->symndx != -1
04670 || entry->d.h->root.type != bfd_link_hash_undefweak)
04671 fixups += entry->relocsfd;
04672 }
04673 else
04674 relocs += entry->relocsfd;
04675 }
04676
04677 if (subtract)
04678 {
04679 relocs = - relocs;
04680 fixups = - fixups;
04681 tlsrets = - tlsrets;
04682 }
04683
04684 entry->dynrelocs += relocs;
04685 entry->fixups += fixups;
04686 dinfo->relocs += relocs;
04687 dinfo->fixups += fixups;
04688 dinfo->tls_ret_refs += tlsrets;
04689 }
04690
04691
04692
04693
04694
04695
04696
04697 static void
04698 _frvfdpic_relax_tls_entries (struct frvfdpic_relocs_info *entry,
04699 struct _frvfdpic_dynamic_got_info *dinfo,
04700 bfd_boolean relaxing)
04701 {
04702 bfd_boolean changed = ! relaxing;
04703
04704 BFD_ASSERT (dinfo->info->executable
04705 || (dinfo->info->flags & DF_STATIC_TLS));
04706
04707 if (entry->tlsdesc12 || entry->tlsdesclos || entry->tlsdeschilo)
04708 {
04709 if (! changed)
04710 {
04711 _frvfdpic_count_relocs_fixups (entry, dinfo, TRUE);
04712 _frvfdpic_count_tls_entries (entry, dinfo, TRUE);
04713 changed = TRUE;
04714 }
04715
04716
04717
04718
04719
04720
04721
04722
04723 if (! dinfo->info->executable
04724 || (entry->symndx == -1
04725 && ! FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)))
04726 {
04727 entry->tlsoff12 |= entry->tlsdesc12;
04728 entry->tlsofflos |= entry->tlsdesclos;
04729 entry->tlsoffhilo |= entry->tlsdeschilo;
04730 }
04731
04732 entry->tlsdesc12 = entry->tlsdesclos = entry->tlsdeschilo = 0;
04733 }
04734
04735
04736
04737
04738
04739
04740
04741
04742
04743
04744
04745 if ((entry->tlsplt
04746 || entry->tlsoff12 || entry->tlsofflos || entry->tlsoffhilo)
04747 && dinfo->info->executable && relaxing
04748 && ((entry->symndx == -1
04749 && FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
04750
04751
04752
04753 && (entry->d.h->root.type == bfd_link_hash_undefweak
04754 || (bfd_vma)(entry->d.h->root.u.def.value
04755 + (entry->d.h->root.u.def.section
04756 ->output_section->vma)
04757 + entry->d.h->root.u.def.section->output_offset
04758 + entry->addend
04759 - tls_biased_base (dinfo->info)
04760 + 32768) < (bfd_vma)65536))
04761 || (entry->symndx != -1
04762 && (elf_hash_table (dinfo->info)->tls_sec->size
04763 + abs (entry->addend) < 32768 + FRVFDPIC_TLS_BIAS))))
04764 {
04765 if (! changed)
04766 {
04767 _frvfdpic_count_relocs_fixups (entry, dinfo, TRUE);
04768 _frvfdpic_count_tls_entries (entry, dinfo, TRUE);
04769 changed = TRUE;
04770 }
04771
04772 entry->tlsplt =
04773 entry->tlsoff12 = entry->tlsofflos = entry->tlsoffhilo = 0;
04774 }
04775
04776
04777
04778
04779 if (entry->tlsplt
04780 && (entry->tlsoff12
04781 || (relaxing
04782 && dinfo->got12 + dinfo->fd12 + dinfo->tlsd12 <= 4096 - 12 - 4
04783 && (dinfo->got12 + dinfo->fd12 + dinfo->tlsd12
04784 + dinfo->gotlos + dinfo->fdlos + dinfo->tlsdlos
04785 <= 65536 - 12 - 4))))
04786 {
04787 if (! changed)
04788 {
04789 _frvfdpic_count_relocs_fixups (entry, dinfo, TRUE);
04790 _frvfdpic_count_tls_entries (entry, dinfo, TRUE);
04791 changed = TRUE;
04792 }
04793
04794 entry->tlsoff12 = 1;
04795 entry->tlsplt = 0;
04796 }
04797
04798 if (changed)
04799 {
04800 _frvfdpic_count_tls_entries (entry, dinfo, FALSE);
04801 _frvfdpic_count_relocs_fixups (entry, dinfo, FALSE);
04802 }
04803
04804 return;
04805 }
04806
04807
04808
04809
04810
04811
04812 static int
04813 _frvfdpic_count_got_plt_entries (void **entryp, void *dinfo_)
04814 {
04815 struct frvfdpic_relocs_info *entry = *entryp;
04816 struct _frvfdpic_dynamic_got_info *dinfo = dinfo_;
04817
04818 _frvfdpic_count_nontls_entries (entry, dinfo);
04819
04820 if (dinfo->info->executable || (dinfo->info->flags & DF_STATIC_TLS))
04821 _frvfdpic_relax_tls_entries (entry, dinfo, FALSE);
04822 else
04823 {
04824 _frvfdpic_count_tls_entries (entry, dinfo, FALSE);
04825 _frvfdpic_count_relocs_fixups (entry, dinfo, FALSE);
04826 }
04827
04828 return 1;
04829 }
04830
04831
04832
04833
04834
04835
04836
04837
04838
04839
04840
04841 inline static bfd_signed_vma
04842 _frvfdpic_compute_got_alloc_data (struct _frvfdpic_dynamic_got_alloc_data *gad,
04843 bfd_signed_vma fdcur,
04844 bfd_signed_vma odd,
04845 bfd_signed_vma cur,
04846 bfd_vma got,
04847 bfd_vma fd,
04848 bfd_vma fdplt,
04849 bfd_vma tlsd,
04850 bfd_vma tlsdplt,
04851 bfd_vma wrap)
04852 {
04853 bfd_signed_vma wrapmin = -wrap;
04854 const bfd_vma tdescsz = 8;
04855
04856
04857 gad->fdcur = fdcur;
04858 gad->cur = cur;
04859
04860
04861
04862
04863
04864
04865
04866
04867 if (odd && got)
04868 {
04869 gad->odd = odd;
04870 got -= 4;
04871 odd = 0;
04872 }
04873 else
04874 gad->odd = 0;
04875
04876
04877
04878
04879
04880
04881
04882
04883 if (got & 4)
04884 {
04885 odd = cur + got;
04886 got += 4;
04887 }
04888
04889
04890 gad->max = cur + got;
04891 gad->min = fdcur - fd;
04892 gad->fdplt = 0;
04893
04894
04895
04896 if (gad->min < wrapmin)
04897 {
04898 gad->max += wrapmin - gad->min;
04899 gad->tmin = gad->min = wrapmin;
04900 }
04901
04902
04903
04904
04905
04906 if ((bfd_vma) gad->max > wrap)
04907 {
04908 gad->min -= gad->max - wrap;
04909 gad->max = wrap;
04910 }
04911
04912
04913 gad->tmax = gad->max + tlsd;
04914 gad->tmin = gad->min;
04915 gad->tlsdplt = 0;
04916
04917
04918
04919 if ((bfd_vma) gad->tmax > wrap)
04920 {
04921 bfd_vma wrapsize = gad->tmax - wrap;
04922
04923 wrapsize += tdescsz / 2;
04924 wrapsize &= ~ tdescsz / 2;
04925
04926 gad->tmin -= wrapsize;
04927 gad->tmax -= wrapsize;
04928 }
04929
04930
04931
04932
04933 if (fdplt && gad->tmin > wrapmin)
04934 {
04935 bfd_vma fds;
04936
04937 if ((bfd_vma) (gad->tmin - wrapmin) < fdplt)
04938 fds = gad->tmin - wrapmin;
04939 else
04940 fds = fdplt;
04941
04942 fdplt -= fds;
04943 gad->min -= fds;
04944 gad->tmin -= fds;
04945 gad->fdplt += fds;
04946 }
04947
04948
04949
04950 if (fdplt && (bfd_vma) gad->tmax < wrap)
04951 {
04952 bfd_vma fds;
04953
04954 if ((bfd_vma) (wrap - gad->tmax) < fdplt)
04955 fds = wrap - gad->tmax;
04956 else
04957 fds = fdplt;
04958
04959 fdplt -= fds;
04960 gad->max += fds;
04961 gad->tmax += fds;
04962 gad->fdplt += fds;
04963 }
04964
04965
04966
04967
04968 if (tlsdplt && gad->tmin > wrapmin)
04969 {
04970 bfd_vma tlsds;
04971
04972 if ((bfd_vma) (gad->tmin - wrapmin) < tlsdplt)
04973 tlsds = (gad->tmin - wrapmin) & ~ (tdescsz / 2);
04974 else
04975 tlsds = tlsdplt;
04976
04977 tlsdplt -= tlsds;
04978 gad->tmin -= tlsds;
04979 gad->tlsdplt += tlsds;
04980 }
04981
04982
04983
04984
04985
04986
04987
04988 if (tlsdplt && (bfd_vma) gad->tmax < wrap - tdescsz / 2)
04989 {
04990 bfd_vma tlsds;
04991
04992 if ((bfd_vma) (wrap - gad->tmax) < tlsdplt)
04993 tlsds = (wrap - gad->tmax) & ~ (tdescsz / 2);
04994 else
04995 tlsds = tlsdplt;
04996
04997 tlsdplt -= tlsds;
04998 gad->tmax += tlsds;
04999 gad->tlsdplt += tlsds;
05000 }
05001
05002
05003
05004 if (odd > gad->max)
05005 odd = gad->min + odd - gad->max;
05006
05007
05008
05009
05010
05011 if (gad->cur == gad->max)
05012 gad->cur = gad->min;
05013
05014
05015 gad->tcur = gad->max;
05016 if (gad->tcur == gad->tmax)
05017 gad->tcur = gad->tmin;
05018
05019 return odd;
05020 }
05021
05022
05023
05024
05025 inline static bfd_signed_vma
05026 _frvfdpic_get_got_entry (struct _frvfdpic_dynamic_got_alloc_data *gad)
05027 {
05028 bfd_signed_vma ret;
05029
05030 if (gad->odd)
05031 {
05032
05033 ret = gad->odd;
05034 gad->odd = 0;
05035 }
05036 else
05037 {
05038
05039
05040
05041 ret = gad->cur;
05042 gad->odd = gad->cur + 4;
05043 gad->cur += 8;
05044 if (gad->cur == gad->max)
05045 gad->cur = gad->min;
05046 }
05047
05048 return ret;
05049 }
05050
05051
05052
05053
05054 inline static bfd_signed_vma
05055 _frvfdpic_get_fd_entry (struct _frvfdpic_dynamic_got_alloc_data *gad)
05056 {
05057
05058
05059 if (gad->fdcur == gad->min)
05060 gad->fdcur = gad->max;
05061 return gad->fdcur -= 8;
05062 }
05063
05064
05065
05066 inline static bfd_signed_vma
05067 _frvfdpic_get_tlsdesc_entry (struct _frvfdpic_dynamic_got_alloc_data *gad)
05068 {
05069 bfd_signed_vma ret;
05070
05071 ret = gad->tcur;
05072
05073 gad->tcur += 8;
05074
05075
05076 if (gad->tcur == gad->tmax)
05077 gad->tcur = gad->tmin;
05078
05079 return ret;
05080 }
05081
05082
05083
05084
05085 static int
05086 _frvfdpic_assign_got_entries (void **entryp, void *info_)
05087 {
05088 struct frvfdpic_relocs_info *entry = *entryp;
05089 struct _frvfdpic_dynamic_got_plt_info *dinfo = info_;
05090
05091 if (entry->got12)
05092 entry->got_entry = _frvfdpic_get_got_entry (&dinfo->got12);
05093 else if (entry->gotlos)
05094 entry->got_entry = _frvfdpic_get_got_entry (&dinfo->gotlos);
05095 else if (entry->gothilo)
05096 entry->got_entry = _frvfdpic_get_got_entry (&dinfo->gothilo);
05097
05098 if (entry->fdgot12)
05099 entry->fdgot_entry = _frvfdpic_get_got_entry (&dinfo->got12);
05100 else if (entry->fdgotlos)
05101 entry->fdgot_entry = _frvfdpic_get_got_entry (&dinfo->gotlos);
05102 else if (entry->fdgothilo)
05103 entry->fdgot_entry = _frvfdpic_get_got_entry (&dinfo->gothilo);
05104
05105 if (entry->fdgoff12)
05106 entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->got12);
05107 else if (entry->plt && dinfo->got12.fdplt)
05108 {
05109 dinfo->got12.fdplt -= 8;
05110 entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->got12);
05111 }
05112 else if (entry->fdgofflos)
05113 entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gotlos);
05114 else if (entry->plt && dinfo->gotlos.fdplt)
05115 {
05116 dinfo->gotlos.fdplt -= 8;
05117 entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gotlos);
05118 }
05119 else if (entry->plt)
05120 {
05121 dinfo->gothilo.fdplt -= 8;
05122 entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gothilo);
05123 }
05124 else if (entry->privfd)
05125 entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gothilo);
05126
05127 if (entry->tlsoff12)
05128 entry->tlsoff_entry = _frvfdpic_get_got_entry (&dinfo->got12);
05129 else if (entry->tlsofflos)
05130 entry->tlsoff_entry = _frvfdpic_get_got_entry (&dinfo->gotlos);
05131 else if (entry->tlsoffhilo)
05132 entry->tlsoff_entry = _frvfdpic_get_got_entry (&dinfo->gothilo);
05133
05134 if (entry->tlsdesc12)
05135 entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->got12);
05136 else if (entry->tlsplt && dinfo->got12.tlsdplt)
05137 {
05138 dinfo->got12.tlsdplt -= 8;
05139 entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->got12);
05140 }
05141 else if (entry->tlsdesclos)
05142 entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->gotlos);
05143 else if (entry->tlsplt && dinfo->gotlos.tlsdplt)
05144 {
05145 dinfo->gotlos.tlsdplt -= 8;
05146 entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->gotlos);
05147 }
05148 else if (entry->tlsplt)
05149 {
05150 dinfo->gothilo.tlsdplt -= 8;
05151 entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->gothilo);
05152 }
05153 else if (entry->tlsdeschilo)
05154 entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->gothilo);
05155
05156 return 1;
05157 }
05158
05159
05160
05161
05162
05163 static int
05164 _frvfdpic_assign_plt_entries (void **entryp, void *info_)
05165 {
05166 struct frvfdpic_relocs_info *entry = *entryp;
05167 struct _frvfdpic_dynamic_got_plt_info *dinfo = info_;
05168
05169 if (entry->privfd)
05170 BFD_ASSERT (entry->fd_entry);
05171
05172 if (entry->plt)
05173 {
05174 int size;
05175
05176
05177
05178 entry->plt_entry = frvfdpic_plt_section (dinfo->g.info)->size;
05179
05180
05181
05182 BFD_ASSERT (entry->fd_entry);
05183 if (entry->fd_entry >= -(1 << (12 - 1))
05184 && entry->fd_entry < (1 << (12 - 1)))
05185 size = 8;
05186 else if (entry->fd_entry >= -(1 << (16 - 1))
05187 && entry->fd_entry < (1 << (16 - 1)))
05188 size = 12;
05189 else
05190 size = 16;
05191
05192 frvfdpic_plt_section (dinfo->g.info)->size += size;
05193 }
05194
05195 if (entry->lazyplt)
05196 {
05197 entry->lzplt_entry = dinfo->g.lzplt;
05198 dinfo->g.lzplt += 8;
05199
05200
05201 if (entry->lzplt_entry % FRVFDPIC_LZPLT_BLOCK_SIZE
05202 == FRVFDPIC_LZPLT_RESOLV_LOC)
05203 dinfo->g.lzplt += 4;
05204 }
05205
05206 if (entry->tlsplt)
05207 {
05208 int size;
05209
05210 entry->tlsplt_entry
05211 = frvfdpic_plt_section (dinfo->g.info)->size;
05212
05213 if (dinfo->g.info->executable
05214 && (entry->symndx != -1
05215 || FRVFDPIC_SYM_LOCAL (dinfo->g.info, entry->d.h)))
05216 {
05217 if ((bfd_signed_vma)entry->addend >= -(1 << (16 - 1))
05218
05219
05220
05221
05222
05223
05224 && elf_hash_table (dinfo->g.info)->tls_sec
05225 && (elf_hash_table (dinfo->g.info)->tls_sec->size
05226 + (bfd_signed_vma)(entry->addend) <= (1 << (16 - 1))))
05227 size = 8;
05228 else
05229 size = 12;
05230 }
05231 else if (entry->tlsoff_entry)
05232 {
05233 if (entry->tlsoff_entry >= -(1 << (12 - 1))
05234 && entry->tlsoff_entry < (1 << (12 - 1)))
05235 size = 8;
05236 else if (entry->tlsoff_entry >= -(1 << (16 - 1))
05237 && entry->tlsoff_entry < (1 << (16 - 1)))
05238 size = 12;
05239 else
05240 size = 16;
05241 }
05242 else
05243 {
05244 BFD_ASSERT (entry->tlsdesc_entry);
05245
05246 if (entry->tlsdesc_entry >= -(1 << (12 - 1))
05247 && entry->tlsdesc_entry < (1 << (12 - 1)))
05248 size = 8;
05249 else if (entry->tlsdesc_entry >= -(1 << (16 - 1))
05250 && entry->tlsdesc_entry < (1 << (16 - 1)))
05251 size = 12;
05252 else
05253 size = 16;
05254 }
05255
05256 frvfdpic_plt_section (dinfo->g.info)->size += size;
05257 }
05258
05259 return 1;
05260 }
05261
05262
05263
05264
05265 static int
05266 _frvfdpic_reset_got_plt_entries (void **entryp, void *ignore ATTRIBUTE_UNUSED)
05267 {
05268 struct frvfdpic_relocs_info *entry = *entryp;
05269
05270 entry->got_entry = 0;
05271 entry->fdgot_entry = 0;
05272 entry->fd_entry = 0;
05273 entry->plt_entry = (bfd_vma)-1;
05274 entry->lzplt_entry = (bfd_vma)-1;
05275 entry->tlsoff_entry = 0;
05276 entry->tlsdesc_entry = 0;
05277 entry->tlsplt_entry = (bfd_vma)-1;
05278
05279 return 1;
05280 }
05281
05282
05283
05284
05285
05286
05287
05288 static int
05289 _frvfdpic_resolve_final_relocs_info (void **entryp, void *p)
05290 {
05291 struct frvfdpic_relocs_info *entry = *entryp;
05292 htab_t *htab = p;
05293
05294 if (entry->symndx == -1)
05295 {
05296 struct elf_link_hash_entry *h = entry->d.h;
05297 struct frvfdpic_relocs_info *oentry;
05298
05299 while (h->root.type == bfd_link_hash_indirect
05300 || h->root.type == bfd_link_hash_warning)
05301 h = (struct elf_link_hash_entry *)h->root.u.i.link;
05302
05303 if (entry->d.h == h)
05304 return 1;
05305
05306 oentry = frvfdpic_relocs_info_for_global (*htab, 0, h, entry->addend,
05307 NO_INSERT);
05308
05309 if (oentry)
05310 {
05311
05312 frvfdpic_pic_merge_early_relocs_info (oentry, entry);
05313 htab_clear_slot (*htab, entryp);
05314 return 1;
05315 }
05316
05317 entry->d.h = h;
05318
05319
05320
05321 if (! htab_find (*htab, entry))
05322 {
05323 htab_clear_slot (*htab, entryp);
05324 entryp = htab_find_slot (*htab, entry, INSERT);
05325 if (! *entryp)
05326 *entryp = entry;
05327
05328
05329
05330 *(htab_t *)p = NULL;
05331 return 0;
05332 }
05333 }
05334
05335 return 1;
05336 }
05337
05338
05339
05340
05341
05342 static bfd_boolean
05343 _frvfdpic_size_got_plt (bfd *output_bfd,
05344 struct _frvfdpic_dynamic_got_plt_info *gpinfop)
05345 {
05346 bfd_signed_vma odd;
05347 bfd_vma limit, tlslimit;
05348 struct bfd_link_info *info = gpinfop->g.info;
05349 bfd *dynobj = elf_hash_table (info)->dynobj;
05350
05351 memcpy (frvfdpic_dynamic_got_plt_info (info), &gpinfop->g,
05352 sizeof (gpinfop->g));
05353
05354 odd = 12;
05355
05356
05357
05358
05359 limit = odd + gpinfop->g.got12 + gpinfop->g.gotlos
05360 + gpinfop->g.fd12 + gpinfop->g.fdlos
05361 + gpinfop->g.tlsd12 + gpinfop->g.tlsdlos;
05362 if (limit < (bfd_vma)1 << 16)
05363 limit = ((bfd_vma)1 << 16) - limit;
05364 else
05365 limit = 0;
05366 if (gpinfop->g.fdplt < limit)
05367 {
05368 tlslimit = (limit - gpinfop->g.fdplt) & ~ (bfd_vma) 8;
05369 limit = gpinfop->g.fdplt;
05370 }
05371 else
05372 tlslimit = 0;
05373 if (gpinfop->g.tlsdplt < tlslimit)
05374 tlslimit = gpinfop->g.tlsdplt;
05375
05376
05377
05378 odd = _frvfdpic_compute_got_alloc_data (&gpinfop->got12,
05379 0,
05380 odd,
05381 16,
05382 gpinfop->g.got12,
05383 gpinfop->g.fd12,
05384 limit,
05385 gpinfop->g.tlsd12,
05386 tlslimit,
05387 (bfd_vma)1 << (12-1));
05388 odd = _frvfdpic_compute_got_alloc_data (&gpinfop->gotlos,
05389 gpinfop->got12.tmin,
05390 odd,
05391 gpinfop->got12.tmax,
05392 gpinfop->g.gotlos,
05393 gpinfop->g.fdlos,
05394 gpinfop->g.fdplt
05395 - gpinfop->got12.fdplt,
05396 gpinfop->g.tlsdlos,
05397 gpinfop->g.tlsdplt
05398 - gpinfop->got12.tlsdplt,
05399 (bfd_vma)1 << (16-1));
05400 odd = _frvfdpic_compute_got_alloc_data (&gpinfop->gothilo,
05401 gpinfop->gotlos.tmin,
05402 odd,
05403 gpinfop->gotlos.tmax,
05404 gpinfop->g.gothilo,
05405 gpinfop->g.fdhilo,
05406 gpinfop->g.fdplt
05407 - gpinfop->got12.fdplt
05408 - gpinfop->gotlos.fdplt,
05409 gpinfop->g.tlsdhilo,
05410 gpinfop->g.tlsdplt
05411 - gpinfop->got12.tlsdplt
05412 - gpinfop->gotlos.tlsdplt,
05413 (bfd_vma)1 << (32-1));
05414
05415
05416 htab_traverse (frvfdpic_relocs_info (info), _frvfdpic_assign_got_entries,
05417 gpinfop);
05418
05419 frvfdpic_got_section (info)->size = gpinfop->gothilo.tmax
05420 - gpinfop->gothilo.tmin
05421
05422
05423 - (odd + 4 == gpinfop->gothilo.tmax ? 4 : 0);
05424 if (frvfdpic_got_section (info)->size == 0)
05425 frvfdpic_got_section (info)->flags |= SEC_EXCLUDE;
05426 else if (frvfdpic_got_section (info)->size == 12
05427 && ! elf_hash_table (info)->dynamic_sections_created)
05428 {
05429 frvfdpic_got_section (info)->flags |= SEC_EXCLUDE;
05430 frvfdpic_got_section (info)->size = 0;
05431 }
05432
05433
05434
05435 else if (frvfdpic_got_section (info)->contents == NULL)
05436 {
05437 frvfdpic_got_section (info)->contents =
05438 (bfd_byte *) bfd_zalloc (dynobj,
05439 frvfdpic_got_section (info)->size);
05440 if (frvfdpic_got_section (info)->contents == NULL)
05441 return FALSE;
05442 }
05443
05444 if (frvfdpic_gotrel_section (info))
05445
05446
05447 frvfdpic_gotrel_section (info)->size =
05448 (gpinfop->g.relocs - gpinfop->g.lzplt / 8)
05449 * get_elf_backend_data (output_bfd)->s->sizeof_rel;
05450 else
05451 BFD_ASSERT (gpinfop->g.relocs == 0);
05452 if (frvfdpic_gotrel_section (info)->size == 0)
05453 frvfdpic_gotrel_section (info)->flags |= SEC_EXCLUDE;
05454 else if (frvfdpic_gotrel_section (info)->contents == NULL)
05455 {
05456 frvfdpic_gotrel_section (info)->contents =
05457 (bfd_byte *) bfd_zalloc (dynobj,
05458 frvfdpic_gotrel_section (info)->size);
05459 if (frvfdpic_gotrel_section (info)->contents == NULL)
05460 return FALSE;
05461 }
05462
05463 frvfdpic_gotfixup_section (info)->size = (gpinfop->g.fixups + 1) * 4;
05464 if (frvfdpic_gotfixup_section (info)->size == 0)
05465 frvfdpic_gotfixup_section (info)->flags |= SEC_EXCLUDE;
05466 else if (frvfdpic_gotfixup_section (info)->contents == NULL)
05467 {
05468 frvfdpic_gotfixup_section (info)->contents =
05469 (bfd_byte *) bfd_zalloc (dynobj,
05470 frvfdpic_gotfixup_section (info)->size);
05471 if (frvfdpic_gotfixup_section (info)->contents == NULL)
05472 return FALSE;
05473 }
05474
05475 if (frvfdpic_pltrel_section (info))
05476 {
05477 frvfdpic_pltrel_section (info)->size =
05478 gpinfop->g.lzplt / 8
05479 * get_elf_backend_data (output_bfd)->s->sizeof_rel;
05480 if (frvfdpic_pltrel_section (info)->size == 0)
05481 frvfdpic_pltrel_section (info)->flags |= SEC_EXCLUDE;
05482 else if (frvfdpic_pltrel_section (info)->contents == NULL)
05483 {
05484 frvfdpic_pltrel_section (info)->contents =
05485 (bfd_byte *) bfd_zalloc (dynobj,
05486 frvfdpic_pltrel_section (info)->size);
05487 if (frvfdpic_pltrel_section (info)->contents == NULL)
05488 return FALSE;
05489 }
05490 }
05491
05492
05493
05494
05495
05496
05497 if (frvfdpic_plt_section (info))
05498 {
05499 frvfdpic_plt_section (info)->size = gpinfop->g.lzplt
05500 + ((gpinfop->g.lzplt + (FRVFDPIC_LZPLT_BLOCK_SIZE - 4) - 8)
05501 / (FRVFDPIC_LZPLT_BLOCK_SIZE - 4) * 4);
05502 }
05503
05504
05505
05506 gpinfop->g.lzplt = 0;
05507
05508
05509
05510 frvfdpic_got_initial_offset (info) = -gpinfop->gothilo.tmin;
05511
05512 if (get_elf_backend_data (output_bfd)->want_got_sym)
05513 elf_hash_table (info)->hgot->root.u.def.value
05514 = frvfdpic_got_initial_offset (info);
05515
05516 if (frvfdpic_plt_section (info))
05517 frvfdpic_plt_initial_offset (info) =
05518 frvfdpic_plt_section (info)->size;
05519
05520
05521
05522 if (gpinfop->g.tls_ret_refs)
05523 frvfdpic_plt_section (info)->size += 4;
05524
05525 htab_traverse (frvfdpic_relocs_info (info), _frvfdpic_assign_plt_entries,
05526 gpinfop);
05527
05528
05529
05530
05531 if (frvfdpic_plt_section (info))
05532 {
05533 if (frvfdpic_plt_section (info)->size == 0)
05534 frvfdpic_plt_section (info)->flags |= SEC_EXCLUDE;
05535 else if (frvfdpic_plt_section (info)->contents == NULL)
05536 {
05537 frvfdpic_plt_section (info)->contents =
05538 (bfd_byte *) bfd_zalloc (dynobj,
05539 frvfdpic_plt_section (info)->size);
05540 if (frvfdpic_plt_section (info)->contents == NULL)
05541 return FALSE;
05542 }
05543 }
05544
05545 return TRUE;
05546 }
05547
05548
05549
05550 static bfd_boolean
05551 elf32_frvfdpic_size_dynamic_sections (bfd *output_bfd,
05552 struct bfd_link_info *info)
05553 {
05554 bfd *dynobj;
05555 asection *s;
05556 struct _frvfdpic_dynamic_got_plt_info gpinfo;
05557
05558 dynobj = elf_hash_table (info)->dynobj;
05559 BFD_ASSERT (dynobj != NULL);
05560
05561 if (elf_hash_table (info)->dynamic_sections_created)
05562 {
05563
05564 if (info->executable)
05565 {
05566 s = bfd_get_section_by_name (dynobj, ".interp");
05567 BFD_ASSERT (s != NULL);
05568 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
05569 s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
05570 }
05571 }
05572
05573 memset (&gpinfo, 0, sizeof (gpinfo));
05574 gpinfo.g.info = info;
05575
05576 for (;;)
05577 {
05578 htab_t relocs = frvfdpic_relocs_info (info);
05579
05580 htab_traverse (relocs, _frvfdpic_resolve_final_relocs_info, &relocs);
05581
05582 if (relocs == frvfdpic_relocs_info (info))
05583 break;
05584 }
05585
05586 htab_traverse (frvfdpic_relocs_info (info), _frvfdpic_count_got_plt_entries,
05587 &gpinfo.g);
05588
05589
05590
05591 frvfdpic_dynamic_got_plt_info (info) = bfd_alloc (dynobj, sizeof (gpinfo.g));
05592
05593 if (!_frvfdpic_size_got_plt (output_bfd, &gpinfo))
05594 return FALSE;
05595
05596 if (elf_hash_table (info)->dynamic_sections_created)
05597 {
05598 if (frvfdpic_got_section (info)->size)
05599 if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0))
05600 return FALSE;
05601
05602 if (frvfdpic_pltrel_section (info)->size)
05603 if (!_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
05604 || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_REL)
05605 || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
05606 return FALSE;
05607
05608 if (frvfdpic_gotrel_section (info)->size)
05609 if (!_bfd_elf_add_dynamic_entry (info, DT_REL, 0)
05610 || !_bfd_elf_add_dynamic_entry (info, DT_RELSZ, 0)
05611 || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
05612 sizeof (Elf32_External_Rel)))
05613 return FALSE;
05614 }
05615
05616 return TRUE;
05617 }
05618
05619 static bfd_boolean
05620 elf32_frvfdpic_always_size_sections (bfd *output_bfd,
05621 struct bfd_link_info *info)
05622 {
05623 if (!info->relocatable)
05624 {
05625 struct elf_link_hash_entry *h;
05626 asection *sec;
05627
05628
05629 if (! elf_tdata (output_bfd)->stack_flags)
05630 elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
05631
05632
05633 h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
05634 FALSE, FALSE, FALSE);
05635 if (! h || h->root.type != bfd_link_hash_defined
05636 || h->type != STT_OBJECT
05637 || !h->def_regular)
05638 {
05639 struct bfd_link_hash_entry *bh = NULL;
05640
05641 if (!(_bfd_generic_link_add_one_symbol
05642 (info, output_bfd, "__stacksize",
05643 BSF_GLOBAL, bfd_abs_section_ptr, DEFAULT_STACK_SIZE,
05644 (const char *) NULL, FALSE,
05645 get_elf_backend_data (output_bfd)->collect, &bh)))
05646 return FALSE;
05647
05648 h = (struct elf_link_hash_entry *) bh;
05649 h->def_regular = 1;
05650 h->type = STT_OBJECT;
05651
05652 }
05653
05654
05655 sec = bfd_make_section (output_bfd, ".stack");
05656
05657 if (sec == NULL
05658 || ! bfd_set_section_alignment (output_bfd, sec, 3))
05659 return FALSE;
05660 }
05661
05662 return TRUE;
05663 }
05664
05665
05666
05667
05668
05669 static int
05670 _frvfdpic_relax_got_plt_entries (void **entryp, void *dinfo_)
05671 {
05672 struct frvfdpic_relocs_info *entry = *entryp;
05673 struct _frvfdpic_dynamic_got_info *dinfo = dinfo_;
05674
05675 _frvfdpic_relax_tls_entries (entry, dinfo, TRUE);
05676
05677 return 1;
05678 }
05679
05680 static bfd_boolean
05681 elf32_frvfdpic_relax_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
05682 struct bfd_link_info *info, bfd_boolean *again)
05683 {
05684 struct _frvfdpic_dynamic_got_plt_info gpinfo;
05685
05686
05687 *again = FALSE;
05688
05689
05690 if (sec != frvfdpic_got_section (info))
05691 return TRUE;
05692
05693
05694
05695 if (! info->executable && ! (info->flags & DF_STATIC_TLS))
05696 return TRUE;
05697
05698
05699
05700
05701 if (elf_hash_table (info)->tls_sec == NULL)
05702 return TRUE;
05703
05704 memset (&gpinfo, 0, sizeof (gpinfo));
05705 memcpy (&gpinfo.g, frvfdpic_dynamic_got_plt_info (info), sizeof (gpinfo.g));
05706
05707
05708
05709 htab_traverse (frvfdpic_relocs_info (info),
05710 _frvfdpic_relax_got_plt_entries,
05711 &gpinfo.g);
05712
05713
05714 if (memcmp (frvfdpic_dynamic_got_plt_info (info),
05715 &gpinfo.g, sizeof (gpinfo.g)) != 0)
05716 {
05717
05718 htab_traverse (frvfdpic_relocs_info (info),
05719 _frvfdpic_reset_got_plt_entries,
05720 NULL);
05721
05722
05723
05724 if (!_frvfdpic_size_got_plt (elf_hash_table (info)->tls_sec->owner,
05725 &gpinfo))
05726 return FALSE;
05727
05728
05729
05730
05731
05732
05733
05734 *again = TRUE;
05735 }
05736
05737 return TRUE;
05738 }
05739
05740 static bfd_boolean
05741 elf32_frvfdpic_modify_segment_map (bfd *output_bfd,
05742 struct bfd_link_info *info)
05743 {
05744 struct elf_segment_map *m;
05745
05746
05747
05748 if (! info)
05749 return TRUE;
05750
05751 for (m = elf_tdata (output_bfd)->segment_map; m != NULL; m = m->next)
05752 if (m->p_type == PT_GNU_STACK)
05753 break;
05754
05755 if (m)
05756 {
05757 asection *sec = bfd_get_section_by_name (output_bfd, ".stack");
05758 struct elf_link_hash_entry *h;
05759
05760 if (sec)
05761 {
05762
05763 h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
05764 FALSE, FALSE, FALSE);
05765 while (h->root.type == bfd_link_hash_indirect
05766 || h->root.type == bfd_link_hash_warning)
05767 h = (struct elf_link_hash_entry *)h->root.u.i.link;
05768 BFD_ASSERT (h->root.type == bfd_link_hash_defined);
05769
05770
05771
05772 if (h->root.type == bfd_link_hash_defined)
05773 sec->size = h->root.u.def.value;
05774 else
05775 sec->size = DEFAULT_STACK_SIZE;
05776
05777
05778
05779
05780 m->sections[m->count] = sec;
05781 m->count++;
05782 }
05783 }
05784
05785 return TRUE;
05786 }
05787
05788
05789
05790 static bfd_boolean
05791 elf32_frv_finish_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
05792 struct bfd_link_info *info ATTRIBUTE_UNUSED)
05793 {
05794
05795 return TRUE;
05796 }
05797
05798 static bfd_boolean
05799 elf32_frvfdpic_finish_dynamic_sections (bfd *output_bfd,
05800 struct bfd_link_info *info)
05801 {
05802 bfd *dynobj;
05803 asection *sdyn;
05804
05805 dynobj = elf_hash_table (info)->dynobj;
05806
05807 if (frvfdpic_dynamic_got_plt_info (info))
05808 {
05809 BFD_ASSERT (frvfdpic_dynamic_got_plt_info (info)->tls_ret_refs == 0);
05810 }
05811 if (frvfdpic_got_section (info))
05812 {
05813 BFD_ASSERT (frvfdpic_gotrel_section (info)->size
05814 == (frvfdpic_gotrel_section (info)->reloc_count
05815 * sizeof (Elf32_External_Rel)));
05816
05817 if (frvfdpic_gotfixup_section (info))
05818 {
05819 struct elf_link_hash_entry *hgot = elf_hash_table (info)->hgot;
05820 bfd_vma got_value = hgot->root.u.def.value
05821 + hgot->root.u.def.section->output_section->vma
05822 + hgot->root.u.def.section->output_offset;
05823 struct bfd_link_hash_entry *hend;
05824
05825 _frvfdpic_add_rofixup (output_bfd, frvfdpic_gotfixup_section (info),
05826 got_value, 0);
05827
05828 if (frvfdpic_gotfixup_section (info)->size
05829 != (frvfdpic_gotfixup_section (info)->reloc_count * 4))
05830 {
05831 error:
05832 (*_bfd_error_handler)
05833 ("LINKER BUG: .rofixup section size mismatch");
05834 return FALSE;
05835 }
05836
05837 hend = bfd_link_hash_lookup (info->hash, "__ROFIXUP_END__",
05838 FALSE, FALSE, TRUE);
05839 if (hend
05840 && (hend->type == bfd_link_hash_defined
05841 || hend->type == bfd_link_hash_defweak))
05842 {
05843 bfd_vma value =
05844 frvfdpic_gotfixup_section (info)->output_section->vma
05845 + frvfdpic_gotfixup_section (info)->output_offset
05846 + frvfdpic_gotfixup_section (info)->size
05847 - hend->u.def.section->output_section->vma
05848 - hend->u.def.section->output_offset;
05849 BFD_ASSERT (hend->u.def.value == value);
05850 if (hend->u.def.value != value)
05851 goto error;
05852 }
05853 }
05854 }
05855 if (frvfdpic_pltrel_section (info))
05856 {
05857 BFD_ASSERT (frvfdpic_pltrel_section (info)->size
05858 == (frvfdpic_pltrel_section (info)->reloc_count
05859 * sizeof (Elf32_External_Rel)));
05860 }
05861
05862
05863 if (elf_hash_table (info)->dynamic_sections_created)
05864 {
05865 Elf32_External_Dyn * dyncon;
05866 Elf32_External_Dyn * dynconend;
05867
05868 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
05869
05870 BFD_ASSERT (sdyn != NULL);
05871
05872 dyncon = (Elf32_External_Dyn *) sdyn->contents;
05873 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
05874
05875 for (; dyncon < dynconend; dyncon++)
05876 {
05877 Elf_Internal_Dyn dyn;
05878
05879 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
05880
05881 switch (dyn.d_tag)
05882 {
05883 default:
05884 break;
05885
05886 case DT_PLTGOT:
05887 dyn.d_un.d_ptr = frvfdpic_got_section (info)->output_section->vma
05888 + frvfdpic_got_section (info)->output_offset
05889 + frvfdpic_got_initial_offset (info);
05890 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
05891 break;
05892
05893 case DT_JMPREL:
05894 dyn.d_un.d_ptr = frvfdpic_pltrel_section (info)
05895 ->output_section->vma
05896 + frvfdpic_pltrel_section (info)->output_offset;
05897 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
05898 break;
05899
05900 case DT_PLTRELSZ:
05901 dyn.d_un.d_val = frvfdpic_pltrel_section (info)->size;
05902 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
05903 break;
05904 }
05905 }
05906 }
05907
05908 return TRUE;
05909 }
05910
05911
05912
05913
05914 static bfd_boolean
05915 elf32_frvfdpic_adjust_dynamic_symbol
05916 (struct bfd_link_info *info ATTRIBUTE_UNUSED,
05917 struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
05918 {
05919 bfd * dynobj;
05920
05921 dynobj = elf_hash_table (info)->dynobj;
05922
05923
05924 BFD_ASSERT (dynobj != NULL
05925 && (h->u.weakdef != NULL
05926 || (h->def_dynamic
05927 && h->ref_regular
05928 && !h->def_regular)));
05929
05930
05931
05932
05933 if (h->u.weakdef != NULL)
05934 {
05935 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
05936 || h->u.weakdef->root.type == bfd_link_hash_defweak);
05937 h->root.u.def.section = h->u.weakdef->root.u.def.section;
05938 h->root.u.def.value = h->u.weakdef->root.u.def.value;
05939 }
05940
05941 return TRUE;
05942 }
05943
05944
05945
05946 static bfd_boolean
05947 elf32_frvfdpic_finish_dynamic_symbol
05948 (bfd *output_bfd ATTRIBUTE_UNUSED,
05949 struct bfd_link_info *info ATTRIBUTE_UNUSED,
05950 struct elf_link_hash_entry *h ATTRIBUTE_UNUSED,
05951 Elf_Internal_Sym *sym ATTRIBUTE_UNUSED)
05952 {
05953 return TRUE;
05954 }
05955
05956
05957
05958
05959 static bfd_boolean
05960 frvfdpic_elf_use_relative_eh_frame
05961 (bfd *input_bfd ATTRIBUTE_UNUSED,
05962 struct bfd_link_info *info ATTRIBUTE_UNUSED,
05963 asection *eh_frame_section ATTRIBUTE_UNUSED)
05964 {
05965
05966 return FALSE;
05967 }
05968
05969
05970
05971 static bfd_byte
05972 frvfdpic_elf_encode_eh_address (bfd *abfd,
05973 struct bfd_link_info *info,
05974 asection *osec, bfd_vma offset,
05975 asection *loc_sec, bfd_vma loc_offset,
05976 bfd_vma *encoded)
05977 {
05978 struct elf_link_hash_entry *h;
05979
05980 h = elf_hash_table (info)->hgot;
05981 BFD_ASSERT (h && h->root.type == bfd_link_hash_defined);
05982
05983 if (! h || (_frvfdpic_osec_to_segment (abfd, osec)
05984 == _frvfdpic_osec_to_segment (abfd, loc_sec->output_section)))
05985 return _bfd_elf_encode_eh_address (abfd, info, osec, offset,
05986 loc_sec, loc_offset, encoded);
05987
05988 BFD_ASSERT (_frvfdpic_osec_to_segment (abfd, osec)
05989 == (_frvfdpic_osec_to_segment
05990 (abfd, h->root.u.def.section->output_section)));
05991
05992 *encoded = osec->vma + offset
05993 - (h->root.u.def.value
05994 + h->root.u.def.section->output_section->vma
05995 + h->root.u.def.section->output_offset);
05996
05997 return DW_EH_PE_datarel | DW_EH_PE_sdata4;
05998 }
05999
06000
06001
06002
06003
06004
06005
06006
06007
06008
06009
06010
06011
06012
06013
06014
06015
06016
06017
06018
06019
06020
06021
06022
06023
06024
06025
06026
06027
06028
06029
06030
06031
06032
06033
06034
06035
06036
06037
06038
06039
06040
06041
06042
06043
06044
06045
06046
06047
06048
06049
06050
06051
06052
06053
06054
06055
06056
06057
06058
06059
06060
06061
06062
06063
06064
06065
06066
06067
06068
06069
06070
06071
06072
06073
06074
06075
06076
06077
06078
06079
06080
06081
06082
06083
06084
06085
06086
06087
06088
06089
06090
06091
06092
06093
06094
06095
06096
06097
06098
06099
06100
06101
06102
06103
06104 static bfd_boolean
06105 elf32_frv_check_relocs (abfd, info, sec, relocs)
06106 bfd *abfd;
06107 struct bfd_link_info *info;
06108 asection *sec;
06109 const Elf_Internal_Rela *relocs;
06110 {
06111 Elf_Internal_Shdr *symtab_hdr;
06112 struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
06113 const Elf_Internal_Rela *rel;
06114 const Elf_Internal_Rela *rel_end;
06115 bfd *dynobj;
06116 struct frvfdpic_relocs_info *picrel;
06117
06118 if (info->relocatable)
06119 return TRUE;
06120
06121 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
06122 sym_hashes = elf_sym_hashes (abfd);
06123 sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
06124 if (!elf_bad_symtab (abfd))
06125 sym_hashes_end -= symtab_hdr->sh_info;
06126
06127 dynobj = elf_hash_table (info)->dynobj;
06128 rel_end = relocs + sec->reloc_count;
06129 for (rel = relocs; rel < rel_end; rel++)
06130 {
06131 struct elf_link_hash_entry *h;
06132 unsigned long r_symndx;
06133
06134 r_symndx = ELF32_R_SYM (rel->r_info);
06135 if (r_symndx < symtab_hdr->sh_info)
06136 h = NULL;
06137 else
06138 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
06139
06140 switch (ELF32_R_TYPE (rel->r_info))
06141 {
06142 case R_FRV_GETTLSOFF:
06143 case R_FRV_TLSDESC_VALUE:
06144 case R_FRV_GOTTLSDESC12:
06145 case R_FRV_GOTTLSDESCHI:
06146 case R_FRV_GOTTLSDESCLO:
06147 case R_FRV_GOTTLSOFF12:
06148 case R_FRV_GOTTLSOFFHI:
06149 case R_FRV_GOTTLSOFFLO:
06150 case R_FRV_TLSOFF:
06151 case R_FRV_GOT12:
06152 case R_FRV_GOTHI:
06153 case R_FRV_GOTLO:
06154 case R_FRV_FUNCDESC_GOT12:
06155 case R_FRV_FUNCDESC_GOTHI:
06156 case R_FRV_FUNCDESC_GOTLO:
06157 case R_FRV_GOTOFF12:
06158 case R_FRV_GOTOFFHI:
06159 case R_FRV_GOTOFFLO:
06160 case R_FRV_FUNCDESC_GOTOFF12:
06161 case R_FRV_FUNCDESC_GOTOFFHI:
06162 case R_FRV_FUNCDESC_GOTOFFLO:
06163 case R_FRV_FUNCDESC:
06164 case R_FRV_FUNCDESC_VALUE:
06165 case R_FRV_TLSMOFF12:
06166 case R_FRV_TLSMOFFHI:
06167 case R_FRV_TLSMOFFLO:
06168 case R_FRV_TLSMOFF:
06169 if (! IS_FDPIC (abfd))
06170 goto bad_reloc;
06171
06172 case R_FRV_GPREL12:
06173 case R_FRV_GPRELU12:
06174 case R_FRV_GPRELHI:
06175 case R_FRV_GPRELLO:
06176 case R_FRV_LABEL24:
06177 case R_FRV_32:
06178 if (! dynobj)
06179 {
06180 elf_hash_table (info)->dynobj = dynobj = abfd;
06181 if (! _frv_create_got_section (abfd, info))
06182 return FALSE;
06183 }
06184 if (! IS_FDPIC (abfd))
06185 {
06186 picrel = NULL;
06187 break;
06188 }
06189 if (h != NULL)
06190 {
06191 if (h->dynindx == -1)
06192 switch (ELF_ST_VISIBILITY (h->other))
06193 {
06194 case STV_INTERNAL:
06195 case STV_HIDDEN:
06196 break;
06197 default:
06198 bfd_elf_link_record_dynamic_symbol (info, h);
06199 break;
06200 }
06201 picrel
06202 = frvfdpic_relocs_info_for_global (frvfdpic_relocs_info (info),
06203 abfd, h,
06204 rel->r_addend, INSERT);
06205 }
06206 else
06207 picrel = frvfdpic_relocs_info_for_local (frvfdpic_relocs_info
06208 (info), abfd, r_symndx,
06209 rel->r_addend, INSERT);
06210 if (! picrel)
06211 return FALSE;
06212 break;
06213
06214 default:
06215 picrel = NULL;
06216 break;
06217 }
06218
06219 switch (ELF32_R_TYPE (rel->r_info))
06220 {
06221 case R_FRV_LABEL24:
06222 if (IS_FDPIC (abfd))
06223 picrel->call = 1;
06224 break;
06225
06226 case R_FRV_FUNCDESC_VALUE:
06227 picrel->relocsfdv++;
06228 if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
06229 picrel->relocs32--;
06230
06231
06232 case R_FRV_32:
06233 if (! IS_FDPIC (abfd))
06234 break;
06235
06236 picrel->sym = 1;
06237 if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
06238 picrel->relocs32++;
06239 break;
06240
06241 case R_FRV_GOT12:
06242 picrel->got12 = 1;
06243 break;
06244
06245 case R_FRV_GOTHI:
06246 case R_FRV_GOTLO:
06247 picrel->gothilo = 1;
06248 break;
06249
06250 case R_FRV_FUNCDESC_GOT12:
06251 picrel->fdgot12 = 1;
06252 break;
06253
06254 case R_FRV_FUNCDESC_GOTHI:
06255 case R_FRV_FUNCDESC_GOTLO:
06256 picrel->fdgothilo = 1;
06257 break;
06258
06259 case R_FRV_GOTOFF12:
06260 case R_FRV_GOTOFFHI:
06261 case R_FRV_GOTOFFLO:
06262 picrel->gotoff = 1;
06263 break;
06264
06265 case R_FRV_FUNCDESC_GOTOFF12:
06266 picrel->fdgoff12 = 1;
06267 break;
06268
06269 case R_FRV_FUNCDESC_GOTOFFHI:
06270 case R_FRV_FUNCDESC_GOTOFFLO:
06271 picrel->fdgoffhilo = 1;
06272 break;
06273
06274 case R_FRV_FUNCDESC:
06275 picrel->fd = 1;
06276 picrel->relocsfd++;
06277 break;
06278
06279 case R_FRV_GETTLSOFF:
06280 picrel->tlsplt = 1;
06281 break;
06282
06283 case R_FRV_TLSDESC_VALUE:
06284 picrel->relocstlsd++;
06285 goto bad_reloc;
06286
06287 case R_FRV_GOTTLSDESC12:
06288 picrel->tlsdesc12 = 1;
06289 break;
06290
06291 case R_FRV_GOTTLSDESCHI:
06292 case R_FRV_GOTTLSDESCLO:
06293 picrel->tlsdeschilo = 1;
06294 break;
06295
06296 case R_FRV_TLSMOFF12:
06297 case R_FRV_TLSMOFFHI:
06298 case R_FRV_TLSMOFFLO:
06299 case R_FRV_TLSMOFF:
06300 break;
06301
06302 case R_FRV_GOTTLSOFF12:
06303 picrel->tlsoff12 = 1;
06304 info->flags |= DF_STATIC_TLS;
06305 break;
06306
06307 case R_FRV_GOTTLSOFFHI:
06308 case R_FRV_GOTTLSOFFLO:
06309 picrel->tlsoffhilo = 1;
06310 info->flags |= DF_STATIC_TLS;
06311 break;
06312
06313 case R_FRV_TLSOFF:
06314 picrel->relocstlsoff++;
06315 info->flags |= DF_STATIC_TLS;
06316 goto bad_reloc;
06317
06318
06319
06320 case R_FRV_GNU_VTINHERIT:
06321 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
06322 return FALSE;
06323 break;
06324
06325
06326
06327 case R_FRV_GNU_VTENTRY:
06328 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
06329 return FALSE;
06330 break;
06331
06332 case R_FRV_LABEL16:
06333 case R_FRV_LO16:
06334 case R_FRV_HI16:
06335 case R_FRV_GPREL12:
06336 case R_FRV_GPRELU12:
06337 case R_FRV_GPREL32:
06338 case R_FRV_GPRELHI:
06339 case R_FRV_GPRELLO:
06340 case R_FRV_TLSDESC_RELAX:
06341 case R_FRV_GETTLSOFF_RELAX:
06342 case R_FRV_TLSOFF_RELAX:
06343 break;
06344
06345 default:
06346 bad_reloc:
06347 (*_bfd_error_handler)
06348 (_("%B: unsupported relocation type %i"),
06349 abfd, ELF32_R_TYPE (rel->r_info));
06350 return FALSE;
06351 }
06352 }
06353
06354 return TRUE;
06355 }
06356
06357
06358
06359
06360 static int
06361 elf32_frv_machine (abfd)
06362 bfd *abfd;
06363 {
06364 switch (elf_elfheader (abfd)->e_flags & EF_FRV_CPU_MASK)
06365 {
06366 default: break;
06367 case EF_FRV_CPU_FR550: return bfd_mach_fr550;
06368 case EF_FRV_CPU_FR500: return bfd_mach_fr500;
06369 case EF_FRV_CPU_FR450: return bfd_mach_fr450;
06370 case EF_FRV_CPU_FR405: return bfd_mach_fr400;
06371 case EF_FRV_CPU_FR400: return bfd_mach_fr400;
06372 case EF_FRV_CPU_FR300: return bfd_mach_fr300;
06373 case EF_FRV_CPU_SIMPLE: return bfd_mach_frvsimple;
06374 case EF_FRV_CPU_TOMCAT: return bfd_mach_frvtomcat;
06375 }
06376
06377 return bfd_mach_frv;
06378 }
06379
06380
06381
06382 static bfd_boolean
06383 elf32_frv_object_p (abfd)
06384 bfd *abfd;
06385 {
06386 bfd_default_set_arch_mach (abfd, bfd_arch_frv, elf32_frv_machine (abfd));
06387 return (((elf_elfheader (abfd)->e_flags & EF_FRV_FDPIC) != 0)
06388 == (IS_FDPIC (abfd)));
06389 }
06390
06391
06392
06393 static bfd_boolean
06394 frv_elf_set_private_flags (abfd, flags)
06395 bfd *abfd;
06396 flagword flags;
06397 {
06398 elf_elfheader (abfd)->e_flags = flags;
06399 elf_flags_init (abfd) = TRUE;
06400 return TRUE;
06401 }
06402
06403
06404
06405 static bfd_boolean
06406 frv_elf_copy_private_bfd_data (ibfd, obfd)
06407 bfd *ibfd;
06408 bfd *obfd;
06409 {
06410 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
06411 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
06412 return TRUE;
06413
06414 BFD_ASSERT (!elf_flags_init (obfd)
06415 || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
06416
06417 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
06418 elf_flags_init (obfd) = TRUE;
06419 return TRUE;
06420 }
06421
06422
06423
06424
06425 static bfd_boolean
06426 frv_elf_arch_extension_p (flagword base, flagword extension)
06427 {
06428 if (base == extension)
06429 return TRUE;
06430
06431
06432
06433
06434
06435 if (base == EF_FRV_CPU_GENERIC)
06436 return TRUE;
06437
06438 if (extension == EF_FRV_CPU_FR450)
06439 if (base == EF_FRV_CPU_FR400 || base == EF_FRV_CPU_FR405)
06440 return TRUE;
06441
06442 if (extension == EF_FRV_CPU_FR405)
06443 if (base == EF_FRV_CPU_FR400)
06444 return TRUE;
06445
06446 return FALSE;
06447 }
06448
06449 static bfd_boolean
06450 elf32_frvfdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
06451 {
06452 unsigned i;
06453
06454 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
06455 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
06456 return TRUE;
06457
06458 if (! frv_elf_copy_private_bfd_data (ibfd, obfd))
06459 return FALSE;
06460
06461 if (! elf_tdata (ibfd) || ! elf_tdata (ibfd)->phdr
06462 || ! elf_tdata (obfd) || ! elf_tdata (obfd)->phdr)
06463 return TRUE;
06464
06465
06466 for (i = 0; i < elf_elfheader (ibfd)->e_phnum; i++)
06467 if (elf_tdata (ibfd)->phdr[i].p_type == PT_GNU_STACK)
06468 {
06469 Elf_Internal_Phdr *iphdr = &elf_tdata (ibfd)->phdr[i];
06470
06471 for (i = 0; i < elf_elfheader (obfd)->e_phnum; i++)
06472 if (elf_tdata (obfd)->phdr[i].p_type == PT_GNU_STACK)
06473 {
06474 memcpy (&elf_tdata (obfd)->phdr[i], iphdr, sizeof (*iphdr));
06475
06476
06477
06478 if (bfd_seek (obfd, (bfd_signed_vma) get_elf_backend_data (obfd)
06479 ->s->sizeof_ehdr, SEEK_SET) != 0
06480 || get_elf_backend_data (obfd)->s
06481 ->write_out_phdrs (obfd, elf_tdata (obfd)->phdr,
06482 elf_elfheader (obfd)->e_phnum) != 0)
06483 return FALSE;
06484 break;
06485 }
06486
06487 break;
06488 }
06489
06490 return TRUE;
06491 }
06492
06493
06494
06495
06496 static bfd_boolean
06497 frv_elf_merge_private_bfd_data (ibfd, obfd)
06498 bfd *ibfd;
06499 bfd *obfd;
06500 {
06501 flagword old_flags, old_partial;
06502 flagword new_flags, new_partial;
06503 bfd_boolean error = FALSE;
06504 char new_opt[80];
06505 char old_opt[80];
06506
06507 new_opt[0] = old_opt[0] = '\0';
06508 new_flags = elf_elfheader (ibfd)->e_flags;
06509 old_flags = elf_elfheader (obfd)->e_flags;
06510
06511 if (new_flags & EF_FRV_FDPIC)
06512 new_flags &= ~EF_FRV_PIC;
06513
06514 #ifdef DEBUG
06515 (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
06516 old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
06517 bfd_get_filename (ibfd));
06518 #endif
06519
06520 if (!elf_flags_init (obfd))
06521 {
06522 elf_flags_init (obfd) = TRUE;
06523 old_flags = new_flags;
06524 }
06525
06526 else if (new_flags == old_flags)
06527 ;
06528
06529 else
06530 {
06531
06532
06533 new_partial = (new_flags & EF_FRV_GPR_MASK);
06534 old_partial = (old_flags & EF_FRV_GPR_MASK);
06535 if (new_partial == old_partial)
06536 ;
06537
06538 else if (new_partial == 0)
06539 ;
06540
06541 else if (old_partial == 0)
06542 old_flags |= new_partial;
06543
06544 else
06545 {
06546 switch (new_partial)
06547 {
06548 default: strcat (new_opt, " -mgpr-??"); break;
06549 case EF_FRV_GPR_32: strcat (new_opt, " -mgpr-32"); break;
06550 case EF_FRV_GPR_64: strcat (new_opt, " -mgpr-64"); break;
06551 }
06552
06553 switch (old_partial)
06554 {
06555 default: strcat (old_opt, " -mgpr-??"); break;
06556 case EF_FRV_GPR_32: strcat (old_opt, " -mgpr-32"); break;
06557 case EF_FRV_GPR_64: strcat (old_opt, " -mgpr-64"); break;
06558 }
06559 }
06560
06561
06562
06563 new_partial = (new_flags & EF_FRV_FPR_MASK);
06564 old_partial = (old_flags & EF_FRV_FPR_MASK);
06565 if (new_partial == old_partial)
06566 ;
06567
06568 else if (new_partial == 0)
06569 ;
06570
06571 else if (old_partial == 0)
06572 old_flags |= new_partial;
06573
06574 else
06575 {
06576 switch (new_partial)
06577 {
06578 default: strcat (new_opt, " -mfpr-?"); break;
06579 case EF_FRV_FPR_32: strcat (new_opt, " -mfpr-32"); break;
06580 case EF_FRV_FPR_64: strcat (new_opt, " -mfpr-64"); break;
06581 case EF_FRV_FPR_NONE: strcat (new_opt, " -msoft-float"); break;
06582 }
06583
06584 switch (old_partial)
06585 {
06586 default: strcat (old_opt, " -mfpr-?"); break;
06587 case EF_FRV_FPR_32: strcat (old_opt, " -mfpr-32"); break;
06588 case EF_FRV_FPR_64: strcat (old_opt, " -mfpr-64"); break;
06589 case EF_FRV_FPR_NONE: strcat (old_opt, " -msoft-float"); break;
06590 }
06591 }
06592
06593
06594
06595 new_partial = (new_flags & EF_FRV_DWORD_MASK);
06596 old_partial = (old_flags & EF_FRV_DWORD_MASK);
06597 if (new_partial == old_partial)
06598 ;
06599
06600 else if (new_partial == 0)
06601 ;
06602
06603 else if (old_partial == 0)
06604 old_flags |= new_partial;
06605
06606 else
06607 {
06608 switch (new_partial)
06609 {
06610 default: strcat (new_opt, " -mdword-?"); break;
06611 case EF_FRV_DWORD_YES: strcat (new_opt, " -mdword"); break;
06612 case EF_FRV_DWORD_NO: strcat (new_opt, " -mno-dword"); break;
06613 }
06614
06615 switch (old_partial)
06616 {
06617 default: strcat (old_opt, " -mdword-?"); break;
06618 case EF_FRV_DWORD_YES: strcat (old_opt, " -mdword"); break;
06619 case EF_FRV_DWORD_NO: strcat (old_opt, " -mno-dword"); break;
06620 }
06621 }
06622
06623
06624
06625 old_flags |= new_flags & (EF_FRV_DOUBLE
06626 | EF_FRV_MEDIA
06627 | EF_FRV_MULADD
06628 | EF_FRV_NON_PIC_RELOCS);
06629
06630
06631 old_flags = ((old_flags & ~ EF_FRV_G0)
06632 | (old_flags & new_flags & EF_FRV_G0));
06633
06634
06635 old_flags = ((old_flags & ~ EF_FRV_NOPACK)
06636 | (old_flags & new_flags & EF_FRV_NOPACK));
06637
06638
06639
06640 new_partial = (new_flags & EF_FRV_PIC_FLAGS);
06641 old_partial = (old_flags & EF_FRV_PIC_FLAGS);
06642 if ((new_partial == old_partial) || ((new_partial & EF_FRV_LIBPIC) != 0))
06643 ;
06644
06645
06646
06647 else if ((old_partial & EF_FRV_LIBPIC) != 0)
06648 old_flags = (old_flags & ~ EF_FRV_PIC_FLAGS) | new_partial;
06649
06650
06651 else if (new_partial != 0 && old_partial != 0)
06652 old_flags |= new_partial;
06653
06654
06655
06656 else
06657 {
06658 if ((old_flags & EF_FRV_NON_PIC_RELOCS) == 0)
06659 old_flags |= new_partial;
06660 else
06661 {
06662 old_flags &= ~ EF_FRV_PIC_FLAGS;
06663 #ifndef FRV_NO_PIC_ERROR
06664 error = TRUE;
06665 (*_bfd_error_handler)
06666 (_("%s: compiled with %s and linked with modules that use non-pic relocations"),
06667 bfd_get_filename (ibfd),
06668 (new_flags & EF_FRV_BIGPIC) ? "-fPIC" : "-fpic");
06669 #endif
06670 }
06671 }
06672
06673
06674
06675 new_partial = (new_flags & EF_FRV_CPU_MASK);
06676 old_partial = (old_flags & EF_FRV_CPU_MASK);
06677 if (frv_elf_arch_extension_p (new_partial, old_partial))
06678 ;
06679
06680 else if (frv_elf_arch_extension_p (old_partial, new_partial))
06681 old_flags = (old_flags & ~EF_FRV_CPU_MASK) | new_partial;
06682
06683 else
06684 {
06685 switch (new_partial)
06686 {
06687 default: strcat (new_opt, " -mcpu=?"); break;
06688 case EF_FRV_CPU_GENERIC: strcat (new_opt, " -mcpu=frv"); break;
06689 case EF_FRV_CPU_SIMPLE: strcat (new_opt, " -mcpu=simple"); break;
06690 case EF_FRV_CPU_FR550: strcat (new_opt, " -mcpu=fr550"); break;
06691 case EF_FRV_CPU_FR500: strcat (new_opt, " -mcpu=fr500"); break;
06692 case EF_FRV_CPU_FR450: strcat (new_opt, " -mcpu=fr450"); break;
06693 case EF_FRV_CPU_FR405: strcat (new_opt, " -mcpu=fr405"); break;
06694 case EF_FRV_CPU_FR400: strcat (new_opt, " -mcpu=fr400"); break;
06695 case EF_FRV_CPU_FR300: strcat (new_opt, " -mcpu=fr300"); break;
06696 case EF_FRV_CPU_TOMCAT: strcat (new_opt, " -mcpu=tomcat"); break;
06697 }
06698
06699 switch (old_partial)
06700 {
06701 default: strcat (old_opt, " -mcpu=?"); break;
06702 case EF_FRV_CPU_GENERIC: strcat (old_opt, " -mcpu=frv"); break;
06703 case EF_FRV_CPU_SIMPLE: strcat (old_opt, " -mcpu=simple"); break;
06704 case EF_FRV_CPU_FR550: strcat (old_opt, " -mcpu=fr550"); break;
06705 case EF_FRV_CPU_FR500: strcat (old_opt, " -mcpu=fr500"); break;
06706 case EF_FRV_CPU_FR450: strcat (old_opt, " -mcpu=fr450"); break;
06707 case EF_FRV_CPU_FR405: strcat (old_opt, " -mcpu=fr405"); break;
06708 case EF_FRV_CPU_FR400: strcat (old_opt, " -mcpu=fr400"); break;
06709 case EF_FRV_CPU_FR300: strcat (old_opt, " -mcpu=fr300"); break;
06710 case EF_FRV_CPU_TOMCAT: strcat (old_opt, " -mcpu=tomcat"); break;
06711 }
06712 }
06713
06714
06715 if (new_opt[0])
06716 {
06717 error = TRUE;
06718 (*_bfd_error_handler)
06719 (_("%s: compiled with %s and linked with modules compiled with %s"),
06720 bfd_get_filename (ibfd), new_opt, old_opt);
06721 }
06722
06723
06724 new_partial = (new_flags & ~ EF_FRV_ALL_FLAGS);
06725 old_partial = (old_flags & ~ EF_FRV_ALL_FLAGS);
06726 if (new_partial != old_partial)
06727 {
06728 old_flags |= new_partial;
06729 error = TRUE;
06730 (*_bfd_error_handler)
06731 (_("%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"),
06732 bfd_get_filename (ibfd), (long)new_partial, (long)old_partial);
06733 }
06734 }
06735
06736
06737 if ((old_flags & EF_FRV_CPU_MASK) == EF_FRV_CPU_SIMPLE)
06738 old_flags |= EF_FRV_NOPACK;
06739
06740
06741 old_partial = elf_elfheader (obfd)->e_flags & EF_FRV_CPU_MASK;
06742 elf_elfheader (obfd)->e_flags = old_flags;
06743 if (old_partial != (old_flags & EF_FRV_CPU_MASK))
06744 bfd_default_set_arch_mach (obfd, bfd_arch_frv, elf32_frv_machine (obfd));
06745
06746 if (((new_flags & EF_FRV_FDPIC) == 0)
06747 != (! IS_FDPIC (ibfd)))
06748 {
06749 error = TRUE;
06750 if (IS_FDPIC (obfd))
06751 (*_bfd_error_handler)
06752 (_("%s: cannot link non-fdpic object file into fdpic executable"),
06753 bfd_get_filename (ibfd));
06754 else
06755 (*_bfd_error_handler)
06756 (_("%s: cannot link fdpic object file into non-fdpic executable"),
06757 bfd_get_filename (ibfd));
06758 }
06759
06760 if (error)
06761 bfd_set_error (bfd_error_bad_value);
06762
06763 return !error;
06764 }
06765
06766
06767 bfd_boolean
06768 frv_elf_print_private_bfd_data (abfd, ptr)
06769 bfd *abfd;
06770 PTR ptr;
06771 {
06772 FILE *file = (FILE *) ptr;
06773 flagword flags;
06774
06775 BFD_ASSERT (abfd != NULL && ptr != NULL);
06776
06777
06778 _bfd_elf_print_private_bfd_data (abfd, ptr);
06779
06780 flags = elf_elfheader (abfd)->e_flags;
06781 fprintf (file, _("private flags = 0x%lx:"), (long)flags);
06782
06783 switch (flags & EF_FRV_CPU_MASK)
06784 {
06785 default: break;
06786 case EF_FRV_CPU_SIMPLE: fprintf (file, " -mcpu=simple"); break;
06787 case EF_FRV_CPU_FR550: fprintf (file, " -mcpu=fr550"); break;
06788 case EF_FRV_CPU_FR500: fprintf (file, " -mcpu=fr500"); break;
06789 case EF_FRV_CPU_FR450: fprintf (file, " -mcpu=fr450"); break;
06790 case EF_FRV_CPU_FR405: fprintf (file, " -mcpu=fr405"); break;
06791 case EF_FRV_CPU_FR400: fprintf (file, " -mcpu=fr400"); break;
06792 case EF_FRV_CPU_FR300: fprintf (file, " -mcpu=fr300"); break;
06793 case EF_FRV_CPU_TOMCAT: fprintf (file, " -mcpu=tomcat"); break;
06794 }
06795
06796 switch (flags & EF_FRV_GPR_MASK)
06797 {
06798 default: break;
06799 case EF_FRV_GPR_32: fprintf (file, " -mgpr-32"); break;
06800 case EF_FRV_GPR_64: fprintf (file, " -mgpr-64"); break;
06801 }
06802
06803 switch (flags & EF_FRV_FPR_MASK)
06804 {
06805 default: break;
06806 case EF_FRV_FPR_32: fprintf (file, " -mfpr-32"); break;
06807 case EF_FRV_FPR_64: fprintf (file, " -mfpr-64"); break;
06808 case EF_FRV_FPR_NONE: fprintf (file, " -msoft-float"); break;
06809 }
06810
06811 switch (flags & EF_FRV_DWORD_MASK)
06812 {
06813 default: break;
06814 case EF_FRV_DWORD_YES: fprintf (file, " -mdword"); break;
06815 case EF_FRV_DWORD_NO: fprintf (file, " -mno-dword"); break;
06816 }
06817
06818 if (flags & EF_FRV_DOUBLE)
06819 fprintf (file, " -mdouble");
06820
06821 if (flags & EF_FRV_MEDIA)
06822 fprintf (file, " -mmedia");
06823
06824 if (flags & EF_FRV_MULADD)
06825 fprintf (file, " -mmuladd");
06826
06827 if (flags & EF_FRV_PIC)
06828 fprintf (file, " -fpic");
06829
06830 if (flags & EF_FRV_BIGPIC)
06831 fprintf (file, " -fPIC");
06832
06833 if (flags & EF_FRV_LIBPIC)
06834 fprintf (file, " -mlibrary-pic");
06835
06836 if (flags & EF_FRV_FDPIC)
06837 fprintf (file, " -mfdpic");
06838
06839 if (flags & EF_FRV_NON_PIC_RELOCS)
06840 fprintf (file, " non-pic relocations");
06841
06842 if (flags & EF_FRV_G0)
06843 fprintf (file, " -G0");
06844
06845 fputc ('\n', file);
06846 return TRUE;
06847 }
06848
06849
06850 #define ELF_ARCH bfd_arch_frv
06851 #define ELF_MACHINE_CODE EM_CYGNUS_FRV
06852 #define ELF_MAXPAGESIZE 0x1000
06853
06854 #define TARGET_BIG_SYM bfd_elf32_frv_vec
06855 #define TARGET_BIG_NAME "elf32-frv"
06856
06857 #define elf_info_to_howto frv_info_to_howto_rela
06858 #define elf_backend_relocate_section elf32_frv_relocate_section
06859 #define elf_backend_gc_mark_hook elf32_frv_gc_mark_hook
06860 #define elf_backend_gc_sweep_hook elf32_frv_gc_sweep_hook
06861 #define elf_backend_check_relocs elf32_frv_check_relocs
06862 #define elf_backend_object_p elf32_frv_object_p
06863 #define elf_backend_add_symbol_hook elf32_frv_add_symbol_hook
06864
06865 #define elf_backend_can_gc_sections 1
06866 #define elf_backend_rela_normal 1
06867
06868 #define bfd_elf32_bfd_reloc_type_lookup frv_reloc_type_lookup
06869 #define bfd_elf32_bfd_set_private_flags frv_elf_set_private_flags
06870 #define bfd_elf32_bfd_copy_private_bfd_data frv_elf_copy_private_bfd_data
06871 #define bfd_elf32_bfd_merge_private_bfd_data frv_elf_merge_private_bfd_data
06872 #define bfd_elf32_bfd_print_private_bfd_data frv_elf_print_private_bfd_data
06873
06874 #define elf_backend_want_got_sym 1
06875 #define elf_backend_got_header_size 0
06876 #define elf_backend_want_got_plt 0
06877 #define elf_backend_plt_readonly 1
06878 #define elf_backend_want_plt_sym 0
06879 #define elf_backend_plt_header_size 0
06880
06881 #define elf_backend_finish_dynamic_sections \
06882 elf32_frv_finish_dynamic_sections
06883
06884 #include "elf32-target.h"
06885
06886 #undef ELF_MAXPAGESIZE
06887 #define ELF_MAXPAGESIZE 0x4000
06888
06889 #undef TARGET_BIG_SYM
06890 #define TARGET_BIG_SYM bfd_elf32_frvfdpic_vec
06891 #undef TARGET_BIG_NAME
06892 #define TARGET_BIG_NAME "elf32-frvfdpic"
06893 #undef elf32_bed
06894 #define elf32_bed elf32_frvfdpic_bed
06895
06896 #undef elf_info_to_howto_rel
06897 #define elf_info_to_howto_rel frvfdpic_info_to_howto_rel
06898
06899 #undef bfd_elf32_bfd_link_hash_table_create
06900 #define bfd_elf32_bfd_link_hash_table_create \
06901 frvfdpic_elf_link_hash_table_create
06902 #undef elf_backend_always_size_sections
06903 #define elf_backend_always_size_sections \
06904 elf32_frvfdpic_always_size_sections
06905 #undef elf_backend_modify_segment_map
06906 #define elf_backend_modify_segment_map \
06907 elf32_frvfdpic_modify_segment_map
06908 #undef bfd_elf32_bfd_copy_private_bfd_data
06909 #define bfd_elf32_bfd_copy_private_bfd_data \
06910 elf32_frvfdpic_copy_private_bfd_data
06911
06912 #undef elf_backend_create_dynamic_sections
06913 #define elf_backend_create_dynamic_sections \
06914 elf32_frvfdpic_create_dynamic_sections
06915 #undef elf_backend_adjust_dynamic_symbol
06916 #define elf_backend_adjust_dynamic_symbol \
06917 elf32_frvfdpic_adjust_dynamic_symbol
06918 #undef elf_backend_size_dynamic_sections
06919 #define elf_backend_size_dynamic_sections \
06920 elf32_frvfdpic_size_dynamic_sections
06921 #undef bfd_elf32_bfd_relax_section
06922 #define bfd_elf32_bfd_relax_section \
06923 elf32_frvfdpic_relax_section
06924 #undef elf_backend_finish_dynamic_symbol
06925 #define elf_backend_finish_dynamic_symbol \
06926 elf32_frvfdpic_finish_dynamic_symbol
06927 #undef elf_backend_finish_dynamic_sections
06928 #define elf_backend_finish_dynamic_sections \
06929 elf32_frvfdpic_finish_dynamic_sections
06930
06931 #undef elf_backend_can_make_relative_eh_frame
06932 #define elf_backend_can_make_relative_eh_frame \
06933 frvfdpic_elf_use_relative_eh_frame
06934 #undef elf_backend_can_make_lsda_relative_eh_frame
06935 #define elf_backend_can_make_lsda_relative_eh_frame \
06936 frvfdpic_elf_use_relative_eh_frame
06937 #undef elf_backend_encode_eh_address
06938 #define elf_backend_encode_eh_address \
06939 frvfdpic_elf_encode_eh_address
06940
06941 #undef elf_backend_may_use_rel_p
06942 #define elf_backend_may_use_rel_p 1
06943 #undef elf_backend_may_use_rela_p
06944 #define elf_backend_may_use_rela_p 1
06945
06946 #undef elf_backend_default_use_rela_p
06947 #define elf_backend_default_use_rela_p 1
06948
06949 #undef elf_backend_omit_section_dynsym
06950 #define elf_backend_omit_section_dynsym _frvfdpic_link_omit_section_dynsym
06951
06952 #include "elf32-target.h"