00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #define SH64_ELF64
00026
00027 #include "bfd.h"
00028 #include "sysdep.h"
00029 #include "bfdlink.h"
00030 #include "libbfd.h"
00031 #include "elf-bfd.h"
00032 #include "elf/sh.h"
00033
00034
00035
00036
00037
00038 #define DATALABEL_SUFFIX " DL"
00039
00040 #define GOT_BIAS (-((long)-32768))
00041
00042 #define PLT_ENTRY_SIZE 64
00043
00044
00045 #define elf_sh64_sizeof_plt(info) PLT_ENTRY_SIZE
00046
00047
00048 #define elf_sh64_plt_plt0_offset(info) 32
00049
00050
00051 #define elf_sh64_plt0_gotplt_offset(info) 0
00052
00053
00054 #define elf_sh64_plt_temp_offset(info) 33
00055
00056
00057 #define elf_sh64_plt_symbol_offset(info) 0
00058
00059
00060 #define elf_sh64_plt_reloc_offset(info) (info->shared ? 52 : 44)
00061
00062 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 struct elf_sh64_pcrel_relocs_copied
00074 {
00075
00076 struct elf_sh64_pcrel_relocs_copied *next;
00077
00078 asection *section;
00079
00080 bfd_size_type count;
00081 };
00082
00083
00084
00085 struct elf_sh64_link_hash_entry
00086 {
00087 struct elf_link_hash_entry root;
00088
00089 bfd_vma datalabel_got_offset;
00090
00091
00092 struct elf_sh64_pcrel_relocs_copied *pcrel_relocs_copied;
00093 };
00094
00095
00096
00097 struct elf_sh64_link_hash_table
00098 {
00099 struct elf_link_hash_table root;
00100 };
00101
00102
00103
00104 #define sh64_elf64_link_hash_traverse(table, func, info) \
00105 (elf_link_hash_traverse \
00106 (&(table)->root, \
00107 (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
00108 (info)))
00109
00110
00111
00112 #define sh64_elf64_hash_table(p) \
00113 ((struct elf_sh64_link_hash_table *) ((p)->hash))
00114
00115 static bfd_reloc_status_type sh_elf64_ignore_reloc
00116 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00117 static bfd_reloc_status_type sh_elf64_reloc
00118 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00119
00120 static reloc_howto_type sh_elf64_howto_table[] = {
00121
00122 HOWTO (R_SH_NONE,
00123 0,
00124 0,
00125 0,
00126 FALSE,
00127 0,
00128 complain_overflow_dont,
00129 sh_elf64_ignore_reloc,
00130 "R_SH_NONE",
00131 FALSE,
00132 0,
00133 0,
00134 FALSE),
00135
00136
00137
00138 HOWTO (R_SH_DIR32,
00139 0,
00140 2,
00141 32,
00142 FALSE,
00143 0,
00144 complain_overflow_bitfield,
00145 sh_elf64_reloc,
00146 "R_SH_DIR32",
00147 TRUE,
00148 0xffffffff,
00149 0xffffffff,
00150 FALSE),
00151
00152
00153 HOWTO (R_SH_REL32,
00154 0,
00155 2,
00156 32,
00157 TRUE,
00158 0,
00159 complain_overflow_signed,
00160 sh_elf64_ignore_reloc,
00161 "R_SH_REL32",
00162 FALSE,
00163 0,
00164 0xffffffff,
00165 TRUE),
00166
00167
00168 EMPTY_HOWTO (3),
00169
00170
00171 EMPTY_HOWTO (4),
00172
00173
00174 EMPTY_HOWTO (5),
00175
00176
00177 EMPTY_HOWTO (6),
00178
00179
00180 EMPTY_HOWTO (7),
00181
00182
00183 EMPTY_HOWTO (8),
00184
00185
00186 EMPTY_HOWTO (9),
00187
00188 EMPTY_HOWTO (10),
00189 EMPTY_HOWTO (11),
00190 EMPTY_HOWTO (12),
00191 EMPTY_HOWTO (13),
00192 EMPTY_HOWTO (14),
00193 EMPTY_HOWTO (15),
00194 EMPTY_HOWTO (16),
00195 EMPTY_HOWTO (17),
00196 EMPTY_HOWTO (18),
00197 EMPTY_HOWTO (19),
00198 EMPTY_HOWTO (20),
00199 EMPTY_HOWTO (21),
00200 EMPTY_HOWTO (22),
00201 EMPTY_HOWTO (23),
00202 EMPTY_HOWTO (24),
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 HOWTO (R_SH_SWITCH16,
00213 0,
00214 1,
00215 16,
00216 FALSE,
00217 0,
00218 complain_overflow_unsigned,
00219 sh_elf64_ignore_reloc,
00220 "R_SH_SWITCH16",
00221 FALSE,
00222 0,
00223 0,
00224 TRUE),
00225
00226
00227
00228
00229 HOWTO (R_SH_SWITCH32,
00230 0,
00231 2,
00232 32,
00233 FALSE,
00234 0,
00235 complain_overflow_unsigned,
00236 sh_elf64_ignore_reloc,
00237 "R_SH_SWITCH32",
00238 FALSE,
00239 0,
00240 0,
00241 TRUE),
00242
00243
00244 EMPTY_HOWTO (27),
00245
00246
00247 EMPTY_HOWTO (28),
00248
00249
00250
00251
00252 EMPTY_HOWTO (29),
00253
00254
00255
00256
00257 EMPTY_HOWTO (30),
00258
00259
00260
00261
00262 EMPTY_HOWTO (31),
00263
00264
00265
00266
00267 EMPTY_HOWTO (32),
00268
00269
00270
00271
00272 HOWTO (R_SH_SWITCH8,
00273 0,
00274 0,
00275 8,
00276 FALSE,
00277 0,
00278 complain_overflow_unsigned,
00279 sh_elf64_ignore_reloc,
00280 "R_SH_SWITCH8",
00281 FALSE,
00282 0,
00283 0,
00284 TRUE),
00285
00286
00287 HOWTO (R_SH_GNU_VTINHERIT,
00288 0,
00289 2,
00290 0,
00291 FALSE,
00292 0,
00293 complain_overflow_dont,
00294 NULL,
00295 "R_SH_GNU_VTINHERIT",
00296 FALSE,
00297 0,
00298 0,
00299 FALSE),
00300
00301
00302 HOWTO (R_SH_GNU_VTENTRY,
00303 0,
00304 2,
00305 0,
00306 FALSE,
00307 0,
00308 complain_overflow_dont,
00309 _bfd_elf_rel_vtable_reloc_fn,
00310 "R_SH_GNU_VTENTRY",
00311 FALSE,
00312 0,
00313 0,
00314 FALSE),
00315
00316
00317 EMPTY_HOWTO (36),
00318
00319
00320 EMPTY_HOWTO (37),
00321
00322 EMPTY_HOWTO (38),
00323 EMPTY_HOWTO (39),
00324 EMPTY_HOWTO (40),
00325 EMPTY_HOWTO (41),
00326 EMPTY_HOWTO (42),
00327 EMPTY_HOWTO (43),
00328 EMPTY_HOWTO (44),
00329
00330
00331 HOWTO (R_SH_DIR5U,
00332 0,
00333 2,
00334 5,
00335 FALSE,
00336 10,
00337 complain_overflow_unsigned,
00338 bfd_elf_generic_reloc,
00339 "R_SH_DIR5U",
00340 FALSE,
00341 0,
00342 0xfc00,
00343 FALSE),
00344
00345
00346 HOWTO (R_SH_DIR6U,
00347 0,
00348 2,
00349 6,
00350 FALSE,
00351 10,
00352 complain_overflow_unsigned,
00353 bfd_elf_generic_reloc,
00354 "R_SH_DIR6U",
00355 FALSE,
00356 0,
00357 0xfc00,
00358 FALSE),
00359
00360
00361 HOWTO (R_SH_DIR6S,
00362 0,
00363 2,
00364 6,
00365 FALSE,
00366 10,
00367 complain_overflow_signed,
00368 bfd_elf_generic_reloc,
00369 "R_SH_DIR6S",
00370 FALSE,
00371 0,
00372 0xfc00,
00373 FALSE),
00374
00375
00376 HOWTO (R_SH_DIR10S,
00377 0,
00378 2,
00379 10,
00380 FALSE,
00381 10,
00382 complain_overflow_signed,
00383 bfd_elf_generic_reloc,
00384 "R_SH_DIR10S",
00385 FALSE,
00386 0,
00387 0xffc00,
00388 FALSE),
00389
00390
00391 HOWTO (R_SH_DIR10SW,
00392 1,
00393 2,
00394 11,
00395 FALSE,
00396 10,
00397 complain_overflow_signed,
00398 bfd_elf_generic_reloc,
00399 "R_SH_DIR10SW",
00400 FALSE,
00401 0,
00402 0xffc00,
00403 FALSE),
00404
00405
00406 HOWTO (R_SH_DIR10SL,
00407 2,
00408 2,
00409 12,
00410 FALSE,
00411 10,
00412 complain_overflow_signed,
00413 bfd_elf_generic_reloc,
00414 "R_SH_DIR10SL",
00415 FALSE,
00416 0,
00417 0xffc00,
00418 FALSE),
00419
00420
00421 HOWTO (R_SH_DIR10SQ,
00422 3,
00423 2,
00424 13,
00425 FALSE,
00426 10,
00427 complain_overflow_signed,
00428 bfd_elf_generic_reloc,
00429 "R_SH_DIR10SQ",
00430 FALSE,
00431 0,
00432 0xffc00,
00433 FALSE),
00434
00435 EMPTY_HOWTO (52),
00436 EMPTY_HOWTO (53),
00437 EMPTY_HOWTO (54),
00438 EMPTY_HOWTO (55),
00439 EMPTY_HOWTO (56),
00440 EMPTY_HOWTO (57),
00441 EMPTY_HOWTO (58),
00442 EMPTY_HOWTO (59),
00443 EMPTY_HOWTO (60),
00444 EMPTY_HOWTO (61),
00445 EMPTY_HOWTO (62),
00446 EMPTY_HOWTO (63),
00447 EMPTY_HOWTO (64),
00448 EMPTY_HOWTO (65),
00449 EMPTY_HOWTO (66),
00450 EMPTY_HOWTO (67),
00451 EMPTY_HOWTO (68),
00452 EMPTY_HOWTO (69),
00453 EMPTY_HOWTO (70),
00454 EMPTY_HOWTO (71),
00455 EMPTY_HOWTO (72),
00456 EMPTY_HOWTO (73),
00457 EMPTY_HOWTO (74),
00458 EMPTY_HOWTO (75),
00459 EMPTY_HOWTO (76),
00460 EMPTY_HOWTO (77),
00461 EMPTY_HOWTO (78),
00462 EMPTY_HOWTO (79),
00463 EMPTY_HOWTO (80),
00464 EMPTY_HOWTO (81),
00465 EMPTY_HOWTO (82),
00466 EMPTY_HOWTO (83),
00467 EMPTY_HOWTO (84),
00468 EMPTY_HOWTO (85),
00469 EMPTY_HOWTO (86),
00470 EMPTY_HOWTO (87),
00471 EMPTY_HOWTO (88),
00472 EMPTY_HOWTO (89),
00473 EMPTY_HOWTO (90),
00474 EMPTY_HOWTO (91),
00475 EMPTY_HOWTO (92),
00476 EMPTY_HOWTO (93),
00477 EMPTY_HOWTO (94),
00478 EMPTY_HOWTO (95),
00479 EMPTY_HOWTO (96),
00480 EMPTY_HOWTO (97),
00481 EMPTY_HOWTO (98),
00482 EMPTY_HOWTO (99),
00483 EMPTY_HOWTO (100),
00484 EMPTY_HOWTO (101),
00485 EMPTY_HOWTO (102),
00486 EMPTY_HOWTO (103),
00487 EMPTY_HOWTO (104),
00488 EMPTY_HOWTO (105),
00489 EMPTY_HOWTO (106),
00490 EMPTY_HOWTO (107),
00491 EMPTY_HOWTO (108),
00492 EMPTY_HOWTO (109),
00493 EMPTY_HOWTO (110),
00494 EMPTY_HOWTO (111),
00495 EMPTY_HOWTO (112),
00496 EMPTY_HOWTO (113),
00497 EMPTY_HOWTO (114),
00498 EMPTY_HOWTO (115),
00499 EMPTY_HOWTO (116),
00500 EMPTY_HOWTO (117),
00501 EMPTY_HOWTO (118),
00502 EMPTY_HOWTO (119),
00503 EMPTY_HOWTO (120),
00504 EMPTY_HOWTO (121),
00505 EMPTY_HOWTO (122),
00506 EMPTY_HOWTO (123),
00507 EMPTY_HOWTO (124),
00508 EMPTY_HOWTO (125),
00509 EMPTY_HOWTO (126),
00510 EMPTY_HOWTO (127),
00511 EMPTY_HOWTO (128),
00512 EMPTY_HOWTO (129),
00513 EMPTY_HOWTO (130),
00514 EMPTY_HOWTO (131),
00515 EMPTY_HOWTO (132),
00516 EMPTY_HOWTO (133),
00517 EMPTY_HOWTO (134),
00518 EMPTY_HOWTO (135),
00519 EMPTY_HOWTO (136),
00520 EMPTY_HOWTO (137),
00521 EMPTY_HOWTO (138),
00522 EMPTY_HOWTO (139),
00523 EMPTY_HOWTO (140),
00524 EMPTY_HOWTO (141),
00525 EMPTY_HOWTO (142),
00526 EMPTY_HOWTO (143),
00527 EMPTY_HOWTO (144),
00528 EMPTY_HOWTO (145),
00529 EMPTY_HOWTO (146),
00530 EMPTY_HOWTO (147),
00531 EMPTY_HOWTO (148),
00532 EMPTY_HOWTO (149),
00533 EMPTY_HOWTO (150),
00534 EMPTY_HOWTO (151),
00535 EMPTY_HOWTO (152),
00536 EMPTY_HOWTO (153),
00537 EMPTY_HOWTO (154),
00538 EMPTY_HOWTO (155),
00539 EMPTY_HOWTO (156),
00540 EMPTY_HOWTO (157),
00541 EMPTY_HOWTO (158),
00542 EMPTY_HOWTO (159),
00543
00544
00545
00546
00547 EMPTY_HOWTO (160),
00548 EMPTY_HOWTO (161),
00549 EMPTY_HOWTO (162),
00550 EMPTY_HOWTO (163),
00551 EMPTY_HOWTO (164),
00552 EMPTY_HOWTO (165),
00553 EMPTY_HOWTO (166),
00554 EMPTY_HOWTO (167),
00555 EMPTY_HOWTO (168),
00556
00557
00558
00559 HOWTO (R_SH_GOT_LOW16,
00560 0,
00561 2,
00562 64,
00563 FALSE,
00564 10,
00565 complain_overflow_dont,
00566 bfd_elf_generic_reloc,
00567 "R_SH_GOT_LOW16",
00568 FALSE,
00569 0,
00570 0x3fffc00,
00571 FALSE),
00572
00573
00574 HOWTO (R_SH_GOT_MEDLOW16,
00575 16,
00576 2,
00577 64,
00578 FALSE,
00579 10,
00580 complain_overflow_dont,
00581 bfd_elf_generic_reloc,
00582 "R_SH_GOT_MEDLOW16",
00583 FALSE,
00584 0,
00585 0x3fffc00,
00586 FALSE),
00587
00588
00589 HOWTO (R_SH_GOT_MEDHI16,
00590 32,
00591 2,
00592 64,
00593 FALSE,
00594 10,
00595 complain_overflow_dont,
00596 bfd_elf_generic_reloc,
00597 "R_SH_GOT_MEDHI16",
00598 FALSE,
00599 0,
00600 0x3fffc00,
00601 FALSE),
00602
00603
00604 HOWTO (R_SH_GOT_HI16,
00605 48,
00606 2,
00607 64,
00608 FALSE,
00609 10,
00610 complain_overflow_dont,
00611 bfd_elf_generic_reloc,
00612 "R_SH_GOT_HI16",
00613 FALSE,
00614 0,
00615 0x3fffc00,
00616 FALSE),
00617
00618
00619 HOWTO (R_SH_GOTPLT_LOW16,
00620 0,
00621 2,
00622 64,
00623 FALSE,
00624 10,
00625 complain_overflow_dont,
00626 bfd_elf_generic_reloc,
00627 "R_SH_GOTPLT_LOW16",
00628 FALSE,
00629 0,
00630 0x3fffc00,
00631 FALSE),
00632
00633
00634 HOWTO (R_SH_GOTPLT_MEDLOW16,
00635 16,
00636 2,
00637 64,
00638 FALSE,
00639 10,
00640 complain_overflow_dont,
00641 bfd_elf_generic_reloc,
00642 "R_SH_GOTPLT_MEDLOW16",
00643 FALSE,
00644 0,
00645 0x3fffc00,
00646 FALSE),
00647
00648
00649 HOWTO (R_SH_GOTPLT_MEDHI16,
00650 32,
00651 2,
00652 64,
00653 FALSE,
00654 10,
00655 complain_overflow_dont,
00656 bfd_elf_generic_reloc,
00657 "R_SH_GOTPLT_MEDHI16",
00658 FALSE,
00659 0,
00660 0x3fffc00,
00661 FALSE),
00662
00663
00664 HOWTO (R_SH_GOTPLT_HI16,
00665 48,
00666 2,
00667 64,
00668 FALSE,
00669 10,
00670 complain_overflow_dont,
00671 bfd_elf_generic_reloc,
00672 "R_SH_GOTPLT_HI16",
00673 FALSE,
00674 0,
00675 0x3fffc00,
00676 FALSE),
00677
00678
00679 HOWTO (R_SH_PLT_LOW16,
00680 0,
00681 2,
00682 64,
00683 TRUE,
00684 10,
00685 complain_overflow_dont,
00686 bfd_elf_generic_reloc,
00687 "R_SH_PLT_LOW16",
00688 FALSE,
00689 0,
00690 0x3fffc00,
00691 TRUE),
00692
00693
00694 HOWTO (R_SH_PLT_MEDLOW16,
00695 16,
00696 2,
00697 64,
00698 TRUE,
00699 10,
00700 complain_overflow_dont,
00701 bfd_elf_generic_reloc,
00702 "R_SH_PLT_MEDLOW16",
00703 FALSE,
00704 0,
00705 0x3fffc00,
00706 TRUE),
00707
00708
00709 HOWTO (R_SH_PLT_MEDHI16,
00710 32,
00711 2,
00712 64,
00713 TRUE,
00714 10,
00715 complain_overflow_dont,
00716 bfd_elf_generic_reloc,
00717 "R_SH_PLT_MEDHI16",
00718 FALSE,
00719 0,
00720 0x3fffc00,
00721 TRUE),
00722
00723
00724 HOWTO (R_SH_PLT_HI16,
00725 48,
00726 2,
00727 64,
00728 TRUE,
00729 10,
00730 complain_overflow_dont,
00731 bfd_elf_generic_reloc,
00732 "R_SH_PLT_HI16",
00733 FALSE,
00734 0,
00735 0x3fffc00,
00736 TRUE),
00737
00738
00739 HOWTO (R_SH_GOTOFF_LOW16,
00740 0,
00741 2,
00742 64,
00743 FALSE,
00744 10,
00745 complain_overflow_dont,
00746 bfd_elf_generic_reloc,
00747 "R_SH_GOTOFF_LOW16",
00748 FALSE,
00749 0,
00750 0x3fffc00,
00751 FALSE),
00752
00753
00754 HOWTO (R_SH_GOTOFF_MEDLOW16,
00755 16,
00756 2,
00757 64,
00758 FALSE,
00759 10,
00760 complain_overflow_dont,
00761 bfd_elf_generic_reloc,
00762 "R_SH_GOTOFF_MEDLOW16",
00763 FALSE,
00764 0,
00765 0x3fffc00,
00766 FALSE),
00767
00768
00769 HOWTO (R_SH_GOTOFF_MEDHI16,
00770 32,
00771 2,
00772 64,
00773 FALSE,
00774 10,
00775 complain_overflow_dont,
00776 bfd_elf_generic_reloc,
00777 "R_SH_GOTOFF_MEDHI16",
00778 FALSE,
00779 0,
00780 0x3fffc00,
00781 FALSE),
00782
00783
00784 HOWTO (R_SH_GOTOFF_HI16,
00785 48,
00786 2,
00787 64,
00788 FALSE,
00789 10,
00790 complain_overflow_dont,
00791 bfd_elf_generic_reloc,
00792 "R_SH_GOTOFF_HI16",
00793 FALSE,
00794 0,
00795 0x3fffc00,
00796 FALSE),
00797
00798
00799 HOWTO (R_SH_GOTPC_LOW16,
00800 0,
00801 2,
00802 64,
00803 TRUE,
00804 10,
00805 complain_overflow_dont,
00806 bfd_elf_generic_reloc,
00807 "R_SH_GOTPC_LOW16",
00808 FALSE,
00809 0,
00810 0x3fffc00,
00811 TRUE),
00812
00813
00814 HOWTO (R_SH_GOTPC_MEDLOW16,
00815 16,
00816 2,
00817 64,
00818 TRUE,
00819 10,
00820 complain_overflow_dont,
00821 bfd_elf_generic_reloc,
00822 "R_SH_GOTPC_MEDLOW16",
00823 FALSE,
00824 0,
00825 0x3fffc00,
00826 TRUE),
00827
00828
00829 HOWTO (R_SH_GOTPC_MEDHI16,
00830 32,
00831 2,
00832 64,
00833 TRUE,
00834 10,
00835 complain_overflow_dont,
00836 bfd_elf_generic_reloc,
00837 "R_SH_GOTPC_MEDHI16",
00838 FALSE,
00839 0,
00840 0x3fffc00,
00841 TRUE),
00842
00843
00844 HOWTO (R_SH_GOTPC_HI16,
00845 48,
00846 2,
00847 64,
00848 TRUE,
00849 10,
00850 complain_overflow_dont,
00851 bfd_elf_generic_reloc,
00852 "R_SH_GOTPC_HI16",
00853 FALSE,
00854 0,
00855 0x3fffc00,
00856 TRUE),
00857
00858
00859 HOWTO (R_SH_GOT10BY4,
00860 2,
00861 2,
00862 12,
00863 FALSE,
00864 10,
00865 complain_overflow_signed,
00866 bfd_elf_generic_reloc,
00867 "R_SH_GOT10BY4",
00868 FALSE,
00869 0,
00870 0xffc00,
00871 FALSE),
00872
00873
00874 HOWTO (R_SH_GOTPLT10BY4,
00875 2,
00876 2,
00877 12,
00878 FALSE,
00879 10,
00880 complain_overflow_signed,
00881 bfd_elf_generic_reloc,
00882 "R_SH_GOTPLT10BY4",
00883 FALSE,
00884 0,
00885 0xffc00,
00886 FALSE),
00887
00888
00889 HOWTO (R_SH_GOT10BY8,
00890 3,
00891 2,
00892 13,
00893 FALSE,
00894 10,
00895 complain_overflow_signed,
00896 bfd_elf_generic_reloc,
00897 "R_SH_GOT10BY8",
00898 FALSE,
00899 0,
00900 0xffc00,
00901 FALSE),
00902
00903
00904 HOWTO (R_SH_GOTPLT10BY8,
00905 3,
00906 2,
00907 13,
00908 FALSE,
00909 10,
00910 complain_overflow_signed,
00911 bfd_elf_generic_reloc,
00912 "R_SH_GOTPLT10BY8",
00913 FALSE,
00914 0,
00915 0xffc00,
00916 FALSE),
00917
00918 HOWTO (R_SH_COPY64,
00919 0,
00920 4,
00921 64,
00922 FALSE,
00923 0,
00924 complain_overflow_dont,
00925 bfd_elf_generic_reloc,
00926 "R_SH_COPY64",
00927 FALSE,
00928 0,
00929 ((bfd_vma) 0) - 1,
00930 FALSE),
00931
00932 HOWTO (R_SH_GLOB_DAT64,
00933 0,
00934 4,
00935 64,
00936 FALSE,
00937 0,
00938 complain_overflow_dont,
00939 bfd_elf_generic_reloc,
00940 "R_SH_GLOB_DAT64",
00941 FALSE,
00942 0,
00943 ((bfd_vma) 0) - 1,
00944 FALSE),
00945
00946 HOWTO (R_SH_JMP_SLOT64,
00947 0,
00948 4,
00949 64,
00950 FALSE,
00951 0,
00952 complain_overflow_dont,
00953 bfd_elf_generic_reloc,
00954 "R_SH_JMP_SLOT64",
00955 FALSE,
00956 0,
00957 ((bfd_vma) 0) - 1,
00958 FALSE),
00959
00960 HOWTO (R_SH_RELATIVE64,
00961 0,
00962 4,
00963 64,
00964 FALSE,
00965 0,
00966 complain_overflow_dont,
00967 bfd_elf_generic_reloc,
00968 "R_SH_RELATIVE64",
00969 FALSE,
00970 0,
00971 ((bfd_vma) 0) - 1,
00972 FALSE),
00973
00974 EMPTY_HOWTO (197),
00975 EMPTY_HOWTO (198),
00976 EMPTY_HOWTO (199),
00977 EMPTY_HOWTO (200),
00978 EMPTY_HOWTO (201),
00979 EMPTY_HOWTO (202),
00980 EMPTY_HOWTO (203),
00981 EMPTY_HOWTO (204),
00982 EMPTY_HOWTO (205),
00983 EMPTY_HOWTO (206),
00984 EMPTY_HOWTO (207),
00985 EMPTY_HOWTO (208),
00986 EMPTY_HOWTO (209),
00987 EMPTY_HOWTO (210),
00988 EMPTY_HOWTO (211),
00989 EMPTY_HOWTO (212),
00990 EMPTY_HOWTO (213),
00991 EMPTY_HOWTO (214),
00992 EMPTY_HOWTO (215),
00993 EMPTY_HOWTO (216),
00994 EMPTY_HOWTO (217),
00995 EMPTY_HOWTO (218),
00996 EMPTY_HOWTO (219),
00997 EMPTY_HOWTO (220),
00998 EMPTY_HOWTO (221),
00999 EMPTY_HOWTO (222),
01000 EMPTY_HOWTO (223),
01001 EMPTY_HOWTO (224),
01002 EMPTY_HOWTO (225),
01003 EMPTY_HOWTO (226),
01004 EMPTY_HOWTO (227),
01005 EMPTY_HOWTO (228),
01006 EMPTY_HOWTO (229),
01007 EMPTY_HOWTO (230),
01008 EMPTY_HOWTO (231),
01009 EMPTY_HOWTO (232),
01010 EMPTY_HOWTO (233),
01011 EMPTY_HOWTO (234),
01012 EMPTY_HOWTO (235),
01013 EMPTY_HOWTO (236),
01014 EMPTY_HOWTO (237),
01015 EMPTY_HOWTO (238),
01016 EMPTY_HOWTO (239),
01017 EMPTY_HOWTO (240),
01018 EMPTY_HOWTO (241),
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029 HOWTO (R_SH_SHMEDIA_CODE,
01030 0,
01031 1,
01032 0,
01033 FALSE,
01034 0,
01035 complain_overflow_unsigned,
01036 sh_elf64_ignore_reloc,
01037 "R_SH_SHMEDIA_CODE",
01038 FALSE,
01039 0,
01040 0,
01041 FALSE),
01042
01043
01044
01045
01046 HOWTO (R_SH_PT_16,
01047 2,
01048 2,
01049 18,
01050 TRUE,
01051 10,
01052 complain_overflow_signed,
01053 bfd_elf_generic_reloc,
01054 "R_SH_PT_16",
01055 FALSE,
01056 0,
01057 0x3fffc00,
01058 TRUE),
01059
01060
01061 HOWTO (R_SH_IMMS16,
01062 0,
01063 2,
01064 16,
01065 FALSE,
01066 10,
01067 complain_overflow_signed,
01068 bfd_elf_generic_reloc,
01069 "R_SH_IMMS16",
01070 FALSE,
01071 0,
01072 0x3fffc00,
01073 FALSE),
01074
01075
01076 HOWTO (R_SH_IMMU16,
01077 0,
01078 2,
01079 16,
01080 FALSE,
01081 10,
01082 complain_overflow_unsigned,
01083 bfd_elf_generic_reloc,
01084 "R_SH_IMMU16",
01085 FALSE,
01086 0,
01087 0x3fffc00,
01088 FALSE),
01089
01090
01091 HOWTO (R_SH_IMM_LOW16,
01092 0,
01093 2,
01094 64,
01095 FALSE,
01096 10,
01097 complain_overflow_dont,
01098 bfd_elf_generic_reloc,
01099 "R_SH_IMM_LOW16",
01100 FALSE,
01101 0,
01102 0x3fffc00,
01103 FALSE),
01104
01105
01106 HOWTO (R_SH_IMM_LOW16_PCREL,
01107 0,
01108 2,
01109 64,
01110 TRUE,
01111 10,
01112 complain_overflow_dont,
01113 bfd_elf_generic_reloc,
01114 "R_SH_IMM_LOW16_PCREL",
01115 FALSE,
01116 0,
01117 0x3fffc00,
01118 TRUE),
01119
01120
01121 HOWTO (R_SH_IMM_MEDLOW16,
01122 16,
01123 2,
01124 64,
01125 FALSE,
01126 10,
01127 complain_overflow_dont,
01128 bfd_elf_generic_reloc,
01129 "R_SH_IMM_MEDLOW16",
01130 FALSE,
01131 0,
01132 0x3fffc00,
01133 FALSE),
01134
01135
01136 HOWTO (R_SH_IMM_MEDLOW16_PCREL,
01137 16,
01138 2,
01139 64,
01140 TRUE,
01141 10,
01142 complain_overflow_dont,
01143 bfd_elf_generic_reloc,
01144 "R_SH_IMM_MEDLOW16_PCREL",
01145 FALSE,
01146 0,
01147 0x3fffc00,
01148 TRUE),
01149
01150
01151 HOWTO (R_SH_IMM_MEDHI16,
01152 32,
01153 2,
01154 64,
01155 FALSE,
01156 10,
01157 complain_overflow_dont,
01158 bfd_elf_generic_reloc,
01159 "R_SH_IMM_MEDHI16",
01160 FALSE,
01161 0,
01162 0x3fffc00,
01163 FALSE),
01164
01165
01166 HOWTO (R_SH_IMM_MEDHI16_PCREL,
01167 32,
01168 2,
01169 64,
01170 TRUE,
01171 10,
01172 complain_overflow_dont,
01173 bfd_elf_generic_reloc,
01174 "R_SH_IMM_MEDHI16_PCREL",
01175 FALSE,
01176 0,
01177 0x3fffc00,
01178 TRUE),
01179
01180
01181 HOWTO (R_SH_IMM_HI16,
01182 48,
01183 2,
01184 64,
01185 FALSE,
01186 10,
01187 complain_overflow_dont,
01188 bfd_elf_generic_reloc,
01189 "R_SH_IMM_HI16",
01190 FALSE,
01191 0,
01192 0x3fffc00,
01193 FALSE),
01194
01195
01196 HOWTO (R_SH_IMM_HI16_PCREL,
01197 48,
01198 2,
01199 64,
01200 TRUE,
01201 10,
01202 complain_overflow_dont,
01203 bfd_elf_generic_reloc,
01204 "R_SH_IMM_HI16_PCREL",
01205 FALSE,
01206 0,
01207 0x3fffc00,
01208 TRUE),
01209
01210
01211 HOWTO (R_SH_64,
01212 0,
01213 4,
01214 64,
01215 FALSE,
01216 0,
01217 complain_overflow_dont,
01218 bfd_elf_generic_reloc,
01219 "R_SH_64",
01220 FALSE,
01221 0,
01222 ((bfd_vma) 0) - 1,
01223 FALSE),
01224
01225
01226 HOWTO (R_SH_64_PCREL,
01227 48,
01228 2,
01229 64,
01230 TRUE,
01231 10,
01232 complain_overflow_dont,
01233 bfd_elf_generic_reloc,
01234 "R_SH_64_PCREL",
01235 FALSE,
01236 0,
01237 ((bfd_vma) 0) - 1,
01238 TRUE),
01239
01240 };
01241
01242
01243
01244
01245 static bfd_reloc_status_type
01246 sh_elf64_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
01247 asymbol *symbol ATTRIBUTE_UNUSED,
01248 void *data ATTRIBUTE_UNUSED, asection *input_section,
01249 bfd *output_bfd,
01250 char **error_message ATTRIBUTE_UNUSED)
01251 {
01252 if (output_bfd != NULL)
01253 reloc_entry->address += input_section->output_offset;
01254 return bfd_reloc_ok;
01255 }
01256
01257
01258
01259
01260
01261
01262 static bfd_reloc_status_type
01263 sh_elf64_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol_in,
01264 void *data, asection *input_section, bfd *output_bfd,
01265 char **error_message ATTRIBUTE_UNUSED)
01266 {
01267 unsigned long insn;
01268 bfd_vma sym_value;
01269 enum elf_sh_reloc_type r_type;
01270 bfd_vma addr = reloc_entry->address;
01271 bfd_byte *hit_data = addr + (bfd_byte *) data;
01272
01273 r_type = (enum elf_sh_reloc_type) reloc_entry->howto->type;
01274
01275 if (output_bfd != NULL)
01276 {
01277
01278 reloc_entry->address += input_section->output_offset;
01279 return bfd_reloc_ok;
01280 }
01281
01282 if (symbol_in != NULL
01283 && bfd_is_und_section (symbol_in->section))
01284 return bfd_reloc_undefined;
01285
01286 if (bfd_is_com_section (symbol_in->section))
01287 sym_value = 0;
01288 else
01289 sym_value = (symbol_in->value +
01290 symbol_in->section->output_section->vma +
01291 symbol_in->section->output_offset);
01292
01293 switch (r_type)
01294 {
01295 case R_SH_DIR32:
01296 insn = bfd_get_32 (abfd, hit_data);
01297 insn += sym_value + reloc_entry->addend;
01298 bfd_put_32 (abfd, insn, hit_data);
01299 break;
01300
01301 default:
01302 abort ();
01303 break;
01304 }
01305
01306 return bfd_reloc_ok;
01307 }
01308
01309
01310
01311 struct elf_reloc_map
01312 {
01313 bfd_reloc_code_real_type bfd_reloc_val;
01314 unsigned char elf_reloc_val;
01315 };
01316
01317
01318
01319 static const struct elf_reloc_map sh64_reloc_map[] =
01320 {
01321 { BFD_RELOC_NONE, R_SH_NONE },
01322 { BFD_RELOC_32, R_SH_DIR32 },
01323 { BFD_RELOC_CTOR, R_SH_DIR32 },
01324 { BFD_RELOC_32_PCREL, R_SH_REL32 },
01325 { BFD_RELOC_8_PCREL, R_SH_SWITCH8 },
01326 { BFD_RELOC_SH_SWITCH16, R_SH_SWITCH16 },
01327 { BFD_RELOC_SH_SWITCH32, R_SH_SWITCH32 },
01328 { BFD_RELOC_VTABLE_INHERIT, R_SH_GNU_VTINHERIT },
01329 { BFD_RELOC_VTABLE_ENTRY, R_SH_GNU_VTENTRY },
01330 { BFD_RELOC_SH_GOT_LOW16, R_SH_GOT_LOW16 },
01331 { BFD_RELOC_SH_GOT_MEDLOW16, R_SH_GOT_MEDLOW16 },
01332 { BFD_RELOC_SH_GOT_MEDHI16, R_SH_GOT_MEDHI16 },
01333 { BFD_RELOC_SH_GOT_HI16, R_SH_GOT_HI16 },
01334 { BFD_RELOC_SH_GOTPLT_LOW16, R_SH_GOTPLT_LOW16 },
01335 { BFD_RELOC_SH_GOTPLT_MEDLOW16, R_SH_GOTPLT_MEDLOW16 },
01336 { BFD_RELOC_SH_GOTPLT_MEDHI16, R_SH_GOTPLT_MEDHI16 },
01337 { BFD_RELOC_SH_GOTPLT_HI16, R_SH_GOTPLT_HI16 },
01338 { BFD_RELOC_SH_PLT_LOW16, R_SH_PLT_LOW16 },
01339 { BFD_RELOC_SH_PLT_MEDLOW16, R_SH_PLT_MEDLOW16 },
01340 { BFD_RELOC_SH_PLT_MEDHI16, R_SH_PLT_MEDHI16 },
01341 { BFD_RELOC_SH_PLT_HI16, R_SH_PLT_HI16 },
01342 { BFD_RELOC_SH_GOTOFF_LOW16, R_SH_GOTOFF_LOW16 },
01343 { BFD_RELOC_SH_GOTOFF_MEDLOW16, R_SH_GOTOFF_MEDLOW16 },
01344 { BFD_RELOC_SH_GOTOFF_MEDHI16, R_SH_GOTOFF_MEDHI16 },
01345 { BFD_RELOC_SH_GOTOFF_HI16, R_SH_GOTOFF_HI16 },
01346 { BFD_RELOC_SH_GOTPC_LOW16, R_SH_GOTPC_LOW16 },
01347 { BFD_RELOC_SH_GOTPC_MEDLOW16, R_SH_GOTPC_MEDLOW16 },
01348 { BFD_RELOC_SH_GOTPC_MEDHI16, R_SH_GOTPC_MEDHI16 },
01349 { BFD_RELOC_SH_GOTPC_HI16, R_SH_GOTPC_HI16 },
01350 { BFD_RELOC_SH_COPY64, R_SH_COPY64 },
01351 { BFD_RELOC_SH_GLOB_DAT64, R_SH_GLOB_DAT64 },
01352 { BFD_RELOC_SH_JMP_SLOT64, R_SH_JMP_SLOT64 },
01353 { BFD_RELOC_SH_RELATIVE64, R_SH_RELATIVE64 },
01354 { BFD_RELOC_SH_GOT10BY4, R_SH_GOT10BY4 },
01355 { BFD_RELOC_SH_GOT10BY8, R_SH_GOT10BY8 },
01356 { BFD_RELOC_SH_GOTPLT10BY4, R_SH_GOTPLT10BY4 },
01357 { BFD_RELOC_SH_GOTPLT10BY8, R_SH_GOTPLT10BY8 },
01358 { BFD_RELOC_SH_PT_16, R_SH_PT_16 },
01359 { BFD_RELOC_SH_SHMEDIA_CODE, R_SH_SHMEDIA_CODE },
01360 { BFD_RELOC_SH_IMMU5, R_SH_DIR5U },
01361 { BFD_RELOC_SH_IMMS6, R_SH_DIR6S },
01362 { BFD_RELOC_SH_IMMU6, R_SH_DIR6U },
01363 { BFD_RELOC_SH_IMMS10, R_SH_DIR10S },
01364 { BFD_RELOC_SH_IMMS10BY2, R_SH_DIR10SW },
01365 { BFD_RELOC_SH_IMMS10BY4, R_SH_DIR10SL },
01366 { BFD_RELOC_SH_IMMS10BY8, R_SH_DIR10SQ },
01367 { BFD_RELOC_SH_IMMS16, R_SH_IMMS16 },
01368 { BFD_RELOC_SH_IMMU16, R_SH_IMMU16 },
01369 { BFD_RELOC_SH_IMM_LOW16, R_SH_IMM_LOW16 },
01370 { BFD_RELOC_SH_IMM_LOW16_PCREL, R_SH_IMM_LOW16_PCREL },
01371 { BFD_RELOC_SH_IMM_MEDLOW16, R_SH_IMM_MEDLOW16 },
01372 { BFD_RELOC_SH_IMM_MEDLOW16_PCREL, R_SH_IMM_MEDLOW16_PCREL },
01373 { BFD_RELOC_SH_IMM_MEDHI16, R_SH_IMM_MEDHI16 },
01374 { BFD_RELOC_SH_IMM_MEDHI16_PCREL, R_SH_IMM_MEDHI16_PCREL },
01375 { BFD_RELOC_SH_IMM_HI16, R_SH_IMM_HI16 },
01376 { BFD_RELOC_SH_IMM_HI16_PCREL, R_SH_IMM_HI16_PCREL },
01377 { BFD_RELOC_64, R_SH_64 },
01378 { BFD_RELOC_64_PCREL, R_SH_64_PCREL },
01379 };
01380
01381
01382
01383
01384 static reloc_howto_type *
01385 sh_elf64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
01386 bfd_reloc_code_real_type code)
01387 {
01388 unsigned int i;
01389
01390 for (i = 0; i < sizeof (sh64_reloc_map) / sizeof (struct elf_reloc_map); i++)
01391 {
01392 if (sh64_reloc_map[i].bfd_reloc_val == code)
01393 return &sh_elf64_howto_table[(int) sh64_reloc_map[i].elf_reloc_val];
01394 }
01395
01396 return NULL;
01397 }
01398
01399
01400
01401
01402
01403 static void
01404 sh_elf64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
01405 Elf_Internal_Rela *dst)
01406 {
01407 unsigned int r;
01408
01409 r = ELF64_R_TYPE (dst->r_info);
01410
01411 BFD_ASSERT (r <= (unsigned int) R_SH_64_PCREL);
01412 BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC || r > R_SH_LAST_INVALID_RELOC);
01413 BFD_ASSERT (r < R_SH_DIR8WPN || r > R_SH_LAST_INVALID_RELOC_2);
01414 BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_3 || r > R_SH_GOTPLT32);
01415 BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_4 || r > R_SH_LAST_INVALID_RELOC_4);
01416
01417 cache_ptr->howto = &sh_elf64_howto_table[r];
01418 }
01419
01420
01421
01422
01423
01424 static bfd_boolean
01425 sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
01426 struct bfd_link_info *info, bfd *input_bfd,
01427 asection *input_section, bfd_byte *contents,
01428 Elf_Internal_Rela *relocs,
01429 Elf_Internal_Sym *local_syms,
01430 asection **local_sections)
01431 {
01432 Elf_Internal_Shdr *symtab_hdr;
01433 struct elf_link_hash_entry **sym_hashes;
01434 Elf_Internal_Rela *rel, *relend;
01435 bfd *dynobj;
01436 bfd_vma *local_got_offsets;
01437 asection *sgot;
01438 asection *sgotplt;
01439 asection *splt;
01440 asection *sreloc;
01441 bfd_vma disp, dropped;
01442
01443 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
01444 sym_hashes = elf_sym_hashes (input_bfd);
01445 dynobj = elf_hash_table (info)->dynobj;
01446 local_got_offsets = elf_local_got_offsets (input_bfd);
01447
01448 sgot = NULL;
01449 sgotplt = NULL;
01450 splt = NULL;
01451 sreloc = NULL;
01452
01453 rel = relocs;
01454 relend = relocs + input_section->reloc_count;
01455 for (; rel < relend; rel++)
01456 {
01457 int r_type;
01458 reloc_howto_type *howto;
01459 unsigned long r_symndx;
01460 Elf_Internal_Sym *sym;
01461 asection *sec;
01462 struct elf_link_hash_entry *h;
01463 bfd_vma relocation;
01464 bfd_vma addend = (bfd_vma)0;
01465 bfd_reloc_status_type r;
01466 int seen_stt_datalabel = 0;
01467
01468 r_symndx = ELF64_R_SYM (rel->r_info);
01469
01470 r_type = ELF64_R_TYPE (rel->r_info);
01471
01472 if (r_type == (int) R_SH_NONE)
01473 continue;
01474
01475 if (r_type < 0
01476 || r_type > R_SH_64_PCREL
01477 || (r_type >= (int) R_SH_FIRST_INVALID_RELOC
01478 && r_type <= (int) R_SH_LAST_INVALID_RELOC)
01479 || (r_type >= (int) R_SH_DIR8WPN
01480 && r_type <= (int) R_SH_LAST_INVALID_RELOC)
01481 || (r_type >= (int) R_SH_GNU_VTINHERIT
01482 && r_type <= (int) R_SH_PSHL)
01483 || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_2
01484 && r_type <= R_SH_GOTPLT32)
01485 || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_4
01486 && r_type <= (int) R_SH_LAST_INVALID_RELOC_4))
01487 {
01488 bfd_set_error (bfd_error_bad_value);
01489 return FALSE;
01490 }
01491
01492 howto = sh_elf64_howto_table + r_type;
01493
01494
01495 h = NULL;
01496 sym = NULL;
01497 sec = NULL;
01498 if (r_symndx < symtab_hdr->sh_info)
01499 {
01500 sym = local_syms + r_symndx;
01501 sec = local_sections[r_symndx];
01502 relocation = ((sec->output_section->vma
01503 + sec->output_offset
01504 + sym->st_value)
01505 | ((sym->st_other & STO_SH5_ISA32) != 0));
01506
01507
01508
01509
01510 if ((sym->st_other & STO_SH5_ISA32) != 0)
01511 ((*info->callbacks->reloc_dangerous)
01512 (info,
01513 _("Unexpected STO_SH5_ISA32 on local symbol is not handled"),
01514 input_bfd, input_section, rel->r_offset));
01515
01516 if (info->relocatable)
01517 {
01518
01519
01520
01521
01522 sym = local_syms + r_symndx;
01523 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
01524 goto final_link_relocate;
01525
01526 continue;
01527 }
01528 else if (! howto->partial_inplace)
01529 {
01530 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
01531 relocation |= ((sym->st_other & STO_SH5_ISA32) != 0);
01532 }
01533 else if ((sec->flags & SEC_MERGE)
01534 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
01535 {
01536 asection *msec;
01537
01538 if (howto->rightshift || howto->src_mask != 0xffffffff)
01539 {
01540 (*_bfd_error_handler)
01541 (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"),
01542 input_bfd, input_section,
01543 (long) rel->r_offset, howto->name);
01544 return FALSE;
01545 }
01546
01547 addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
01548 msec = sec;
01549 addend =
01550 _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend)
01551 - relocation;
01552 addend += msec->output_section->vma + msec->output_offset;
01553 bfd_put_32 (input_bfd, addend, contents + rel->r_offset);
01554 addend = 0;
01555 }
01556 }
01557 else
01558 {
01559
01560
01561
01562
01563
01564 if (info->relocatable)
01565 continue;
01566
01567 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
01568 while (h->root.type == bfd_link_hash_indirect
01569 || h->root.type == bfd_link_hash_warning)
01570 {
01571
01572
01573
01574 seen_stt_datalabel |= h->type == STT_DATALABEL;
01575 h = (struct elf_link_hash_entry *) h->root.u.i.link;
01576 }
01577
01578 if (h->root.type == bfd_link_hash_defined
01579 || h->root.type == bfd_link_hash_defweak)
01580 {
01581 sec = h->root.u.def.section;
01582
01583
01584
01585 if (r_type == R_SH_GOTPC_LOW16
01586 || r_type == R_SH_GOTPC_MEDLOW16
01587 || r_type == R_SH_GOTPC_MEDHI16
01588 || r_type == R_SH_GOTPC_HI16
01589 || ((r_type == R_SH_PLT_LOW16
01590 || r_type == R_SH_PLT_MEDLOW16
01591 || r_type == R_SH_PLT_MEDHI16
01592 || r_type == R_SH_PLT_HI16)
01593 && h->plt.offset != (bfd_vma) -1)
01594 || ((r_type == R_SH_GOT_LOW16
01595 || r_type == R_SH_GOT_MEDLOW16
01596 || r_type == R_SH_GOT_MEDHI16
01597 || r_type == R_SH_GOT_HI16)
01598 && elf_hash_table (info)->dynamic_sections_created
01599 && (! info->shared
01600 || (! info->symbolic && h->dynindx != -1)
01601 || !h->def_regular))
01602
01603
01604
01605
01606
01607 || (info->shared
01608 && ((! info->symbolic && h->dynindx != -1)
01609 || !h->def_regular)
01610 && ((r_type == R_SH_64
01611 && !(ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
01612 || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN))
01613 || r_type == R_SH_64_PCREL)
01614 && ((input_section->flags & SEC_ALLOC) != 0
01615
01616
01617
01618
01619 || (input_section->flags & SEC_DEBUGGING) != 0))
01620
01621
01622
01623 || (sec->output_section == NULL
01624 && ((input_section->flags & SEC_DEBUGGING) != 0
01625 && h->def_dynamic)))
01626 relocation = 0;
01627 else if (sec->output_section == NULL)
01628 {
01629 (*_bfd_error_handler)
01630 (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
01631 bfd_get_filename (input_bfd), h->root.root.string,
01632 bfd_get_section_name (input_bfd, input_section));
01633 relocation = 0;
01634 }
01635 else
01636 relocation = ((h->root.u.def.value
01637 + sec->output_section->vma
01638 + sec->output_offset)
01639
01640
01641
01642 | ((h->other & STO_SH5_ISA32) != 0
01643 && ! seen_stt_datalabel));
01644 }
01645 else if (h->root.type == bfd_link_hash_undefweak)
01646 relocation = 0;
01647 else if (info->unresolved_syms_in_objects == RM_IGNORE
01648 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
01649 relocation = 0;
01650 else
01651 {
01652 if (! ((*info->callbacks->undefined_symbol)
01653 (info, h->root.root.string, input_bfd,
01654 input_section, rel->r_offset,
01655 (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
01656 || ELF_ST_VISIBILITY (h->other)))))
01657 return FALSE;
01658 relocation = 0;
01659 }
01660 }
01661
01662 disp = (relocation
01663 - input_section->output_section->vma
01664 - input_section->output_offset
01665 - rel->r_offset);
01666 dropped = 0;
01667 switch ((int)r_type)
01668 {
01669 case R_SH_PT_16: dropped = disp & 2; break;
01670 case R_SH_DIR10SW: dropped = disp & 1; break;
01671 case R_SH_DIR10SL: dropped = disp & 3; break;
01672 case R_SH_DIR10SQ: dropped = disp & 7; break;
01673 }
01674 if (dropped != 0)
01675 {
01676 (*_bfd_error_handler)
01677 (_("%s: error: unaligned relocation type %d at %08x reloc %08x\n"),
01678 bfd_get_filename (input_bfd), (int)r_type, (unsigned)rel->r_offset, (unsigned)relocation);
01679 bfd_set_error (bfd_error_bad_value);
01680 return FALSE;
01681 }
01682 switch ((int)r_type)
01683 {
01684 case R_SH_64:
01685 case R_SH_64_PCREL:
01686 if (info->shared
01687 && (input_section->flags & SEC_ALLOC) != 0
01688 && (r_type != R_SH_64_PCREL
01689 || (h != NULL
01690 && h->dynindx != -1
01691 && (! info->symbolic
01692 || !h->def_regular))))
01693 {
01694 Elf_Internal_Rela outrel;
01695 bfd_byte *loc;
01696 bfd_boolean skip, relocate;
01697
01698
01699
01700
01701
01702 if (sreloc == NULL)
01703 {
01704 const char *name;
01705
01706 name = (bfd_elf_string_from_elf_section
01707 (input_bfd,
01708 elf_elfheader (input_bfd)->e_shstrndx,
01709 elf_section_data (input_section)->rel_hdr.sh_name));
01710 if (name == NULL)
01711 return FALSE;
01712
01713 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
01714 && strcmp (bfd_get_section_name (input_bfd,
01715 input_section),
01716 name + 5) == 0);
01717
01718 sreloc = bfd_get_section_by_name (dynobj, name);
01719 BFD_ASSERT (sreloc != NULL);
01720 }
01721
01722 skip = FALSE;
01723 relocate = FALSE;
01724
01725 outrel.r_offset
01726 = _bfd_elf_section_offset (output_bfd, info,
01727 input_section, rel->r_offset);
01728
01729 if (outrel.r_offset == (bfd_vma) -1)
01730 skip = TRUE;
01731 else if (outrel.r_offset == (bfd_vma) -2)
01732 skip = TRUE, relocate = TRUE;
01733
01734 outrel.r_offset += (input_section->output_section->vma
01735 + input_section->output_offset);
01736
01737 if (skip)
01738 memset (&outrel, 0, sizeof outrel);
01739 else if (r_type == R_SH_64_PCREL)
01740 {
01741 BFD_ASSERT (h != NULL && h->dynindx != -1);
01742 outrel.r_info = ELF64_R_INFO (h->dynindx, R_SH_64_PCREL);
01743 outrel.r_addend = rel->r_addend;
01744 }
01745 else
01746 {
01747
01748
01749 if (h == NULL
01750 || ((info->symbolic || h->dynindx == -1)
01751 && h->def_regular))
01752 {
01753 relocate = TRUE;
01754 outrel.r_info = ELF64_R_INFO (0, R_SH_RELATIVE64);
01755 outrel.r_addend = relocation + rel->r_addend;
01756 }
01757 else
01758 {
01759 BFD_ASSERT (h->dynindx != -1);
01760 outrel.r_info = ELF64_R_INFO (h->dynindx, R_SH_64);
01761 outrel.r_addend = relocation + rel->r_addend;
01762 }
01763 }
01764
01765 loc = sreloc->contents;
01766 loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
01767 bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
01768
01769
01770
01771
01772
01773 if (! relocate)
01774 continue;
01775 }
01776 else if (r_type == R_SH_64)
01777 addend = rel->r_addend;
01778 goto final_link_relocate;
01779
01780 case R_SH_GOTPLT_LOW16:
01781 case R_SH_GOTPLT_MEDLOW16:
01782 case R_SH_GOTPLT_MEDHI16:
01783 case R_SH_GOTPLT_HI16:
01784 case R_SH_GOTPLT10BY4:
01785 case R_SH_GOTPLT10BY8:
01786
01787
01788
01789 if (h == NULL
01790 || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
01791 || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
01792 || ! info->shared
01793 || info->symbolic
01794 || h->dynindx == -1
01795 || h->plt.offset == (bfd_vma) -1
01796 || h->got.offset != (bfd_vma) -1)
01797 goto force_got;
01798
01799
01800
01801 if (sgotplt == NULL)
01802 {
01803 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
01804 BFD_ASSERT (sgotplt != NULL);
01805 }
01806
01807 relocation = (sgotplt->output_offset
01808 + ((h->plt.offset / elf_sh64_sizeof_plt (info)
01809 - 1 + 3) * 8));
01810
01811 relocation -= GOT_BIAS;
01812
01813 goto final_link_relocate;
01814
01815 force_got:
01816 case R_SH_GOT_LOW16:
01817 case R_SH_GOT_MEDLOW16:
01818 case R_SH_GOT_MEDHI16:
01819 case R_SH_GOT_HI16:
01820 case R_SH_GOT10BY4:
01821 case R_SH_GOT10BY8:
01822
01823
01824 if (sgot == NULL)
01825 {
01826 sgot = bfd_get_section_by_name (dynobj, ".got");
01827 BFD_ASSERT (sgot != NULL);
01828 }
01829
01830 if (h != NULL)
01831 {
01832 bfd_vma off;
01833
01834 off = h->got.offset;
01835 if (seen_stt_datalabel)
01836 {
01837 struct elf_sh64_link_hash_entry *hsh;
01838
01839 hsh = (struct elf_sh64_link_hash_entry *)h;
01840 off = hsh->datalabel_got_offset;
01841 }
01842 BFD_ASSERT (off != (bfd_vma) -1);
01843
01844 if (! elf_hash_table (info)->dynamic_sections_created
01845 || (info->shared
01846 && (info->symbolic || h->dynindx == -1
01847 || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
01848 || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
01849 && h->def_regular))
01850 {
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863 if ((off & 1) != 0)
01864 off &= ~1;
01865 else
01866 {
01867 bfd_put_64 (output_bfd, relocation,
01868 sgot->contents + off);
01869 if (seen_stt_datalabel)
01870 {
01871 struct elf_sh64_link_hash_entry *hsh;
01872
01873 hsh = (struct elf_sh64_link_hash_entry *)h;
01874 hsh->datalabel_got_offset |= 1;
01875 }
01876 else
01877 h->got.offset |= 1;
01878 }
01879 }
01880
01881 relocation = sgot->output_offset + off;
01882 }
01883 else
01884 {
01885 bfd_vma off;
01886
01887 if (rel->r_addend)
01888 {
01889 BFD_ASSERT (local_got_offsets != NULL
01890 && (local_got_offsets[symtab_hdr->sh_info
01891 + r_symndx]
01892 != (bfd_vma) -1));
01893
01894 off = local_got_offsets[symtab_hdr->sh_info
01895 + r_symndx];
01896 }
01897 else
01898 {
01899 BFD_ASSERT (local_got_offsets != NULL
01900 && local_got_offsets[r_symndx] != (bfd_vma) -1);
01901
01902 off = local_got_offsets[r_symndx];
01903 }
01904
01905
01906
01907
01908 if ((off & 1) != 0)
01909 off &= ~1;
01910 else
01911 {
01912 bfd_put_64 (output_bfd, relocation, sgot->contents + off);
01913
01914 if (info->shared)
01915 {
01916 asection *s;
01917 Elf_Internal_Rela outrel;
01918 bfd_byte *loc;
01919
01920 s = bfd_get_section_by_name (dynobj, ".rela.got");
01921 BFD_ASSERT (s != NULL);
01922
01923 outrel.r_offset = (sgot->output_section->vma
01924 + sgot->output_offset
01925 + off);
01926 outrel.r_info = ELF64_R_INFO (0, R_SH_RELATIVE64);
01927 outrel.r_addend = relocation;
01928 loc = s->contents;
01929 loc += s->reloc_count++ * sizeof (Elf64_External_Rela);
01930 bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
01931 }
01932
01933 if (rel->r_addend)
01934 local_got_offsets[symtab_hdr->sh_info + r_symndx] |= 1;
01935 else
01936 local_got_offsets[r_symndx] |= 1;
01937 }
01938
01939 relocation = sgot->output_offset + off;
01940 }
01941
01942 relocation -= GOT_BIAS;
01943
01944 goto final_link_relocate;
01945
01946 case R_SH_GOTOFF_LOW16:
01947 case R_SH_GOTOFF_MEDLOW16:
01948 case R_SH_GOTOFF_MEDHI16:
01949 case R_SH_GOTOFF_HI16:
01950
01951
01952
01953 if (sgot == NULL)
01954 {
01955 sgot = bfd_get_section_by_name (dynobj, ".got");
01956 BFD_ASSERT (sgot != NULL);
01957 }
01958
01959
01960
01961
01962
01963
01964 relocation -= sgot->output_section->vma;
01965
01966 relocation -= GOT_BIAS;
01967
01968 addend = rel->r_addend;
01969
01970 goto final_link_relocate;
01971
01972 case R_SH_GOTPC_LOW16:
01973 case R_SH_GOTPC_MEDLOW16:
01974 case R_SH_GOTPC_MEDHI16:
01975 case R_SH_GOTPC_HI16:
01976
01977
01978 if (sgot == NULL)
01979 {
01980 sgot = bfd_get_section_by_name (dynobj, ".got");
01981 BFD_ASSERT (sgot != NULL);
01982 }
01983
01984 relocation = sgot->output_section->vma;
01985
01986 relocation += GOT_BIAS;
01987
01988 addend = rel->r_addend;
01989
01990 goto final_link_relocate;
01991
01992 case R_SH_PLT_LOW16:
01993 case R_SH_PLT_MEDLOW16:
01994 case R_SH_PLT_MEDHI16:
01995 case R_SH_PLT_HI16:
01996
01997
01998
01999
02000
02001 if (h == NULL)
02002 goto final_link_relocate;
02003
02004 if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
02005 || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
02006 goto final_link_relocate;
02007
02008 if (h->plt.offset == (bfd_vma) -1)
02009 {
02010
02011
02012
02013 goto final_link_relocate;
02014 }
02015
02016 if (splt == NULL)
02017 {
02018 splt = bfd_get_section_by_name (dynobj, ".plt");
02019 BFD_ASSERT (splt != NULL);
02020 }
02021
02022 relocation = (splt->output_section->vma
02023 + splt->output_offset
02024 + h->plt.offset);
02025 relocation++;
02026
02027 addend = rel->r_addend;
02028
02029 goto final_link_relocate;
02030
02031 case R_SH_DIR32:
02032 case R_SH_SHMEDIA_CODE:
02033 case R_SH_PT_16:
02034 case R_SH_DIR5U:
02035 case R_SH_DIR6S:
02036 case R_SH_DIR6U:
02037 case R_SH_DIR10S:
02038 case R_SH_DIR10SW:
02039 case R_SH_DIR10SL:
02040 case R_SH_DIR10SQ:
02041 case R_SH_IMMS16:
02042 case R_SH_IMMU16:
02043 case R_SH_IMM_LOW16:
02044 case R_SH_IMM_LOW16_PCREL:
02045 case R_SH_IMM_MEDLOW16:
02046 case R_SH_IMM_MEDLOW16_PCREL:
02047 case R_SH_IMM_MEDHI16:
02048 case R_SH_IMM_MEDHI16_PCREL:
02049 case R_SH_IMM_HI16:
02050 case R_SH_IMM_HI16_PCREL:
02051 addend = rel->r_addend;
02052
02053 case R_SH_REL32:
02054 final_link_relocate:
02055 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
02056 contents, rel->r_offset,
02057 relocation, addend);
02058 break;
02059
02060 default:
02061 bfd_set_error (bfd_error_bad_value);
02062 return FALSE;
02063
02064 }
02065
02066 if (r != bfd_reloc_ok)
02067 {
02068 switch (r)
02069 {
02070 default:
02071 case bfd_reloc_outofrange:
02072 abort ();
02073 case bfd_reloc_overflow:
02074 {
02075 const char *name;
02076
02077 if (h != NULL)
02078 name = NULL;
02079 else
02080 {
02081 name = (bfd_elf_string_from_elf_section
02082 (input_bfd, symtab_hdr->sh_link, sym->st_name));
02083 if (name == NULL)
02084 return FALSE;
02085 if (*name == '\0')
02086 name = bfd_section_name (input_bfd, sec);
02087 }
02088 if (! ((*info->callbacks->reloc_overflow)
02089 (info, (h ? &h->root : NULL), name, howto->name,
02090 (bfd_vma) 0, input_bfd, input_section,
02091 rel->r_offset)))
02092 return FALSE;
02093 }
02094 break;
02095 }
02096 }
02097 }
02098
02099 return TRUE;
02100 }
02101
02102
02103
02104
02105
02106
02107 static bfd_byte *
02108 sh_elf64_get_relocated_section_contents (bfd *output_bfd,
02109 struct bfd_link_info *link_info,
02110 struct bfd_link_order *link_order,
02111 bfd_byte *data,
02112 bfd_boolean relocatable,
02113 asymbol **symbols)
02114 {
02115 Elf_Internal_Shdr *symtab_hdr;
02116 asection *input_section = link_order->u.indirect.section;
02117 bfd *input_bfd = input_section->owner;
02118 asection **sections = NULL;
02119 Elf_Internal_Rela *internal_relocs = NULL;
02120 Elf_Internal_Sym *isymbuf = NULL;
02121
02122
02123
02124 if (relocatable
02125 || elf_section_data (input_section)->this_hdr.contents == NULL)
02126 return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
02127 link_order, data,
02128 relocatable,
02129 symbols);
02130
02131 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
02132
02133 memcpy (data, elf_section_data (input_section)->this_hdr.contents,
02134 input_section->size);
02135
02136 if ((input_section->flags & SEC_RELOC) != 0
02137 && input_section->reloc_count > 0)
02138 {
02139 Elf_Internal_Sym *isymp;
02140 Elf_Internal_Sym *isymend;
02141 asection **secpp;
02142
02143
02144 if (symtab_hdr->sh_info != 0)
02145 {
02146 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
02147 if (isymbuf == NULL)
02148 isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
02149 symtab_hdr->sh_info, 0,
02150 NULL, NULL, NULL);
02151 if (isymbuf == NULL)
02152 goto error_return;
02153 }
02154
02155 internal_relocs = (_bfd_elf_link_read_relocs
02156 (input_bfd, input_section, NULL,
02157 (Elf_Internal_Rela *) NULL, FALSE));
02158 if (internal_relocs == NULL)
02159 goto error_return;
02160
02161 sections = (asection **) bfd_malloc (symtab_hdr->sh_info
02162 * sizeof (asection *));
02163 if (sections == NULL && symtab_hdr->sh_info > 0)
02164 goto error_return;
02165
02166 secpp = sections;
02167 isymend = isymbuf + symtab_hdr->sh_info;
02168 for (isymp = isymbuf; isymp < isymend; ++isymp, ++secpp)
02169 {
02170 asection *isec;
02171
02172 if (isymp->st_shndx == SHN_UNDEF)
02173 isec = bfd_und_section_ptr;
02174 else if (isymp->st_shndx > 0 && isymp->st_shndx < SHN_LORESERVE)
02175 isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
02176 else if (isymp->st_shndx == SHN_ABS)
02177 isec = bfd_abs_section_ptr;
02178 else if (isymp->st_shndx == SHN_COMMON)
02179 isec = bfd_com_section_ptr;
02180 else
02181 {
02182
02183 isec = NULL;
02184 }
02185
02186 *secpp = isec;
02187 }
02188
02189 if (! sh_elf64_relocate_section (output_bfd, link_info, input_bfd,
02190 input_section, data, internal_relocs,
02191 isymbuf, sections))
02192 goto error_return;
02193
02194 if (sections != NULL)
02195 free (sections);
02196 if (internal_relocs != elf_section_data (input_section)->relocs)
02197 free (internal_relocs);
02198 if (isymbuf != NULL
02199 && (unsigned char *) isymbuf != symtab_hdr->contents)
02200 free (isymbuf);
02201 }
02202
02203 return data;
02204
02205 error_return:
02206 if (sections != NULL)
02207 free (sections);
02208 if (internal_relocs != NULL
02209 && internal_relocs != elf_section_data (input_section)->relocs)
02210 free (internal_relocs);
02211 if (isymbuf != NULL
02212 && (unsigned char *) isymbuf != symtab_hdr->contents)
02213 free (isymbuf);
02214 return NULL;
02215 }
02216
02217
02218
02219 static bfd_boolean
02220 sh64_elf64_fake_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
02221 Elf_Internal_Shdr *elf_section_hdr,
02222 asection *asect)
02223 {
02224
02225 if (bfd_get_section_flags (output_bfd, asect) & SEC_CODE)
02226 elf_section_hdr->sh_flags |= SHF_SH5_ISA32;
02227
02228 return TRUE;
02229 }
02230
02231 static bfd_boolean
02232 sh_elf64_set_mach_from_flags (bfd *abfd)
02233 {
02234 flagword flags = elf_elfheader (abfd)->e_flags;
02235
02236 switch (flags & EF_SH_MACH_MASK)
02237 {
02238 case EF_SH5:
02239
02240 bfd_default_set_arch_mach (abfd, bfd_arch_sh, bfd_mach_sh5);
02241 break;
02242
02243 default:
02244 bfd_set_error (bfd_error_wrong_format);
02245 return FALSE;
02246 }
02247 return TRUE;
02248 }
02249
02250
02251
02252
02253
02254 static bfd_boolean
02255 sh_elf64_set_private_flags (bfd *abfd, flagword flags)
02256 {
02257 BFD_ASSERT (! elf_flags_init (abfd)
02258 || elf_elfheader (abfd)->e_flags == flags);
02259
02260 elf_elfheader (abfd)->e_flags = flags;
02261 elf_flags_init (abfd) = TRUE;
02262 return sh_elf64_set_mach_from_flags (abfd);
02263 }
02264
02265
02266
02267
02268 static bfd_boolean
02269 sh_elf64_copy_private_data_internal (bfd *ibfd, bfd *obfd)
02270 {
02271 Elf_Internal_Shdr **o_shdrp;
02272 asection *isec;
02273 asection *osec;
02274
02275 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
02276 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
02277 return TRUE;
02278
02279 o_shdrp = elf_elfsections (obfd);
02280 for (osec = obfd->sections; osec; osec = osec->next)
02281 {
02282 int oIndex = ((struct bfd_elf_section_data *) elf_section_data (osec))->this_idx;
02283 for (isec = ibfd->sections; isec; isec = isec->next)
02284 {
02285 if (strcmp (osec->name, isec->name) == 0)
02286 {
02287
02288 if ((elf_section_data (isec)->this_hdr.sh_flags
02289 & SHF_SH5_ISA32) != 0)
02290 o_shdrp[oIndex]->sh_flags |= SHF_SH5_ISA32;
02291 break;
02292 }
02293 }
02294 }
02295
02296 return sh_elf64_set_private_flags (obfd, elf_elfheader (ibfd)->e_flags);
02297 }
02298
02299 static bfd_boolean
02300 sh_elf64_copy_private_data (bfd *ibfd, bfd *obfd)
02301 {
02302 return sh_elf64_copy_private_data_internal (ibfd, obfd);
02303 }
02304
02305 static bfd_boolean
02306 sh_elf64_merge_private_data (bfd *ibfd, bfd *obfd)
02307 {
02308 flagword old_flags, new_flags;
02309
02310 if (! _bfd_generic_verify_endian_match (ibfd, obfd))
02311 return FALSE;
02312
02313 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
02314 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
02315 return TRUE;
02316
02317 if (bfd_get_arch_size (ibfd) != bfd_get_arch_size (obfd))
02318 {
02319 const char *msg;
02320
02321 if (bfd_get_arch_size (ibfd) == 32
02322 && bfd_get_arch_size (obfd) == 64)
02323 msg = _("%s: compiled as 32-bit object and %s is 64-bit");
02324 else if (bfd_get_arch_size (ibfd) == 64
02325 && bfd_get_arch_size (obfd) == 32)
02326 msg = _("%s: compiled as 64-bit object and %s is 32-bit");
02327 else
02328 msg = _("%s: object size does not match that of target %s");
02329
02330 (*_bfd_error_handler) (msg, bfd_get_filename (ibfd),
02331 bfd_get_filename (obfd));
02332 bfd_set_error (bfd_error_wrong_format);
02333 return FALSE;
02334 }
02335
02336 old_flags = elf_elfheader (obfd)->e_flags;
02337 new_flags = elf_elfheader (ibfd)->e_flags;
02338 if (! elf_flags_init (obfd))
02339 {
02340
02341 elf_flags_init (obfd) = TRUE;
02342 elf_elfheader (obfd)->e_flags = old_flags = new_flags;
02343 }
02344
02345
02346
02347 else if ((new_flags & EF_SH_MACH_MASK) != EF_SH5)
02348 {
02349 (*_bfd_error_handler)
02350 ("%s: does not use the SH64 64-bit ABI as previous modules do",
02351 bfd_get_filename (ibfd));
02352 bfd_set_error (bfd_error_bad_value);
02353 return FALSE;
02354 }
02355
02356 sh_elf64_copy_private_data_internal (ibfd, obfd);
02357
02358
02359
02360 elf_elfheader (obfd)->e_flags = old_flags;
02361
02362 return sh_elf64_set_mach_from_flags (obfd);
02363 }
02364
02365
02366
02367
02368 static asection *
02369 sh_elf64_gc_mark_hook (asection *sec,
02370 struct bfd_link_info *info ATTRIBUTE_UNUSED,
02371 Elf_Internal_Rela *rel,
02372 struct elf_link_hash_entry *h,
02373 Elf_Internal_Sym *sym)
02374 {
02375 if (h != NULL)
02376 {
02377 switch (ELF64_R_TYPE (rel->r_info))
02378 {
02379 case R_SH_GNU_VTINHERIT:
02380 case R_SH_GNU_VTENTRY:
02381 break;
02382
02383 default:
02384 while (h->root.type == bfd_link_hash_indirect
02385 && h->root.u.i.link)
02386 h = (struct elf_link_hash_entry *) h->root.u.i.link;
02387 switch (h->root.type)
02388 {
02389 case bfd_link_hash_defined:
02390 case bfd_link_hash_defweak:
02391 return h->root.u.def.section;
02392
02393 case bfd_link_hash_common:
02394 return h->root.u.c.p->section;
02395
02396 default:
02397 break;
02398 }
02399 }
02400 }
02401 else
02402 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
02403
02404 return NULL;
02405 }
02406
02407
02408
02409 static bfd_boolean
02410 sh_elf64_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
02411 struct bfd_link_info *info ATTRIBUTE_UNUSED,
02412 asection *sec ATTRIBUTE_UNUSED,
02413 const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
02414 {
02415
02416 return TRUE;
02417 }
02418
02419
02420
02421
02422
02423 static bfd_boolean
02424 sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info,
02425 asection *sec, const Elf_Internal_Rela *relocs)
02426 {
02427 Elf_Internal_Shdr *symtab_hdr;
02428 struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
02429 const Elf_Internal_Rela *rel;
02430 const Elf_Internal_Rela *rel_end;
02431 bfd *dynobj;
02432 bfd_vma *local_got_offsets;
02433 asection *sgot;
02434 asection *srelgot;
02435 asection *sreloc;
02436
02437 sgot = NULL;
02438 srelgot = NULL;
02439 sreloc = NULL;
02440
02441 if (info->relocatable)
02442 return TRUE;
02443
02444 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
02445 sym_hashes = elf_sym_hashes (abfd);
02446 sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf64_External_Sym);
02447 if (!elf_bad_symtab (abfd))
02448 sym_hashes_end -= symtab_hdr->sh_info;
02449
02450 dynobj = elf_hash_table (info)->dynobj;
02451 local_got_offsets = elf_local_got_offsets (abfd);
02452
02453 rel_end = relocs + sec->reloc_count;
02454 for (rel = relocs; rel < rel_end; rel++)
02455 {
02456 struct elf_link_hash_entry *h;
02457 unsigned long r_symndx;
02458
02459 r_symndx = ELF64_R_SYM (rel->r_info);
02460 if (r_symndx < symtab_hdr->sh_info)
02461 h = NULL;
02462 else
02463 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
02464
02465
02466 if (dynobj == NULL)
02467 {
02468 switch (ELF64_R_TYPE (rel->r_info))
02469 {
02470 case R_SH_GOTPLT_LOW16:
02471 case R_SH_GOTPLT_MEDLOW16:
02472 case R_SH_GOTPLT_MEDHI16:
02473 case R_SH_GOTPLT_HI16:
02474 case R_SH_GOTPLT10BY4:
02475 case R_SH_GOTPLT10BY8:
02476 case R_SH_GOT_LOW16:
02477 case R_SH_GOT_MEDLOW16:
02478 case R_SH_GOT_MEDHI16:
02479 case R_SH_GOT_HI16:
02480 case R_SH_GOT10BY4:
02481 case R_SH_GOT10BY8:
02482 case R_SH_GOTOFF_LOW16:
02483 case R_SH_GOTOFF_MEDLOW16:
02484 case R_SH_GOTOFF_MEDHI16:
02485 case R_SH_GOTOFF_HI16:
02486 case R_SH_GOTPC_LOW16:
02487 case R_SH_GOTPC_MEDLOW16:
02488 case R_SH_GOTPC_MEDHI16:
02489 case R_SH_GOTPC_HI16:
02490 elf_hash_table (info)->dynobj = dynobj = abfd;
02491 if (! _bfd_elf_create_got_section (dynobj, info))
02492 return FALSE;
02493 break;
02494
02495 default:
02496 break;
02497 }
02498 }
02499
02500 switch (ELF64_R_TYPE (rel->r_info))
02501 {
02502
02503
02504 case R_SH_GNU_VTINHERIT:
02505 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
02506 return FALSE;
02507 break;
02508
02509
02510
02511 case R_SH_GNU_VTENTRY:
02512 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
02513 return FALSE;
02514 break;
02515
02516 force_got:
02517 case R_SH_GOT_LOW16:
02518 case R_SH_GOT_MEDLOW16:
02519 case R_SH_GOT_MEDHI16:
02520 case R_SH_GOT_HI16:
02521 case R_SH_GOT10BY4:
02522 case R_SH_GOT10BY8:
02523
02524
02525 if (sgot == NULL)
02526 {
02527 sgot = bfd_get_section_by_name (dynobj, ".got");
02528 BFD_ASSERT (sgot != NULL);
02529 }
02530
02531 if (srelgot == NULL
02532 && (h != NULL || info->shared))
02533 {
02534 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
02535 if (srelgot == NULL)
02536 {
02537 srelgot = bfd_make_section (dynobj, ".rela.got");
02538 if (srelgot == NULL
02539 || ! bfd_set_section_flags (dynobj, srelgot,
02540 (SEC_ALLOC
02541 | SEC_LOAD
02542 | SEC_HAS_CONTENTS
02543 | SEC_IN_MEMORY
02544 | SEC_LINKER_CREATED
02545 | SEC_READONLY))
02546 || ! bfd_set_section_alignment (dynobj, srelgot, 2))
02547 return FALSE;
02548 }
02549 }
02550
02551 if (h != NULL)
02552 {
02553 if (h->type == STT_DATALABEL)
02554 {
02555 struct elf_sh64_link_hash_entry *hsh;
02556
02557 h = (struct elf_link_hash_entry *) h->root.u.i.link;
02558 hsh = (struct elf_sh64_link_hash_entry *)h;
02559 if (hsh->datalabel_got_offset != (bfd_vma) -1)
02560 break;
02561
02562 hsh->datalabel_got_offset = sgot->size;
02563 }
02564 else
02565 {
02566 if (h->got.offset != (bfd_vma) -1)
02567 {
02568
02569 break;
02570 }
02571 h->got.offset = sgot->size;
02572 }
02573
02574
02575 if (h->dynindx == -1)
02576 {
02577 if (! bfd_elf_link_record_dynamic_symbol (info, h))
02578 return FALSE;
02579 }
02580
02581 srelgot->size += sizeof (Elf64_External_Rela);
02582 }
02583 else
02584 {
02585
02586
02587 if (local_got_offsets == NULL)
02588 {
02589 size_t size;
02590 register unsigned int i;
02591
02592 size = symtab_hdr->sh_info * sizeof (bfd_vma);
02593
02594
02595 size *= 2;
02596 local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
02597 if (local_got_offsets == NULL)
02598 return FALSE;
02599 elf_local_got_offsets (abfd) = local_got_offsets;
02600 for (i = 0; i < symtab_hdr->sh_info; i++)
02601 local_got_offsets[i] = (bfd_vma) -1;
02602 for (; i < 2 * symtab_hdr->sh_info; i++)
02603 local_got_offsets[i] = (bfd_vma) -1;
02604 }
02605 if ((rel->r_addend & 1) != 0)
02606 {
02607 if (local_got_offsets[symtab_hdr->sh_info
02608 + r_symndx] != (bfd_vma) -1)
02609 {
02610
02611 break;
02612 }
02613 local_got_offsets[symtab_hdr->sh_info
02614 + r_symndx] = sgot->size;
02615 }
02616 else
02617 {
02618 if (local_got_offsets[r_symndx] != (bfd_vma) -1)
02619 {
02620
02621 break;
02622 }
02623 local_got_offsets[r_symndx] = sgot->size;
02624 }
02625
02626 if (info->shared)
02627 {
02628
02629
02630
02631 srelgot->size += sizeof (Elf64_External_Rela);
02632 }
02633 }
02634
02635 sgot->size += 8;
02636
02637 break;
02638
02639 case R_SH_GOTPLT_LOW16:
02640 case R_SH_GOTPLT_MEDLOW16:
02641 case R_SH_GOTPLT_MEDHI16:
02642 case R_SH_GOTPLT_HI16:
02643 case R_SH_GOTPLT10BY4:
02644 case R_SH_GOTPLT10BY8:
02645
02646
02647
02648 if (h == NULL
02649 || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
02650 || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
02651 || ! info->shared
02652 || info->symbolic
02653 || h->dynindx == -1
02654 || h->got.offset != (bfd_vma) -1)
02655 goto force_got;
02656
02657
02658 if (h->dynindx == -1)
02659 {
02660 if (! bfd_elf_link_record_dynamic_symbol (info, h))
02661 return FALSE;
02662 }
02663
02664 h->needs_plt = 1;
02665
02666 break;
02667
02668 case R_SH_PLT_LOW16:
02669 case R_SH_PLT_MEDLOW16:
02670 case R_SH_PLT_MEDHI16:
02671 case R_SH_PLT_HI16:
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681 if (h == NULL)
02682 continue;
02683
02684 if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
02685 || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
02686 break;
02687
02688 h->needs_plt = 1;
02689
02690 break;
02691
02692 case R_SH_64:
02693 case R_SH_64_PCREL:
02694 if (h != NULL)
02695 h->non_got_ref = 1;
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709 if (info->shared
02710 && (sec->flags & SEC_ALLOC) != 0
02711 && (ELF32_R_TYPE (rel->r_info) != R_SH_64_PCREL
02712 || (h != NULL
02713 && (! info->symbolic
02714 || !h->def_regular))))
02715 {
02716
02717
02718
02719 if (sreloc == NULL)
02720 {
02721 const char *name;
02722
02723 name = (bfd_elf_string_from_elf_section
02724 (abfd,
02725 elf_elfheader (abfd)->e_shstrndx,
02726 elf_section_data (sec)->rel_hdr.sh_name));
02727 if (name == NULL)
02728 return FALSE;
02729
02730 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
02731 && strcmp (bfd_get_section_name (abfd, sec),
02732 name + 5) == 0);
02733
02734 sreloc = bfd_get_section_by_name (dynobj, name);
02735 if (sreloc == NULL)
02736 {
02737 flagword flags;
02738
02739 sreloc = bfd_make_section (dynobj, name);
02740 flags = (SEC_HAS_CONTENTS | SEC_READONLY
02741 | SEC_IN_MEMORY | SEC_LINKER_CREATED);
02742 if ((sec->flags & SEC_ALLOC) != 0)
02743 flags |= SEC_ALLOC | SEC_LOAD;
02744 if (sreloc == NULL
02745 || ! bfd_set_section_flags (dynobj, sreloc, flags)
02746 || ! bfd_set_section_alignment (dynobj, sreloc, 2))
02747 return FALSE;
02748 }
02749 }
02750
02751 sreloc->size += sizeof (Elf64_External_Rela);
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761 if (h != NULL && info->symbolic
02762 && ELF64_R_TYPE (rel->r_info) == R_SH_64_PCREL)
02763 {
02764 struct elf_sh64_link_hash_entry *eh;
02765 struct elf_sh64_pcrel_relocs_copied *p;
02766
02767 eh = (struct elf_sh64_link_hash_entry *) h;
02768
02769 for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)
02770 if (p->section == sreloc)
02771 break;
02772
02773 if (p == NULL)
02774 {
02775 p = ((struct elf_sh64_pcrel_relocs_copied *)
02776 bfd_alloc (dynobj, sizeof *p));
02777 if (p == NULL)
02778 return FALSE;
02779 p->next = eh->pcrel_relocs_copied;
02780 eh->pcrel_relocs_copied = p;
02781 p->section = sreloc;
02782 p->count = 0;
02783 }
02784
02785 ++p->count;
02786 }
02787 }
02788
02789 break;
02790 }
02791 }
02792
02793 return TRUE;
02794 }
02795
02796 static int
02797 sh64_elf64_get_symbol_type (Elf_Internal_Sym * elf_sym, int type)
02798 {
02799 if (ELF_ST_TYPE (elf_sym->st_info) == STT_DATALABEL)
02800 return STT_DATALABEL;
02801
02802 return type;
02803 }
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827 static bfd_boolean
02828 sh64_elf64_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
02829 Elf_Internal_Sym *sym, const char **namep,
02830 flagword *flagsp ATTRIBUTE_UNUSED,
02831 asection **secp, bfd_vma *valp)
02832 {
02833
02834 if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL
02835 && is_elf_hash_table (info->hash))
02836 {
02837 struct elf_link_hash_entry *h;
02838
02839
02840
02841
02842 flagword flags
02843 = info->relocatable || info->emitrelocations
02844 ? BSF_GLOBAL : BSF_GLOBAL | BSF_INDIRECT;
02845
02846 char *dl_name
02847 = bfd_malloc (strlen (*namep) + sizeof (DATALABEL_SUFFIX));
02848 struct elf_link_hash_entry ** sym_hash = elf_sym_hashes (abfd);
02849
02850 BFD_ASSERT (sym_hash != NULL);
02851
02852
02853 if (dl_name == NULL)
02854 return FALSE;
02855
02856 strcpy (dl_name, *namep);
02857 strcat (dl_name, DATALABEL_SUFFIX);
02858
02859 h = (struct elf_link_hash_entry *)
02860 bfd_link_hash_lookup (info->hash, dl_name, FALSE, FALSE, FALSE);
02861
02862 if (h == NULL)
02863 {
02864
02865 struct bfd_link_hash_entry *bh = NULL;
02866 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
02867
02868 if (! _bfd_generic_link_add_one_symbol (info, abfd, dl_name,
02869 flags, *secp, *valp,
02870 *namep, FALSE,
02871 bed->collect, &bh))
02872 {
02873 free (dl_name);
02874 return FALSE;
02875 }
02876
02877 h = (struct elf_link_hash_entry *) bh;
02878 h->non_elf = 0;
02879 h->type = STT_DATALABEL;
02880 }
02881 else
02882
02883
02884 free (dl_name);
02885
02886 if (h->type != STT_DATALABEL
02887 || ((info->relocatable || info->emitrelocations)
02888 && h->root.type != bfd_link_hash_undefined)
02889 || (! info->relocatable && !info->emitrelocations
02890 && h->root.type != bfd_link_hash_indirect))
02891 {
02892
02893 (*_bfd_error_handler)
02894 (_("%s: encountered datalabel symbol in input"),
02895 bfd_get_filename (abfd));
02896 bfd_set_error (bfd_error_bad_value);
02897 return FALSE;
02898 }
02899
02900
02901 while (*sym_hash != NULL)
02902 sym_hash++;
02903 *sym_hash = h;
02904
02905
02906 *namep = NULL;
02907 }
02908
02909 return TRUE;
02910 }
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924 static bfd_boolean
02925 sh64_elf64_link_output_symbol_hook (struct bfd_link_info *info,
02926 const char *cname,
02927 Elf_Internal_Sym *sym,
02928 asection *input_sec ATTRIBUTE_UNUSED,
02929 struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
02930 {
02931 char *name = (char *) cname;
02932
02933 if (info->relocatable || info->emitrelocations)
02934 {
02935 if (ELF_ST_TYPE (sym->st_info) == STT_DATALABEL)
02936 name[strlen (name) - strlen (DATALABEL_SUFFIX)] = 0;
02937 }
02938
02939 return TRUE;
02940 }
02941
02942
02943
02944
02945
02946
02947
02948
02949 static void
02950 sh64_elf64_final_write_processing (bfd *abfd,
02951 bfd_boolean linker ATTRIBUTE_UNUSED)
02952 {
02953
02954
02955
02956
02957 if (elf_elfheader (abfd)->e_type == ET_EXEC)
02958 elf_elfheader (abfd)->e_entry |= 1;
02959 }
02960
02961
02962
02963 static const bfd_byte elf_sh64_plt0_entry_be[PLT_ENTRY_SIZE] =
02964 {
02965 0xcc, 0x00, 0x01, 0x10,
02966 0xc8, 0x00, 0x01, 0x10,
02967 0xc8, 0x00, 0x01, 0x10,
02968 0xc8, 0x00, 0x01, 0x10,
02969 0x8d, 0x10, 0x09, 0x90,
02970 0x6b, 0xf1, 0x66, 0x00,
02971 0x8d, 0x10, 0x05, 0x10,
02972 0x44, 0x01, 0xff, 0xf0,
02973 0x6f, 0xf0, 0xff, 0xf0,
02974 0x6f, 0xf0, 0xff, 0xf0,
02975 0x6f, 0xf0, 0xff, 0xf0,
02976 0x6f, 0xf0, 0xff, 0xf0,
02977 0x6f, 0xf0, 0xff, 0xf0,
02978 0x6f, 0xf0, 0xff, 0xf0,
02979 0x6f, 0xf0, 0xff, 0xf0,
02980 0x6f, 0xf0, 0xff, 0xf0,
02981 };
02982
02983 static const bfd_byte elf_sh64_plt0_entry_le[PLT_ENTRY_SIZE] =
02984 {
02985 0x10, 0x01, 0x00, 0xcc,
02986 0x10, 0x01, 0x00, 0xc8,
02987 0x10, 0x01, 0x00, 0xc8,
02988 0x10, 0x01, 0x00, 0xc8,
02989 0x90, 0x09, 0x10, 0x8d,
02990 0x00, 0x66, 0xf1, 0x6b,
02991 0x10, 0x05, 0x10, 0x8d,
02992 0xf0, 0xff, 0x01, 0x44,
02993 0xf0, 0xff, 0xf0, 0x6f,
02994 0xf0, 0xff, 0xf0, 0x6f,
02995 0xf0, 0xff, 0xf0, 0x6f,
02996 0xf0, 0xff, 0xf0, 0x6f,
02997 0xf0, 0xff, 0xf0, 0x6f,
02998 0xf0, 0xff, 0xf0, 0x6f,
02999 0xf0, 0xff, 0xf0, 0x6f,
03000 0xf0, 0xff, 0xf0, 0x6f,
03001 };
03002
03003
03004
03005
03006 static const bfd_byte elf_sh64_plt_entry_be[PLT_ENTRY_SIZE] =
03007 {
03008 0xcc, 0x00, 0x01, 0x90,
03009 0xc8, 0x00, 0x01, 0x90,
03010 0xc8, 0x00, 0x01, 0x90,
03011 0xc8, 0x00, 0x01, 0x90,
03012 0x8d, 0x90, 0x01, 0x90,
03013 0x6b, 0xf1, 0x66, 0x00,
03014 0x44, 0x01, 0xff, 0xf0,
03015 0x6f, 0xf0, 0xff, 0xf0,
03016 0xcc, 0x00, 0x01, 0x90,
03017 0xc8, 0x00, 0x01, 0x90,
03018 0x6b, 0xf5, 0x66, 0x00,
03019 0xcc, 0x00, 0x01, 0x50,
03020 0xc8, 0x00, 0x01, 0x50,
03021 0x44, 0x01, 0xff, 0xf0,
03022 0x6f, 0xf0, 0xff, 0xf0,
03023 0x6f, 0xf0, 0xff, 0xf0,
03024 };
03025
03026 static const bfd_byte elf_sh64_plt_entry_le[PLT_ENTRY_SIZE] =
03027 {
03028 0x90, 0x01, 0x00, 0xcc,
03029 0x90, 0x01, 0x00, 0xc8,
03030 0x90, 0x01, 0x00, 0xc8,
03031 0x90, 0x01, 0x00, 0xc8,
03032 0x90, 0x01, 0x90, 0x8d,
03033 0x00, 0x66, 0xf1, 0x6b,
03034 0xf0, 0xff, 0x01, 0x44,
03035 0xf0, 0xff, 0xf0, 0x6f,
03036 0x90, 0x01, 0x00, 0xcc,
03037 0x90, 0x01, 0x00, 0xc8,
03038 0x00, 0x66, 0xf5, 0x6b,
03039 0x50, 0x01, 0x00, 0xcc,
03040 0x50, 0x01, 0x00, 0xc8,
03041 0xf0, 0xff, 0x01, 0x44,
03042 0xf0, 0xff, 0xf0, 0x6f,
03043 0xf0, 0xff, 0xf0, 0x6f,
03044 };
03045
03046
03047
03048 static const bfd_byte elf_sh64_pic_plt_entry_be[PLT_ENTRY_SIZE] =
03049 {
03050 0xcc, 0x00, 0x01, 0x90,
03051 0xc8, 0x00, 0x01, 0x90,
03052 0x40, 0xc3, 0x65, 0x90,
03053 0x6b, 0xf1, 0x66, 0x00,
03054 0x44, 0x01, 0xff, 0xf0,
03055 0x6f, 0xf0, 0xff, 0xf0,
03056 0x6f, 0xf0, 0xff, 0xf0,
03057 0x6f, 0xf0, 0xff, 0xf0,
03058 0xce, 0x00, 0x01, 0x10,
03059 0x00, 0xc9, 0x45, 0x10,
03060 0x8d, 0x10, 0x09, 0x90,
03061 0x6b, 0xf1, 0x66, 0x00,
03062 0x8d, 0x10, 0x05, 0x10,
03063 0xcc, 0x00, 0x01, 0x50,
03064 0xc8, 0x00, 0x01, 0x50,
03065 0x44, 0x01, 0xff, 0xf0,
03066 };
03067
03068 static const bfd_byte elf_sh64_pic_plt_entry_le[PLT_ENTRY_SIZE] =
03069 {
03070 0x90, 0x01, 0x00, 0xcc,
03071 0x90, 0x01, 0x00, 0xc8,
03072 0x90, 0x65, 0xc3, 0x40,
03073 0x00, 0x66, 0xf1, 0x6b,
03074 0xf0, 0xff, 0x01, 0x44,
03075 0xf0, 0xff, 0xf0, 0x6f,
03076 0xf0, 0xff, 0xf0, 0x6f,
03077 0xf0, 0xff, 0xf0, 0x6f,
03078 0x10, 0x01, 0x00, 0xce,
03079 0x10, 0x45, 0xc9, 0x00,
03080 0x90, 0x09, 0x10, 0x8d,
03081 0x00, 0x66, 0xf1, 0x6b,
03082 0x10, 0x05, 0x10, 0x8d,
03083 0x50, 0x01, 0x00, 0xcc,
03084 0x50, 0x01, 0x00, 0xc8,
03085 0xf0, 0xff, 0x01, 0x44,
03086 };
03087
03088 static const bfd_byte *elf_sh64_plt0_entry;
03089 static const bfd_byte *elf_sh64_plt_entry;
03090 static const bfd_byte *elf_sh64_pic_plt_entry;
03091
03092
03093
03094 static struct bfd_hash_entry *
03095 sh64_elf64_link_hash_newfunc (struct bfd_hash_entry *entry,
03096 struct bfd_hash_table *table,
03097 const char *string)
03098 {
03099 struct elf_sh64_link_hash_entry *ret =
03100 (struct elf_sh64_link_hash_entry *) entry;
03101
03102
03103
03104 if (ret == (struct elf_sh64_link_hash_entry *) NULL)
03105 ret = ((struct elf_sh64_link_hash_entry *)
03106 bfd_hash_allocate (table,
03107 sizeof (struct elf_sh64_link_hash_entry)));
03108 if (ret == (struct elf_sh64_link_hash_entry *) NULL)
03109 return (struct bfd_hash_entry *) ret;
03110
03111
03112 ret = ((struct elf_sh64_link_hash_entry *)
03113 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
03114 table, string));
03115 if (ret != (struct elf_sh64_link_hash_entry *) NULL)
03116 {
03117 ret->pcrel_relocs_copied = NULL;
03118 ret->datalabel_got_offset = (bfd_vma) -1;
03119 }
03120
03121 return (struct bfd_hash_entry *) ret;
03122 }
03123
03124
03125
03126 static struct bfd_link_hash_table *
03127 sh64_elf64_link_hash_table_create (bfd *abfd)
03128 {
03129 struct elf_sh64_link_hash_table *ret;
03130
03131 ret = ((struct elf_sh64_link_hash_table *)
03132 bfd_malloc (sizeof (struct elf_sh64_link_hash_table)));
03133 if (ret == (struct elf_sh64_link_hash_table *) NULL)
03134 return NULL;
03135
03136 if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
03137 sh64_elf64_link_hash_newfunc))
03138 {
03139 free (ret);
03140 return NULL;
03141 }
03142
03143 return &ret->root.root;
03144 }
03145
03146 inline static void
03147 movi_shori_putval (bfd *output_bfd, unsigned long value, bfd_byte *addr)
03148 {
03149 bfd_put_32 (output_bfd,
03150 bfd_get_32 (output_bfd, addr)
03151 | ((value >> 6) & 0x3fffc00),
03152 addr);
03153 bfd_put_32 (output_bfd,
03154 bfd_get_32 (output_bfd, addr + 4)
03155 | ((value << 10) & 0x3fffc00),
03156 addr + 4);
03157 }
03158
03159 inline static void
03160 movi_3shori_putval (bfd *output_bfd, bfd_vma value, bfd_byte *addr)
03161 {
03162 bfd_put_32 (output_bfd,
03163 bfd_get_32 (output_bfd, addr)
03164 | ((value >> 38) & 0x3fffc00),
03165 addr);
03166 bfd_put_32 (output_bfd,
03167 bfd_get_32 (output_bfd, addr + 4)
03168 | ((value >> 22) & 0x3fffc00),
03169 addr + 4);
03170 bfd_put_32 (output_bfd,
03171 bfd_get_32 (output_bfd, addr + 8)
03172 | ((value >> 6) & 0x3fffc00),
03173 addr + 8);
03174 bfd_put_32 (output_bfd,
03175 bfd_get_32 (output_bfd, addr + 12)
03176 | ((value << 10) & 0x3fffc00),
03177 addr + 12);
03178 }
03179
03180
03181
03182 static bfd_boolean
03183 sh64_elf64_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
03184 {
03185 flagword flags, pltflags;
03186 register asection *s;
03187 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
03188 int ptralign = 0;
03189
03190 switch (bed->s->arch_size)
03191 {
03192 case 32:
03193 ptralign = 2;
03194 break;
03195
03196 case 64:
03197 ptralign = 3;
03198 break;
03199
03200 default:
03201 bfd_set_error (bfd_error_bad_value);
03202 return FALSE;
03203 }
03204
03205
03206
03207
03208 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
03209 | SEC_LINKER_CREATED);
03210
03211 pltflags = flags;
03212 pltflags |= SEC_CODE;
03213 if (bed->plt_not_loaded)
03214 pltflags &= ~ (SEC_LOAD | SEC_HAS_CONTENTS);
03215 if (bed->plt_readonly)
03216 pltflags |= SEC_READONLY;
03217
03218 s = bfd_make_section (abfd, ".plt");
03219 if (s == NULL
03220 || ! bfd_set_section_flags (abfd, s, pltflags)
03221 || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
03222 return FALSE;
03223
03224 if (bed->want_plt_sym)
03225 {
03226
03227
03228 struct elf_link_hash_entry *h;
03229 struct bfd_link_hash_entry *bh = NULL;
03230
03231 if (! (_bfd_generic_link_add_one_symbol
03232 (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
03233 (bfd_vma) 0, (const char *) NULL, FALSE, bed->collect, &bh)))
03234 return FALSE;
03235
03236 h = (struct elf_link_hash_entry *) bh;
03237 h->def_regular = 1;
03238 h->type = STT_OBJECT;
03239
03240 if (info->shared
03241 && ! bfd_elf_link_record_dynamic_symbol (info, h))
03242 return FALSE;
03243 }
03244
03245 s = bfd_make_section (abfd,
03246 bed->default_use_rela_p ? ".rela.plt" : ".rel.plt");
03247 if (s == NULL
03248 || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
03249 || ! bfd_set_section_alignment (abfd, s, ptralign))
03250 return FALSE;
03251
03252 if (! _bfd_elf_create_got_section (abfd, info))
03253 return FALSE;
03254
03255 {
03256 const char *secname;
03257 char *relname;
03258 flagword secflags;
03259 asection *sec;
03260
03261 for (sec = abfd->sections; sec; sec = sec->next)
03262 {
03263 secflags = bfd_get_section_flags (abfd, sec);
03264 if ((secflags & (SEC_DATA | SEC_LINKER_CREATED))
03265 || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS))
03266 continue;
03267 secname = bfd_get_section_name (abfd, sec);
03268 relname = (char *) bfd_malloc (strlen (secname) + 6);
03269 strcpy (relname, ".rela");
03270 strcat (relname, secname);
03271 s = bfd_make_section (abfd, relname);
03272 if (s == NULL
03273 || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
03274 || ! bfd_set_section_alignment (abfd, s, ptralign))
03275 return FALSE;
03276 }
03277 }
03278
03279 if (bed->want_dynbss)
03280 {
03281
03282
03283
03284
03285
03286
03287 s = bfd_make_section (abfd, ".dynbss");
03288 if (s == NULL
03289 || ! bfd_set_section_flags (abfd, s, SEC_ALLOC))
03290 return FALSE;
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303 if (! info->shared)
03304 {
03305 s = bfd_make_section (abfd,
03306 (bed->default_use_rela_p
03307 ? ".rela.bss" : ".rel.bss"));
03308 if (s == NULL
03309 || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
03310 || ! bfd_set_section_alignment (abfd, s, ptralign))
03311 return FALSE;
03312 }
03313 }
03314
03315 return TRUE;
03316 }
03317
03318
03319
03320
03321
03322
03323
03324 static bfd_boolean
03325 sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *info,
03326 struct elf_link_hash_entry *h)
03327 {
03328 bfd *dynobj;
03329 asection *s;
03330 unsigned int power_of_two;
03331
03332 dynobj = elf_hash_table (info)->dynobj;
03333
03334
03335 BFD_ASSERT (dynobj != NULL
03336 && (h->needs_plt
03337 || h->u.weakdef != NULL
03338 || (h->def_dynamic
03339 && h->ref_regular
03340 && !h->def_regular)));
03341
03342
03343
03344
03345 if (h->type == STT_FUNC
03346 || h->needs_plt)
03347 {
03348 if (! info->shared
03349 && !h->def_dynamic
03350 && !h->ref_dynamic)
03351 {
03352
03353
03354
03355
03356
03357 BFD_ASSERT (h->needs_plt);
03358 return TRUE;
03359 }
03360
03361
03362 if (h->dynindx == -1)
03363 {
03364 if (! bfd_elf_link_record_dynamic_symbol (info, h))
03365 return FALSE;
03366 }
03367
03368 s = bfd_get_section_by_name (dynobj, ".plt");
03369 BFD_ASSERT (s != NULL);
03370
03371
03372
03373 if (s->size == 0)
03374 s->size += PLT_ENTRY_SIZE;
03375
03376
03377
03378
03379
03380
03381 if (! info->shared
03382 && !h->def_regular)
03383 {
03384 h->root.u.def.section = s;
03385 h->root.u.def.value = s->size;
03386 }
03387
03388 h->plt.offset = s->size;
03389
03390
03391 s->size += elf_sh64_sizeof_plt (info);
03392
03393
03394
03395
03396 s = bfd_get_section_by_name (dynobj, ".got.plt");
03397 BFD_ASSERT (s != NULL);
03398 s->size += 8;
03399
03400
03401
03402 s = bfd_get_section_by_name (dynobj, ".rela.plt");
03403 BFD_ASSERT (s != NULL);
03404 s->size += sizeof (Elf64_External_Rela);
03405
03406 return TRUE;
03407 }
03408
03409
03410
03411
03412 if (h->u.weakdef != NULL)
03413 {
03414 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
03415 || h->u.weakdef->root.type == bfd_link_hash_defweak);
03416 h->root.u.def.section = h->u.weakdef->root.u.def.section;
03417 h->root.u.def.value = h->u.weakdef->root.u.def.value;
03418 return TRUE;
03419 }
03420
03421
03422
03423
03424
03425
03426
03427
03428 if (info->shared)
03429 return TRUE;
03430
03431
03432
03433 if (!h->non_got_ref)
03434 return TRUE;
03435
03436
03437
03438
03439
03440
03441
03442
03443
03444
03445
03446 s = bfd_get_section_by_name (dynobj, ".dynbss");
03447 BFD_ASSERT (s != NULL);
03448
03449
03450
03451
03452
03453 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
03454 {
03455 asection *srel;
03456
03457 srel = bfd_get_section_by_name (dynobj, ".rela.bss");
03458 BFD_ASSERT (srel != NULL);
03459 srel->size += sizeof (Elf64_External_Rela);
03460 h->needs_copy = 1;
03461 }
03462
03463
03464
03465 power_of_two = bfd_log2 (h->size);
03466 if (power_of_two > 3)
03467 power_of_two = 3;
03468
03469
03470 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
03471 if (power_of_two > bfd_get_section_alignment (dynobj, s))
03472 {
03473 if (! bfd_set_section_alignment (dynobj, s, power_of_two))
03474 return FALSE;
03475 }
03476
03477
03478 h->root.u.def.section = s;
03479 h->root.u.def.value = s->size;
03480
03481
03482 s->size += h->size;
03483
03484 return TRUE;
03485 }
03486
03487
03488
03489
03490
03491
03492
03493
03494 static bfd_boolean
03495 sh64_elf64_discard_copies (struct elf_sh64_link_hash_entry *h,
03496 void *ignore ATTRIBUTE_UNUSED)
03497 {
03498 struct elf_sh64_pcrel_relocs_copied *s;
03499
03500 if (h->root.root.type == bfd_link_hash_warning)
03501 h = (struct elf_sh64_link_hash_entry *) h->root.root.u.i.link;
03502
03503
03504 if (!h->root.def_regular)
03505 return TRUE;
03506
03507 for (s = h->pcrel_relocs_copied; s != NULL; s = s->next)
03508 s->section->size -= s->count * sizeof (Elf64_External_Rela);
03509
03510 return TRUE;
03511 }
03512
03513
03514
03515 static bfd_boolean
03516 sh64_elf64_size_dynamic_sections (bfd *output_bfd,
03517 struct bfd_link_info *info)
03518 {
03519 bfd *dynobj;
03520 asection *s;
03521 bfd_boolean plt;
03522 bfd_boolean relocs;
03523 bfd_boolean reltext;
03524
03525 dynobj = elf_hash_table (info)->dynobj;
03526 BFD_ASSERT (dynobj != NULL);
03527
03528 if (elf_hash_table (info)->dynamic_sections_created)
03529 {
03530
03531 if (info->executable)
03532 {
03533 s = bfd_get_section_by_name (dynobj, ".interp");
03534 BFD_ASSERT (s != NULL);
03535 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
03536 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
03537 }
03538 }
03539 else
03540 {
03541
03542
03543
03544
03545
03546 s = bfd_get_section_by_name (dynobj, ".rela.got");
03547 if (s != NULL)
03548 s->size = 0;
03549 }
03550
03551
03552
03553
03554
03555 if (info->shared && info->symbolic)
03556 sh64_elf64_link_hash_traverse (sh64_elf64_hash_table (info),
03557 sh64_elf64_discard_copies, NULL);
03558
03559
03560
03561
03562 plt = FALSE;
03563 relocs = FALSE;
03564 reltext = FALSE;
03565 for (s = dynobj->sections; s != NULL; s = s->next)
03566 {
03567 const char *name;
03568 bfd_boolean strip;
03569
03570 if ((s->flags & SEC_LINKER_CREATED) == 0)
03571 continue;
03572
03573
03574
03575 name = bfd_get_section_name (dynobj, s);
03576
03577 strip = FALSE;
03578
03579 if (strcmp (name, ".plt") == 0)
03580 {
03581 if (s->size == 0)
03582 {
03583
03584
03585 strip = TRUE;
03586 }
03587 else
03588 {
03589
03590 plt = TRUE;
03591 }
03592 }
03593 else if (strncmp (name, ".rela", 5) == 0)
03594 {
03595 if (s->size == 0)
03596 {
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606 strip = TRUE;
03607 }
03608 else
03609 {
03610 asection *target;
03611
03612
03613
03614 if (strcmp (name, ".rela.plt") != 0)
03615 {
03616 const char *outname;
03617
03618 relocs = TRUE;
03619
03620
03621
03622
03623
03624
03625 outname = bfd_get_section_name (output_bfd,
03626 s->output_section);
03627 target = bfd_get_section_by_name (output_bfd, outname + 5);
03628 if (target != NULL
03629 && (target->flags & SEC_READONLY) != 0
03630 && (target->flags & SEC_ALLOC) != 0)
03631 reltext = TRUE;
03632 }
03633
03634
03635
03636 s->reloc_count = 0;
03637 }
03638 }
03639 else if (strncmp (name, ".got", 4) != 0)
03640 {
03641
03642 continue;
03643 }
03644
03645 if (strip)
03646 {
03647 _bfd_strip_section_from_output (info, s);
03648 continue;
03649 }
03650
03651
03652 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
03653 if (s->contents == NULL && s->size != 0)
03654 return FALSE;
03655 }
03656
03657 if (elf_hash_table (info)->dynamic_sections_created)
03658 {
03659
03660
03661
03662
03663
03664 if (info->executable)
03665 {
03666 if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
03667 return FALSE;
03668 }
03669
03670 if (plt)
03671 {
03672 if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
03673 || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
03674 || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
03675 || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
03676 return FALSE;
03677 }
03678
03679 if (relocs)
03680 {
03681 if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
03682 || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
03683 || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
03684 sizeof (Elf64_External_Rela)))
03685 return FALSE;
03686 }
03687
03688 if (reltext)
03689 {
03690 if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
03691 return FALSE;
03692 }
03693 }
03694
03695 return TRUE;
03696 }
03697
03698
03699
03700
03701 static bfd_boolean
03702 sh64_elf64_finish_dynamic_symbol (bfd *output_bfd,
03703 struct bfd_link_info *info,
03704 struct elf_link_hash_entry *h,
03705 Elf_Internal_Sym *sym)
03706 {
03707 bfd *dynobj;
03708
03709 dynobj = elf_hash_table (info)->dynobj;
03710
03711 if (h->plt.offset != (bfd_vma) -1)
03712 {
03713 asection *splt;
03714 asection *sgot;
03715 asection *srel;
03716
03717 bfd_vma plt_index;
03718 bfd_vma got_offset;
03719 Elf_Internal_Rela rel;
03720 bfd_byte *loc;
03721
03722
03723
03724
03725 BFD_ASSERT (h->dynindx != -1);
03726
03727 splt = bfd_get_section_by_name (dynobj, ".plt");
03728 sgot = bfd_get_section_by_name (dynobj, ".got.plt");
03729 srel = bfd_get_section_by_name (dynobj, ".rela.plt");
03730 BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
03731
03732
03733
03734
03735
03736 plt_index = h->plt.offset / elf_sh64_sizeof_plt (info) - 1;
03737
03738
03739
03740
03741 got_offset = (plt_index + 3) * 8;
03742
03743 if (info->shared)
03744 got_offset -= GOT_BIAS;
03745
03746
03747 if (! info->shared)
03748 {
03749 if (elf_sh64_plt_entry == NULL)
03750 {
03751 elf_sh64_plt_entry = (bfd_big_endian (output_bfd) ?
03752 elf_sh64_plt_entry_be : elf_sh64_plt_entry_le);
03753 }
03754 memcpy (splt->contents + h->plt.offset, elf_sh64_plt_entry,
03755 elf_sh64_sizeof_plt (info));
03756 movi_3shori_putval (output_bfd,
03757 (sgot->output_section->vma
03758 + sgot->output_offset
03759 + got_offset),
03760 (splt->contents + h->plt.offset
03761 + elf_sh64_plt_symbol_offset (info)));
03762
03763
03764 movi_shori_putval (output_bfd,
03765 -(h->plt.offset
03766 + elf_sh64_plt_plt0_offset (info) + 8)
03767 | 1,
03768 (splt->contents + h->plt.offset
03769 + elf_sh64_plt_plt0_offset (info)));
03770 }
03771 else
03772 {
03773 if (elf_sh64_pic_plt_entry == NULL)
03774 {
03775 elf_sh64_pic_plt_entry = (bfd_big_endian (output_bfd) ?
03776 elf_sh64_pic_plt_entry_be :
03777 elf_sh64_pic_plt_entry_le);
03778 }
03779 memcpy (splt->contents + h->plt.offset, elf_sh64_pic_plt_entry,
03780 elf_sh64_sizeof_plt (info));
03781 movi_shori_putval (output_bfd, got_offset,
03782 (splt->contents + h->plt.offset
03783 + elf_sh64_plt_symbol_offset (info)));
03784 }
03785
03786 if (info->shared)
03787 got_offset += GOT_BIAS;
03788
03789 movi_shori_putval (output_bfd,
03790 plt_index * sizeof (Elf64_External_Rela),
03791 (splt->contents + h->plt.offset
03792 + elf_sh64_plt_reloc_offset (info)));
03793
03794
03795 bfd_put_64 (output_bfd,
03796 (splt->output_section->vma
03797 + splt->output_offset
03798 + h->plt.offset
03799 + elf_sh64_plt_temp_offset (info)),
03800 sgot->contents + got_offset);
03801
03802
03803 rel.r_offset = (sgot->output_section->vma
03804 + sgot->output_offset
03805 + got_offset);
03806 rel.r_info = ELF64_R_INFO (h->dynindx, R_SH_JMP_SLOT64);
03807 rel.r_addend = 0;
03808 rel.r_addend = GOT_BIAS;
03809 loc = srel->contents + plt_index * sizeof (Elf64_External_Rela);
03810 bfd_elf64_swap_reloca_out (output_bfd, &rel, loc);
03811
03812 if (!h->def_regular)
03813 {
03814
03815
03816 sym->st_shndx = SHN_UNDEF;
03817 }
03818 }
03819
03820 if (h->got.offset != (bfd_vma) -1)
03821 {
03822 asection *sgot;
03823 asection *srel;
03824 Elf_Internal_Rela rel;
03825 bfd_byte *loc;
03826
03827
03828
03829
03830 sgot = bfd_get_section_by_name (dynobj, ".got");
03831 srel = bfd_get_section_by_name (dynobj, ".rela.got");
03832 BFD_ASSERT (sgot != NULL && srel != NULL);
03833
03834 rel.r_offset = (sgot->output_section->vma
03835 + sgot->output_offset
03836 + (h->got.offset &~ 1));
03837
03838
03839
03840
03841
03842
03843 if (info->shared
03844 && (info->symbolic || h->dynindx == -1)
03845 && h->def_regular)
03846 {
03847 rel.r_info = ELF64_R_INFO (0, R_SH_RELATIVE64);
03848 rel.r_addend = (h->root.u.def.value
03849 + h->root.u.def.section->output_section->vma
03850 + h->root.u.def.section->output_offset);
03851 }
03852 else
03853 {
03854 bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
03855 rel.r_info = ELF64_R_INFO (h->dynindx, R_SH_GLOB_DAT64);
03856 rel.r_addend = 0;
03857 }
03858
03859 loc = srel->contents;
03860 loc += srel->reloc_count++ * sizeof (Elf64_External_Rela);
03861 bfd_elf64_swap_reloca_out (output_bfd, &rel, loc);
03862 }
03863
03864 if (h->needs_copy)
03865 {
03866 asection *s;
03867 Elf_Internal_Rela rel;
03868 bfd_byte *loc;
03869
03870
03871
03872 BFD_ASSERT (h->dynindx != -1
03873 && (h->root.type == bfd_link_hash_defined
03874 || h->root.type == bfd_link_hash_defweak));
03875
03876 s = bfd_get_section_by_name (h->root.u.def.section->owner,
03877 ".rela.bss");
03878 BFD_ASSERT (s != NULL);
03879
03880 rel.r_offset = (h->root.u.def.value
03881 + h->root.u.def.section->output_section->vma
03882 + h->root.u.def.section->output_offset);
03883 rel.r_info = ELF64_R_INFO (h->dynindx, R_SH_COPY64);
03884 rel.r_addend = 0;
03885 loc = s->contents;
03886 loc += s->reloc_count++ * sizeof (Elf64_External_Rela);
03887 bfd_elf64_swap_reloca_out (output_bfd, &rel, loc);
03888 }
03889
03890
03891 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
03892 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
03893 sym->st_shndx = SHN_ABS;
03894
03895 return TRUE;
03896 }
03897
03898
03899
03900 static bfd_boolean
03901 sh64_elf64_finish_dynamic_sections (bfd *output_bfd,
03902 struct bfd_link_info *info)
03903 {
03904 bfd *dynobj;
03905 asection *sgot;
03906 asection *sdyn;
03907
03908 dynobj = elf_hash_table (info)->dynobj;
03909
03910 sgot = bfd_get_section_by_name (dynobj, ".got.plt");
03911 BFD_ASSERT (sgot != NULL);
03912 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
03913
03914 if (elf_hash_table (info)->dynamic_sections_created)
03915 {
03916 asection *splt;
03917 Elf64_External_Dyn *dyncon, *dynconend;
03918
03919 BFD_ASSERT (sdyn != NULL);
03920
03921 dyncon = (Elf64_External_Dyn *) sdyn->contents;
03922 dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
03923 for (; dyncon < dynconend; dyncon++)
03924 {
03925 Elf_Internal_Dyn dyn;
03926 const char *name;
03927 asection *s;
03928 struct elf_link_hash_entry *h;
03929
03930 bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
03931
03932 switch (dyn.d_tag)
03933 {
03934 default:
03935 break;
03936
03937 case DT_INIT:
03938 name = info->init_function;
03939 goto get_sym;
03940
03941 case DT_FINI:
03942 name = info->fini_function;
03943 get_sym:
03944 if (dyn.d_un.d_val != 0)
03945 {
03946 h = elf_link_hash_lookup (elf_hash_table (info), name,
03947 FALSE, FALSE, TRUE);
03948 if (h != NULL && (h->other & STO_SH5_ISA32))
03949 {
03950 dyn.d_un.d_val |= 1;
03951 bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
03952 }
03953 }
03954 break;
03955
03956 case DT_PLTGOT:
03957 name = ".got";
03958 goto get_vma;
03959
03960 case DT_JMPREL:
03961 name = ".rela.plt";
03962 get_vma:
03963 s = bfd_get_section_by_name (output_bfd, name);
03964 BFD_ASSERT (s != NULL);
03965 dyn.d_un.d_ptr = s->vma;
03966 bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
03967 break;
03968
03969 case DT_PLTRELSZ:
03970 s = bfd_get_section_by_name (output_bfd, ".rela.plt");
03971 BFD_ASSERT (s != NULL);
03972 dyn.d_un.d_val = s->size;
03973 bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
03974 break;
03975
03976 case DT_RELASZ:
03977
03978
03979
03980
03981
03982
03983
03984
03985
03986 s = bfd_get_section_by_name (output_bfd, ".rela.plt");
03987 if (s != NULL)
03988 dyn.d_un.d_val -= s->size;
03989 bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
03990 break;
03991 }
03992 }
03993
03994
03995 splt = bfd_get_section_by_name (dynobj, ".plt");
03996 if (splt && splt->size > 0)
03997 {
03998 if (info->shared)
03999 {
04000 if (elf_sh64_pic_plt_entry == NULL)
04001 {
04002 elf_sh64_pic_plt_entry = (bfd_big_endian (output_bfd) ?
04003 elf_sh64_pic_plt_entry_be :
04004 elf_sh64_pic_plt_entry_le);
04005 }
04006 memcpy (splt->contents, elf_sh64_pic_plt_entry,
04007 elf_sh64_sizeof_plt (info));
04008 }
04009 else
04010 {
04011 if (elf_sh64_plt0_entry == NULL)
04012 {
04013 elf_sh64_plt0_entry = (bfd_big_endian (output_bfd) ?
04014 elf_sh64_plt0_entry_be :
04015 elf_sh64_plt0_entry_le);
04016 }
04017 memcpy (splt->contents, elf_sh64_plt0_entry, PLT_ENTRY_SIZE);
04018 movi_3shori_putval (output_bfd,
04019 sgot->output_section->vma
04020 + sgot->output_offset,
04021 splt->contents
04022 + elf_sh64_plt0_gotplt_offset (info));
04023 }
04024
04025
04026
04027 elf_section_data (splt->output_section)->this_hdr.sh_entsize = 8;
04028 }
04029 }
04030
04031
04032 if (sgot->size > 0)
04033 {
04034 if (sdyn == NULL)
04035 bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents);
04036 else
04037 bfd_put_64 (output_bfd,
04038 sdyn->output_section->vma + sdyn->output_offset,
04039 sgot->contents);
04040 bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
04041 bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + 16);
04042 }
04043
04044 elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 8;
04045
04046 return TRUE;
04047 }
04048
04049
04050
04051 static void
04052 sh64_elf64_merge_symbol_attribute (struct elf_link_hash_entry *h,
04053 const Elf_Internal_Sym *isym,
04054 bfd_boolean definition,
04055 bfd_boolean dynamic)
04056 {
04057 if (isym->st_other != 0 && dynamic)
04058 {
04059 unsigned char other;
04060
04061
04062 other = (definition ? isym->st_other : h->other);
04063 other &= ~ ELF_ST_VISIBILITY (-1);
04064 h->other = other | ELF_ST_VISIBILITY (h->other);
04065 }
04066
04067 return;
04068 }
04069
04070 static struct bfd_elf_special_section const sh64_elf64_special_sections[]=
04071 {
04072 { ".cranges", 8, 0, SHT_PROGBITS, 0 },
04073 { NULL, 0, 0, 0, 0 }
04074 };
04075
04076 #define TARGET_BIG_SYM bfd_elf64_sh64_vec
04077 #define TARGET_BIG_NAME "elf64-sh64"
04078 #define TARGET_LITTLE_SYM bfd_elf64_sh64l_vec
04079 #define TARGET_LITTLE_NAME "elf64-sh64l"
04080 #define ELF_ARCH bfd_arch_sh
04081 #define ELF_MACHINE_CODE EM_SH
04082 #define ELF_MAXPAGESIZE 128
04083
04084 #define elf_symbol_leading_char '_'
04085
04086 #define bfd_elf64_bfd_reloc_type_lookup sh_elf64_reloc_type_lookup
04087 #define elf_info_to_howto sh_elf64_info_to_howto
04088
04089
04090
04091 #define elf_backend_relocate_section sh_elf64_relocate_section
04092 #define bfd_elf64_bfd_get_relocated_section_contents \
04093 sh_elf64_get_relocated_section_contents
04094 #define elf_backend_object_p sh_elf64_set_mach_from_flags
04095 #define bfd_elf64_bfd_set_private_flags \
04096 sh_elf64_set_private_flags
04097 #define bfd_elf64_bfd_copy_private_bfd_data \
04098 sh_elf64_copy_private_data
04099 #define bfd_elf64_bfd_merge_private_bfd_data \
04100 sh_elf64_merge_private_data
04101 #define elf_backend_fake_sections sh64_elf64_fake_sections
04102
04103 #define elf_backend_gc_mark_hook sh_elf64_gc_mark_hook
04104 #define elf_backend_gc_sweep_hook sh_elf64_gc_sweep_hook
04105 #define elf_backend_check_relocs sh_elf64_check_relocs
04106
04107 #define elf_backend_can_gc_sections 1
04108
04109 #define elf_backend_get_symbol_type sh64_elf64_get_symbol_type
04110
04111 #define elf_backend_add_symbol_hook sh64_elf64_add_symbol_hook
04112
04113 #define elf_backend_link_output_symbol_hook \
04114 sh64_elf64_link_output_symbol_hook
04115
04116 #define elf_backend_merge_symbol_attribute \
04117 sh64_elf64_merge_symbol_attribute
04118
04119 #define elf_backend_final_write_processing \
04120 sh64_elf64_final_write_processing
04121
04122 #define elf_backend_create_dynamic_sections \
04123 sh64_elf64_create_dynamic_sections
04124 #define bfd_elf64_bfd_link_hash_table_create \
04125 sh64_elf64_link_hash_table_create
04126 #define elf_backend_adjust_dynamic_symbol \
04127 sh64_elf64_adjust_dynamic_symbol
04128 #define elf_backend_size_dynamic_sections \
04129 sh64_elf64_size_dynamic_sections
04130 #define elf_backend_finish_dynamic_symbol \
04131 sh64_elf64_finish_dynamic_symbol
04132 #define elf_backend_finish_dynamic_sections \
04133 sh64_elf64_finish_dynamic_sections
04134 #define elf_backend_special_sections sh64_elf64_special_sections
04135
04136 #define elf_backend_want_got_plt 1
04137 #define elf_backend_plt_readonly 1
04138 #define elf_backend_want_plt_sym 0
04139 #define elf_backend_got_header_size 24
04140
04141 #include "elf64-target.h"
04142
04143
04144 #undef TARGET_BIG_SYM
04145 #define TARGET_BIG_SYM bfd_elf64_sh64nbsd_vec
04146 #undef TARGET_BIG_NAME
04147 #define TARGET_BIG_NAME "elf64-sh64-nbsd"
04148 #undef TARGET_LITTLE_SYM
04149 #define TARGET_LITTLE_SYM bfd_elf64_sh64lnbsd_vec
04150 #undef TARGET_LITTLE_NAME
04151 #define TARGET_LITTLE_NAME "elf64-sh64l-nbsd"
04152 #undef ELF_MAXPAGESIZE
04153 #define ELF_MAXPAGESIZE 0x10000
04154 #undef elf_symbol_leading_char
04155 #define elf_symbol_leading_char 0
04156
04157 #define elf64_bed elf64_sh64_nbsd_bed
04158
04159 #include "elf64-target.h"
04160
04161
04162 #undef TARGET_BIG_SYM
04163 #define TARGET_BIG_SYM bfd_elf64_sh64blin_vec
04164 #undef TARGET_BIG_NAME
04165 #define TARGET_BIG_NAME "elf64-sh64big-linux"
04166 #undef TARGET_LITTLE_SYM
04167 #define TARGET_LITTLE_SYM bfd_elf64_sh64lin_vec
04168 #undef TARGET_LITTLE_NAME
04169 #define TARGET_LITTLE_NAME "elf64-sh64-linux"
04170
04171 #define INCLUDED_TARGET_FILE
04172 #include "elf64-target.h"