00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "bfd.h"
00027 #include "sysdep.h"
00028 #include "bfdlink.h"
00029 #include "libbfd.h"
00030 #include "elf-bfd.h"
00031 #include "elf/sh.h"
00032 #include "libiberty.h"
00033 #include "../opcodes/sh-opc.h"
00034
00035 static bfd_reloc_status_type sh_elf_reloc
00036 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00037 static bfd_reloc_status_type sh_elf_ignore_reloc
00038 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00039 static bfd_boolean sh_elf_relax_delete_bytes
00040 (bfd *, asection *, bfd_vma, int);
00041 static bfd_boolean sh_elf_align_loads
00042 (bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_boolean *);
00043 #ifndef SH64_ELF
00044 static bfd_boolean sh_elf_swap_insns
00045 (bfd *, asection *, void *, bfd_byte *, bfd_vma);
00046 #endif
00047 static int sh_elf_optimized_tls_reloc
00048 (struct bfd_link_info *, int, int);
00049 static bfd_vma dtpoff_base
00050 (struct bfd_link_info *);
00051 static bfd_vma tpoff
00052 (struct bfd_link_info *, bfd_vma);
00053
00054
00055
00056
00057 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
00058
00059 static reloc_howto_type sh_elf_howto_table[] =
00060 {
00061
00062 HOWTO (R_SH_NONE,
00063 0,
00064 0,
00065 0,
00066 FALSE,
00067 0,
00068 complain_overflow_dont,
00069 sh_elf_ignore_reloc,
00070 "R_SH_NONE",
00071 FALSE,
00072 0,
00073 0,
00074 FALSE),
00075
00076
00077
00078 HOWTO (R_SH_DIR32,
00079 0,
00080 2,
00081 32,
00082 FALSE,
00083 0,
00084 complain_overflow_bitfield,
00085 sh_elf_reloc,
00086 "R_SH_DIR32",
00087 TRUE,
00088 0xffffffff,
00089 0xffffffff,
00090 FALSE),
00091
00092
00093 HOWTO (R_SH_REL32,
00094 0,
00095 2,
00096 32,
00097 TRUE,
00098 0,
00099 complain_overflow_signed,
00100 sh_elf_ignore_reloc,
00101 "R_SH_REL32",
00102 TRUE,
00103 0xffffffff,
00104 0xffffffff,
00105 TRUE),
00106
00107
00108 HOWTO (R_SH_DIR8WPN,
00109 1,
00110 1,
00111 8,
00112 TRUE,
00113 0,
00114 complain_overflow_signed,
00115 sh_elf_ignore_reloc,
00116 "R_SH_DIR8WPN",
00117 TRUE,
00118 0xff,
00119 0xff,
00120 TRUE),
00121
00122
00123
00124
00125 HOWTO (R_SH_IND12W,
00126 1,
00127 1,
00128 12,
00129 TRUE,
00130 0,
00131 complain_overflow_signed,
00132 NULL,
00133 "R_SH_IND12W",
00134 FALSE,
00135 0x0,
00136 0xfff,
00137 TRUE),
00138
00139
00140 HOWTO (R_SH_DIR8WPL,
00141 2,
00142 1,
00143 8,
00144 TRUE,
00145 0,
00146 complain_overflow_unsigned,
00147 sh_elf_ignore_reloc,
00148 "R_SH_DIR8WPL",
00149 TRUE,
00150 0xff,
00151 0xff,
00152 TRUE),
00153
00154
00155 HOWTO (R_SH_DIR8WPZ,
00156 1,
00157 1,
00158 8,
00159 TRUE,
00160 0,
00161 complain_overflow_unsigned,
00162 sh_elf_ignore_reloc,
00163 "R_SH_DIR8WPZ",
00164 TRUE,
00165 0xff,
00166 0xff,
00167 TRUE),
00168
00169
00170
00171
00172 HOWTO (R_SH_DIR8BP,
00173 0,
00174 1,
00175 8,
00176 FALSE,
00177 0,
00178 complain_overflow_unsigned,
00179 sh_elf_ignore_reloc,
00180 "R_SH_DIR8BP",
00181 FALSE,
00182 0,
00183 0xff,
00184 TRUE),
00185
00186
00187
00188
00189 HOWTO (R_SH_DIR8W,
00190 1,
00191 1,
00192 8,
00193 FALSE,
00194 0,
00195 complain_overflow_unsigned,
00196 sh_elf_ignore_reloc,
00197 "R_SH_DIR8W",
00198 FALSE,
00199 0,
00200 0xff,
00201 TRUE),
00202
00203
00204
00205
00206 HOWTO (R_SH_DIR8L,
00207 2,
00208 1,
00209 8,
00210 FALSE,
00211 0,
00212 complain_overflow_unsigned,
00213 sh_elf_ignore_reloc,
00214 "R_SH_DIR8L",
00215 FALSE,
00216 0,
00217 0xff,
00218 TRUE),
00219
00220
00221 HOWTO (R_SH_LOOP_START,
00222 1,
00223 1,
00224 8,
00225 FALSE,
00226 0,
00227 complain_overflow_signed,
00228 sh_elf_ignore_reloc,
00229 "R_SH_LOOP_START",
00230 TRUE,
00231 0xff,
00232 0xff,
00233 TRUE),
00234
00235
00236 HOWTO (R_SH_LOOP_END,
00237 1,
00238 1,
00239 8,
00240 FALSE,
00241 0,
00242 complain_overflow_signed,
00243 sh_elf_ignore_reloc,
00244 "R_SH_LOOP_END",
00245 TRUE,
00246 0xff,
00247 0xff,
00248 TRUE),
00249
00250 EMPTY_HOWTO (12),
00251 EMPTY_HOWTO (13),
00252 EMPTY_HOWTO (14),
00253 EMPTY_HOWTO (15),
00254 EMPTY_HOWTO (16),
00255 EMPTY_HOWTO (17),
00256 EMPTY_HOWTO (18),
00257 EMPTY_HOWTO (19),
00258 EMPTY_HOWTO (20),
00259 EMPTY_HOWTO (21),
00260
00261
00262
00263
00264
00265
00266
00267 HOWTO (R_SH_GNU_VTINHERIT,
00268 0,
00269 2,
00270 0,
00271 FALSE,
00272 0,
00273 complain_overflow_dont,
00274 NULL,
00275 "R_SH_GNU_VTINHERIT",
00276 FALSE,
00277 0,
00278 0,
00279 FALSE),
00280
00281
00282 HOWTO (R_SH_GNU_VTENTRY,
00283 0,
00284 2,
00285 0,
00286 FALSE,
00287 0,
00288 complain_overflow_dont,
00289 _bfd_elf_rel_vtable_reloc_fn,
00290 "R_SH_GNU_VTENTRY",
00291 FALSE,
00292 0,
00293 0,
00294 FALSE),
00295
00296
00297
00298
00299 HOWTO (R_SH_SWITCH8,
00300 0,
00301 0,
00302 8,
00303 FALSE,
00304 0,
00305 complain_overflow_unsigned,
00306 sh_elf_ignore_reloc,
00307 "R_SH_SWITCH8",
00308 FALSE,
00309 0,
00310 0,
00311 TRUE),
00312
00313
00314
00315
00316 HOWTO (R_SH_SWITCH16,
00317 0,
00318 1,
00319 16,
00320 FALSE,
00321 0,
00322 complain_overflow_unsigned,
00323 sh_elf_ignore_reloc,
00324 "R_SH_SWITCH16",
00325 FALSE,
00326 0,
00327 0,
00328 TRUE),
00329
00330
00331
00332
00333 HOWTO (R_SH_SWITCH32,
00334 0,
00335 2,
00336 32,
00337 FALSE,
00338 0,
00339 complain_overflow_unsigned,
00340 sh_elf_ignore_reloc,
00341 "R_SH_SWITCH32",
00342 FALSE,
00343 0,
00344 0,
00345 TRUE),
00346
00347
00348
00349
00350
00351 HOWTO (R_SH_USES,
00352 0,
00353 1,
00354 0,
00355 FALSE,
00356 0,
00357 complain_overflow_unsigned,
00358 sh_elf_ignore_reloc,
00359 "R_SH_USES",
00360 FALSE,
00361 0,
00362 0,
00363 TRUE),
00364
00365
00366
00367
00368
00369 HOWTO (R_SH_COUNT,
00370 0,
00371 1,
00372 0,
00373 FALSE,
00374 0,
00375 complain_overflow_unsigned,
00376 sh_elf_ignore_reloc,
00377 "R_SH_COUNT",
00378 FALSE,
00379 0,
00380 0,
00381 TRUE),
00382
00383
00384
00385
00386 HOWTO (R_SH_ALIGN,
00387 0,
00388 1,
00389 0,
00390 FALSE,
00391 0,
00392 complain_overflow_unsigned,
00393 sh_elf_ignore_reloc,
00394 "R_SH_ALIGN",
00395 FALSE,
00396 0,
00397 0,
00398 TRUE),
00399
00400
00401
00402
00403 HOWTO (R_SH_CODE,
00404 0,
00405 1,
00406 0,
00407 FALSE,
00408 0,
00409 complain_overflow_unsigned,
00410 sh_elf_ignore_reloc,
00411 "R_SH_CODE",
00412 FALSE,
00413 0,
00414 0,
00415 TRUE),
00416
00417
00418
00419 HOWTO (R_SH_DATA,
00420 0,
00421 1,
00422 0,
00423 FALSE,
00424 0,
00425 complain_overflow_unsigned,
00426 sh_elf_ignore_reloc,
00427 "R_SH_DATA",
00428 FALSE,
00429 0,
00430 0,
00431 TRUE),
00432
00433
00434
00435
00436 HOWTO (R_SH_LABEL,
00437 0,
00438 1,
00439 0,
00440 FALSE,
00441 0,
00442 complain_overflow_unsigned,
00443 sh_elf_ignore_reloc,
00444 "R_SH_LABEL",
00445 FALSE,
00446 0,
00447 0,
00448 TRUE),
00449
00450
00451 HOWTO (R_SH_DIR16,
00452 0,
00453 1,
00454 16,
00455 FALSE,
00456 0,
00457 complain_overflow_dont,
00458 bfd_elf_generic_reloc,
00459 "R_SH_DIR16",
00460 FALSE,
00461 0,
00462 0xffff,
00463 FALSE),
00464
00465 HOWTO (R_SH_DIR8,
00466 0,
00467 0,
00468 8,
00469 FALSE,
00470 0,
00471 complain_overflow_dont,
00472 bfd_elf_generic_reloc,
00473 "R_SH_DIR8",
00474 FALSE,
00475 0,
00476 0xff,
00477 FALSE),
00478
00479 HOWTO (R_SH_DIR8UL,
00480 2,
00481 0,
00482 8,
00483 FALSE,
00484 0,
00485 complain_overflow_unsigned,
00486 bfd_elf_generic_reloc,
00487 "R_SH_DIR8UL",
00488 FALSE,
00489 0,
00490 0xff,
00491 FALSE),
00492
00493 HOWTO (R_SH_DIR8UW,
00494 1,
00495 0,
00496 8,
00497 FALSE,
00498 0,
00499 complain_overflow_unsigned,
00500 bfd_elf_generic_reloc,
00501 "R_SH_DIR8UW",
00502 FALSE,
00503 0,
00504 0xff,
00505 FALSE),
00506
00507 HOWTO (R_SH_DIR8U,
00508 0,
00509 0,
00510 8,
00511 FALSE,
00512 0,
00513 complain_overflow_unsigned,
00514 bfd_elf_generic_reloc,
00515 "R_SH_DIR8U",
00516 FALSE,
00517 0,
00518 0xff,
00519 FALSE),
00520
00521 HOWTO (R_SH_DIR8SW,
00522 1,
00523 0,
00524 8,
00525 FALSE,
00526 0,
00527 complain_overflow_signed,
00528 bfd_elf_generic_reloc,
00529 "R_SH_DIR8SW",
00530 FALSE,
00531 0,
00532 0xff,
00533 FALSE),
00534
00535 HOWTO (R_SH_DIR8S,
00536 0,
00537 0,
00538 8,
00539 FALSE,
00540 0,
00541 complain_overflow_signed,
00542 bfd_elf_generic_reloc,
00543 "R_SH_DIR8S",
00544 FALSE,
00545 0,
00546 0xff,
00547 FALSE),
00548
00549 HOWTO (R_SH_DIR4UL,
00550 2,
00551 0,
00552 4,
00553 FALSE,
00554 0,
00555 complain_overflow_unsigned,
00556 bfd_elf_generic_reloc,
00557 "R_SH_DIR4UL",
00558 FALSE,
00559 0,
00560 0x0f,
00561 FALSE),
00562
00563 HOWTO (R_SH_DIR4UW,
00564 1,
00565 0,
00566 4,
00567 FALSE,
00568 0,
00569 complain_overflow_unsigned,
00570 bfd_elf_generic_reloc,
00571 "R_SH_DIR4UW",
00572 FALSE,
00573 0,
00574 0x0f,
00575 FALSE),
00576
00577 HOWTO (R_SH_DIR4U,
00578 0,
00579 0,
00580 4,
00581 FALSE,
00582 0,
00583 complain_overflow_unsigned,
00584 bfd_elf_generic_reloc,
00585 "R_SH_DIR4U",
00586 FALSE,
00587 0,
00588 0x0f,
00589 FALSE),
00590
00591 HOWTO (R_SH_PSHA,
00592 0,
00593 1,
00594 7,
00595 FALSE,
00596 4,
00597 complain_overflow_signed,
00598 bfd_elf_generic_reloc,
00599 "R_SH_PSHA",
00600 FALSE,
00601 0,
00602 0x0f,
00603 FALSE),
00604
00605 HOWTO (R_SH_PSHL,
00606 0,
00607 1,
00608 7,
00609 FALSE,
00610 4,
00611 complain_overflow_signed,
00612 bfd_elf_generic_reloc,
00613 "R_SH_PSHL",
00614 FALSE,
00615 0,
00616 0x0f,
00617 FALSE),
00618
00619 #ifdef INCLUDE_SHMEDIA
00620
00621 HOWTO (R_SH_DIR5U,
00622 0,
00623 2,
00624 5,
00625 FALSE,
00626 10,
00627 complain_overflow_unsigned,
00628 bfd_elf_generic_reloc,
00629 "R_SH_DIR5U",
00630 FALSE,
00631 0,
00632 0xfc00,
00633 FALSE),
00634
00635
00636 HOWTO (R_SH_DIR6U,
00637 0,
00638 2,
00639 6,
00640 FALSE,
00641 10,
00642 complain_overflow_unsigned,
00643 bfd_elf_generic_reloc,
00644 "R_SH_DIR6U",
00645 FALSE,
00646 0,
00647 0xfc00,
00648 FALSE),
00649
00650
00651 HOWTO (R_SH_DIR6S,
00652 0,
00653 2,
00654 6,
00655 FALSE,
00656 10,
00657 complain_overflow_signed,
00658 bfd_elf_generic_reloc,
00659 "R_SH_DIR6S",
00660 FALSE,
00661 0,
00662 0xfc00,
00663 FALSE),
00664
00665
00666 HOWTO (R_SH_DIR10S,
00667 0,
00668 2,
00669 10,
00670 FALSE,
00671 10,
00672 complain_overflow_signed,
00673 bfd_elf_generic_reloc,
00674 "R_SH_DIR10S",
00675 FALSE,
00676 0,
00677 0xffc00,
00678 FALSE),
00679
00680
00681 HOWTO (R_SH_DIR10SW,
00682 1,
00683 2,
00684 11,
00685 FALSE,
00686 10,
00687 complain_overflow_signed,
00688 bfd_elf_generic_reloc,
00689 "R_SH_DIR10SW",
00690 FALSE,
00691 0,
00692 0xffc00,
00693 FALSE),
00694
00695
00696 HOWTO (R_SH_DIR10SL,
00697 2,
00698 2,
00699 12,
00700 FALSE,
00701 10,
00702 complain_overflow_signed,
00703 bfd_elf_generic_reloc,
00704 "R_SH_DIR10SL",
00705 FALSE,
00706 0,
00707 0xffc00,
00708 FALSE),
00709
00710
00711 HOWTO (R_SH_DIR10SQ,
00712 3,
00713 2,
00714 13,
00715 FALSE,
00716 10,
00717 complain_overflow_signed,
00718 bfd_elf_generic_reloc,
00719 "R_SH_DIR10SQ",
00720 FALSE,
00721 0,
00722 0xffc00,
00723 FALSE),
00724
00725 #else
00726 EMPTY_HOWTO (45),
00727 EMPTY_HOWTO (46),
00728 EMPTY_HOWTO (47),
00729 EMPTY_HOWTO (48),
00730 EMPTY_HOWTO (49),
00731 EMPTY_HOWTO (50),
00732 EMPTY_HOWTO (51),
00733 #endif
00734
00735 EMPTY_HOWTO (52),
00736
00737 HOWTO (R_SH_DIR16S,
00738 0,
00739 1,
00740 16,
00741 FALSE,
00742 0,
00743 complain_overflow_signed,
00744 bfd_elf_generic_reloc,
00745 "R_SH_DIR16S",
00746 FALSE,
00747 0,
00748 0xffff,
00749 FALSE),
00750
00751 EMPTY_HOWTO (54),
00752 EMPTY_HOWTO (55),
00753 EMPTY_HOWTO (56),
00754 EMPTY_HOWTO (57),
00755 EMPTY_HOWTO (58),
00756 EMPTY_HOWTO (59),
00757 EMPTY_HOWTO (60),
00758 EMPTY_HOWTO (61),
00759 EMPTY_HOWTO (62),
00760 EMPTY_HOWTO (63),
00761 EMPTY_HOWTO (64),
00762 EMPTY_HOWTO (65),
00763 EMPTY_HOWTO (66),
00764 EMPTY_HOWTO (67),
00765 EMPTY_HOWTO (68),
00766 EMPTY_HOWTO (69),
00767 EMPTY_HOWTO (70),
00768 EMPTY_HOWTO (71),
00769 EMPTY_HOWTO (72),
00770 EMPTY_HOWTO (73),
00771 EMPTY_HOWTO (74),
00772 EMPTY_HOWTO (75),
00773 EMPTY_HOWTO (76),
00774 EMPTY_HOWTO (77),
00775 EMPTY_HOWTO (78),
00776 EMPTY_HOWTO (79),
00777 EMPTY_HOWTO (80),
00778 EMPTY_HOWTO (81),
00779 EMPTY_HOWTO (82),
00780 EMPTY_HOWTO (83),
00781 EMPTY_HOWTO (84),
00782 EMPTY_HOWTO (85),
00783 EMPTY_HOWTO (86),
00784 EMPTY_HOWTO (87),
00785 EMPTY_HOWTO (88),
00786 EMPTY_HOWTO (89),
00787 EMPTY_HOWTO (90),
00788 EMPTY_HOWTO (91),
00789 EMPTY_HOWTO (92),
00790 EMPTY_HOWTO (93),
00791 EMPTY_HOWTO (94),
00792 EMPTY_HOWTO (95),
00793 EMPTY_HOWTO (96),
00794 EMPTY_HOWTO (97),
00795 EMPTY_HOWTO (98),
00796 EMPTY_HOWTO (99),
00797 EMPTY_HOWTO (100),
00798 EMPTY_HOWTO (101),
00799 EMPTY_HOWTO (102),
00800 EMPTY_HOWTO (103),
00801 EMPTY_HOWTO (104),
00802 EMPTY_HOWTO (105),
00803 EMPTY_HOWTO (106),
00804 EMPTY_HOWTO (107),
00805 EMPTY_HOWTO (108),
00806 EMPTY_HOWTO (109),
00807 EMPTY_HOWTO (110),
00808 EMPTY_HOWTO (111),
00809 EMPTY_HOWTO (112),
00810 EMPTY_HOWTO (113),
00811 EMPTY_HOWTO (114),
00812 EMPTY_HOWTO (115),
00813 EMPTY_HOWTO (116),
00814 EMPTY_HOWTO (117),
00815 EMPTY_HOWTO (118),
00816 EMPTY_HOWTO (119),
00817 EMPTY_HOWTO (120),
00818 EMPTY_HOWTO (121),
00819 EMPTY_HOWTO (122),
00820 EMPTY_HOWTO (123),
00821 EMPTY_HOWTO (124),
00822 EMPTY_HOWTO (125),
00823 EMPTY_HOWTO (126),
00824 EMPTY_HOWTO (127),
00825 EMPTY_HOWTO (128),
00826 EMPTY_HOWTO (129),
00827 EMPTY_HOWTO (130),
00828 EMPTY_HOWTO (131),
00829 EMPTY_HOWTO (132),
00830 EMPTY_HOWTO (133),
00831 EMPTY_HOWTO (134),
00832 EMPTY_HOWTO (135),
00833 EMPTY_HOWTO (136),
00834 EMPTY_HOWTO (137),
00835 EMPTY_HOWTO (138),
00836 EMPTY_HOWTO (139),
00837 EMPTY_HOWTO (140),
00838 EMPTY_HOWTO (141),
00839 EMPTY_HOWTO (142),
00840 EMPTY_HOWTO (143),
00841
00842 HOWTO (R_SH_TLS_GD_32,
00843 0,
00844 2,
00845 32,
00846 FALSE,
00847 0,
00848 complain_overflow_bitfield,
00849 bfd_elf_generic_reloc,
00850 "R_SH_TLS_GD_32",
00851 TRUE,
00852 0xffffffff,
00853 0xffffffff,
00854 FALSE),
00855
00856 HOWTO (R_SH_TLS_LD_32,
00857 0,
00858 2,
00859 32,
00860 FALSE,
00861 0,
00862 complain_overflow_bitfield,
00863 bfd_elf_generic_reloc,
00864 "R_SH_TLS_LD_32",
00865 TRUE,
00866 0xffffffff,
00867 0xffffffff,
00868 FALSE),
00869
00870 HOWTO (R_SH_TLS_LDO_32,
00871 0,
00872 2,
00873 32,
00874 FALSE,
00875 0,
00876 complain_overflow_bitfield,
00877 bfd_elf_generic_reloc,
00878 "R_SH_TLS_LDO_32",
00879 TRUE,
00880 0xffffffff,
00881 0xffffffff,
00882 FALSE),
00883
00884 HOWTO (R_SH_TLS_IE_32,
00885 0,
00886 2,
00887 32,
00888 FALSE,
00889 0,
00890 complain_overflow_bitfield,
00891 bfd_elf_generic_reloc,
00892 "R_SH_TLS_IE_32",
00893 TRUE,
00894 0xffffffff,
00895 0xffffffff,
00896 FALSE),
00897
00898 HOWTO (R_SH_TLS_LE_32,
00899 0,
00900 2,
00901 32,
00902 FALSE,
00903 0,
00904 complain_overflow_bitfield,
00905 bfd_elf_generic_reloc,
00906 "R_SH_TLS_LE_32",
00907 TRUE,
00908 0xffffffff,
00909 0xffffffff,
00910 FALSE),
00911
00912 HOWTO (R_SH_TLS_DTPMOD32,
00913 0,
00914 2,
00915 32,
00916 FALSE,
00917 0,
00918 complain_overflow_bitfield,
00919 bfd_elf_generic_reloc,
00920 "R_SH_TLS_DTPMOD32",
00921 TRUE,
00922 0xffffffff,
00923 0xffffffff,
00924 FALSE),
00925
00926 HOWTO (R_SH_TLS_DTPOFF32,
00927 0,
00928 2,
00929 32,
00930 FALSE,
00931 0,
00932 complain_overflow_bitfield,
00933 bfd_elf_generic_reloc,
00934 "R_SH_TLS_DTPOFF32",
00935 TRUE,
00936 0xffffffff,
00937 0xffffffff,
00938 FALSE),
00939
00940 HOWTO (R_SH_TLS_TPOFF32,
00941 0,
00942 2,
00943 32,
00944 FALSE,
00945 0,
00946 complain_overflow_bitfield,
00947 bfd_elf_generic_reloc,
00948 "R_SH_TLS_TPOFF32",
00949 TRUE,
00950 0xffffffff,
00951 0xffffffff,
00952 FALSE),
00953
00954 EMPTY_HOWTO (152),
00955 EMPTY_HOWTO (153),
00956 EMPTY_HOWTO (154),
00957 EMPTY_HOWTO (155),
00958 EMPTY_HOWTO (156),
00959 EMPTY_HOWTO (157),
00960 EMPTY_HOWTO (158),
00961 EMPTY_HOWTO (159),
00962
00963 HOWTO (R_SH_GOT32,
00964 0,
00965 2,
00966 32,
00967 FALSE,
00968 0,
00969 complain_overflow_bitfield,
00970 bfd_elf_generic_reloc,
00971 "R_SH_GOT32",
00972 TRUE,
00973 0xffffffff,
00974 0xffffffff,
00975 FALSE),
00976
00977 HOWTO (R_SH_PLT32,
00978 0,
00979 2,
00980 32,
00981 TRUE,
00982 0,
00983 complain_overflow_bitfield,
00984 bfd_elf_generic_reloc,
00985 "R_SH_PLT32",
00986 TRUE,
00987 0xffffffff,
00988 0xffffffff,
00989 TRUE),
00990
00991 HOWTO (R_SH_COPY,
00992 0,
00993 2,
00994 32,
00995 FALSE,
00996 0,
00997 complain_overflow_bitfield,
00998 bfd_elf_generic_reloc,
00999 "R_SH_COPY",
01000 TRUE,
01001 0xffffffff,
01002 0xffffffff,
01003 FALSE),
01004
01005 HOWTO (R_SH_GLOB_DAT,
01006 0,
01007 2,
01008 32,
01009 FALSE,
01010 0,
01011 complain_overflow_bitfield,
01012 bfd_elf_generic_reloc,
01013 "R_SH_GLOB_DAT",
01014 TRUE,
01015 0xffffffff,
01016 0xffffffff,
01017 FALSE),
01018
01019 HOWTO (R_SH_JMP_SLOT,
01020 0,
01021 2,
01022 32,
01023 FALSE,
01024 0,
01025 complain_overflow_bitfield,
01026 bfd_elf_generic_reloc,
01027 "R_SH_JMP_SLOT",
01028 TRUE,
01029 0xffffffff,
01030 0xffffffff,
01031 FALSE),
01032
01033 HOWTO (R_SH_RELATIVE,
01034 0,
01035 2,
01036 32,
01037 FALSE,
01038 0,
01039 complain_overflow_bitfield,
01040 bfd_elf_generic_reloc,
01041 "R_SH_RELATIVE",
01042 TRUE,
01043 0xffffffff,
01044 0xffffffff,
01045 FALSE),
01046
01047 HOWTO (R_SH_GOTOFF,
01048 0,
01049 2,
01050 32,
01051 FALSE,
01052 0,
01053 complain_overflow_bitfield,
01054 bfd_elf_generic_reloc,
01055 "R_SH_GOTOFF",
01056 TRUE,
01057 0xffffffff,
01058 0xffffffff,
01059 FALSE),
01060
01061 HOWTO (R_SH_GOTPC,
01062 0,
01063 2,
01064 32,
01065 TRUE,
01066 0,
01067 complain_overflow_bitfield,
01068 bfd_elf_generic_reloc,
01069 "R_SH_GOTPC",
01070 TRUE,
01071 0xffffffff,
01072 0xffffffff,
01073 TRUE),
01074
01075 HOWTO (R_SH_GOTPLT32,
01076 0,
01077 2,
01078 32,
01079 FALSE,
01080 0,
01081 complain_overflow_bitfield,
01082 bfd_elf_generic_reloc,
01083 "R_SH_GOTPLT32",
01084 FALSE,
01085 0xffffffff,
01086 0xffffffff,
01087 FALSE),
01088
01089 #ifdef INCLUDE_SHMEDIA
01090
01091 HOWTO (R_SH_GOT_LOW16,
01092 0,
01093 2,
01094 64,
01095 FALSE,
01096 10,
01097 complain_overflow_dont,
01098 bfd_elf_generic_reloc,
01099 "R_SH_GOT_LOW16",
01100 FALSE,
01101 0,
01102 0x3fffc00,
01103 FALSE),
01104
01105
01106 HOWTO (R_SH_GOT_MEDLOW16,
01107 16,
01108 2,
01109 64,
01110 FALSE,
01111 10,
01112 complain_overflow_dont,
01113 bfd_elf_generic_reloc,
01114 "R_SH_GOT_MEDLOW16",
01115 FALSE,
01116 0,
01117 0x3fffc00,
01118 FALSE),
01119
01120
01121 HOWTO (R_SH_GOT_MEDHI16,
01122 32,
01123 2,
01124 64,
01125 FALSE,
01126 10,
01127 complain_overflow_dont,
01128 bfd_elf_generic_reloc,
01129 "R_SH_GOT_MEDHI16",
01130 FALSE,
01131 0,
01132 0x3fffc00,
01133 FALSE),
01134
01135
01136 HOWTO (R_SH_GOT_HI16,
01137 48,
01138 2,
01139 64,
01140 FALSE,
01141 10,
01142 complain_overflow_dont,
01143 bfd_elf_generic_reloc,
01144 "R_SH_GOT_HI16",
01145 FALSE,
01146 0,
01147 0x3fffc00,
01148 FALSE),
01149
01150
01151 HOWTO (R_SH_GOTPLT_LOW16,
01152 0,
01153 2,
01154 64,
01155 FALSE,
01156 10,
01157 complain_overflow_dont,
01158 bfd_elf_generic_reloc,
01159 "R_SH_GOTPLT_LOW16",
01160 FALSE,
01161 0,
01162 0x3fffc00,
01163 FALSE),
01164
01165
01166 HOWTO (R_SH_GOTPLT_MEDLOW16,
01167 16,
01168 2,
01169 64,
01170 FALSE,
01171 10,
01172 complain_overflow_dont,
01173 bfd_elf_generic_reloc,
01174 "R_SH_GOTPLT_MEDLOW16",
01175 FALSE,
01176 0,
01177 0x3fffc00,
01178 FALSE),
01179
01180
01181 HOWTO (R_SH_GOTPLT_MEDHI16,
01182 32,
01183 2,
01184 64,
01185 FALSE,
01186 10,
01187 complain_overflow_dont,
01188 bfd_elf_generic_reloc,
01189 "R_SH_GOTPLT_MEDHI16",
01190 FALSE,
01191 0,
01192 0x3fffc00,
01193 FALSE),
01194
01195
01196 HOWTO (R_SH_GOTPLT_HI16,
01197 48,
01198 2,
01199 64,
01200 FALSE,
01201 10,
01202 complain_overflow_dont,
01203 bfd_elf_generic_reloc,
01204 "R_SH_GOTPLT_HI16",
01205 FALSE,
01206 0,
01207 0x3fffc00,
01208 FALSE),
01209
01210
01211 HOWTO (R_SH_PLT_LOW16,
01212 0,
01213 2,
01214 64,
01215 TRUE,
01216 10,
01217 complain_overflow_dont,
01218 bfd_elf_generic_reloc,
01219 "R_SH_PLT_LOW16",
01220 FALSE,
01221 0,
01222 0x3fffc00,
01223 TRUE),
01224
01225
01226 HOWTO (R_SH_PLT_MEDLOW16,
01227 16,
01228 2,
01229 64,
01230 TRUE,
01231 10,
01232 complain_overflow_dont,
01233 bfd_elf_generic_reloc,
01234 "R_SH_PLT_MEDLOW16",
01235 FALSE,
01236 0,
01237 0x3fffc00,
01238 TRUE),
01239
01240
01241 HOWTO (R_SH_PLT_MEDHI16,
01242 32,
01243 2,
01244 64,
01245 TRUE,
01246 10,
01247 complain_overflow_dont,
01248 bfd_elf_generic_reloc,
01249 "R_SH_PLT_MEDHI16",
01250 FALSE,
01251 0,
01252 0x3fffc00,
01253 TRUE),
01254
01255
01256 HOWTO (R_SH_PLT_HI16,
01257 48,
01258 2,
01259 64,
01260 TRUE,
01261 10,
01262 complain_overflow_dont,
01263 bfd_elf_generic_reloc,
01264 "R_SH_PLT_HI16",
01265 FALSE,
01266 0,
01267 0x3fffc00,
01268 TRUE),
01269
01270
01271 HOWTO (R_SH_GOTOFF_LOW16,
01272 0,
01273 2,
01274 64,
01275 FALSE,
01276 10,
01277 complain_overflow_dont,
01278 bfd_elf_generic_reloc,
01279 "R_SH_GOTOFF_LOW16",
01280 FALSE,
01281 0,
01282 0x3fffc00,
01283 FALSE),
01284
01285
01286 HOWTO (R_SH_GOTOFF_MEDLOW16,
01287 16,
01288 2,
01289 64,
01290 FALSE,
01291 10,
01292 complain_overflow_dont,
01293 bfd_elf_generic_reloc,
01294 "R_SH_GOTOFF_MEDLOW16",
01295 FALSE,
01296 0,
01297 0x3fffc00,
01298 FALSE),
01299
01300
01301 HOWTO (R_SH_GOTOFF_MEDHI16,
01302 32,
01303 2,
01304 64,
01305 FALSE,
01306 10,
01307 complain_overflow_dont,
01308 bfd_elf_generic_reloc,
01309 "R_SH_GOTOFF_MEDHI16",
01310 FALSE,
01311 0,
01312 0x3fffc00,
01313 FALSE),
01314
01315
01316 HOWTO (R_SH_GOTOFF_HI16,
01317 48,
01318 2,
01319 64,
01320 FALSE,
01321 10,
01322 complain_overflow_dont,
01323 bfd_elf_generic_reloc,
01324 "R_SH_GOTOFF_HI16",
01325 FALSE,
01326 0,
01327 0x3fffc00,
01328 FALSE),
01329
01330
01331 HOWTO (R_SH_GOTPC_LOW16,
01332 0,
01333 2,
01334 64,
01335 TRUE,
01336 10,
01337 complain_overflow_dont,
01338 bfd_elf_generic_reloc,
01339 "R_SH_GOTPC_LOW16",
01340 FALSE,
01341 0,
01342 0x3fffc00,
01343 TRUE),
01344
01345
01346 HOWTO (R_SH_GOTPC_MEDLOW16,
01347 16,
01348 2,
01349 64,
01350 TRUE,
01351 10,
01352 complain_overflow_dont,
01353 bfd_elf_generic_reloc,
01354 "R_SH_GOTPC_MEDLOW16",
01355 FALSE,
01356 0,
01357 0x3fffc00,
01358 TRUE),
01359
01360
01361 HOWTO (R_SH_GOTPC_MEDHI16,
01362 32,
01363 2,
01364 64,
01365 TRUE,
01366 10,
01367 complain_overflow_dont,
01368 bfd_elf_generic_reloc,
01369 "R_SH_GOTPC_MEDHI16",
01370 FALSE,
01371 0,
01372 0x3fffc00,
01373 TRUE),
01374
01375
01376 HOWTO (R_SH_GOTPC_HI16,
01377 48,
01378 2,
01379 64,
01380 TRUE,
01381 10,
01382 complain_overflow_dont,
01383 bfd_elf_generic_reloc,
01384 "R_SH_GOTPC_HI16",
01385 FALSE,
01386 0,
01387 0x3fffc00,
01388 TRUE),
01389
01390
01391 HOWTO (R_SH_GOT10BY4,
01392 2,
01393 2,
01394 12,
01395 FALSE,
01396 10,
01397 complain_overflow_signed,
01398 bfd_elf_generic_reloc,
01399 "R_SH_GOT10BY4",
01400 FALSE,
01401 0,
01402 0xffc00,
01403 FALSE),
01404
01405
01406 HOWTO (R_SH_GOTPLT10BY4,
01407 2,
01408 2,
01409 12,
01410 FALSE,
01411 10,
01412 complain_overflow_signed,
01413 bfd_elf_generic_reloc,
01414 "R_SH_GOTPLT10BY4",
01415 FALSE,
01416 0,
01417 0xffc00,
01418 FALSE),
01419
01420
01421 HOWTO (R_SH_GOT10BY8,
01422 3,
01423 2,
01424 13,
01425 FALSE,
01426 10,
01427 complain_overflow_signed,
01428 bfd_elf_generic_reloc,
01429 "R_SH_GOT10BY8",
01430 FALSE,
01431 0,
01432 0xffc00,
01433 FALSE),
01434
01435
01436 HOWTO (R_SH_GOTPLT10BY8,
01437 3,
01438 2,
01439 13,
01440 FALSE,
01441 10,
01442 complain_overflow_signed,
01443 bfd_elf_generic_reloc,
01444 "R_SH_GOTPLT10BY8",
01445 FALSE,
01446 0,
01447 0xffc00,
01448 FALSE),
01449
01450 HOWTO (R_SH_COPY64,
01451 0,
01452 4,
01453 64,
01454 FALSE,
01455 0,
01456 complain_overflow_dont,
01457 bfd_elf_generic_reloc,
01458 "R_SH_COPY64",
01459 FALSE,
01460 0,
01461 ((bfd_vma) 0) - 1,
01462 FALSE),
01463
01464 HOWTO (R_SH_GLOB_DAT64,
01465 0,
01466 4,
01467 64,
01468 FALSE,
01469 0,
01470 complain_overflow_dont,
01471 bfd_elf_generic_reloc,
01472 "R_SH_GLOB_DAT64",
01473 FALSE,
01474 0,
01475 ((bfd_vma) 0) - 1,
01476 FALSE),
01477
01478 HOWTO (R_SH_JMP_SLOT64,
01479 0,
01480 4,
01481 64,
01482 FALSE,
01483 0,
01484 complain_overflow_dont,
01485 bfd_elf_generic_reloc,
01486 "R_SH_JMP_SLOT64",
01487 FALSE,
01488 0,
01489 ((bfd_vma) 0) - 1,
01490 FALSE),
01491
01492 HOWTO (R_SH_RELATIVE64,
01493 0,
01494 4,
01495 64,
01496 FALSE,
01497 0,
01498 complain_overflow_dont,
01499 bfd_elf_generic_reloc,
01500 "R_SH_RELATIVE64",
01501 FALSE,
01502 0,
01503 ((bfd_vma) 0) - 1,
01504 FALSE),
01505
01506 EMPTY_HOWTO (197),
01507 EMPTY_HOWTO (198),
01508 EMPTY_HOWTO (199),
01509 EMPTY_HOWTO (200),
01510 EMPTY_HOWTO (201),
01511 EMPTY_HOWTO (202),
01512 EMPTY_HOWTO (203),
01513 EMPTY_HOWTO (204),
01514 EMPTY_HOWTO (205),
01515 EMPTY_HOWTO (206),
01516 EMPTY_HOWTO (207),
01517 EMPTY_HOWTO (208),
01518 EMPTY_HOWTO (209),
01519 EMPTY_HOWTO (210),
01520 EMPTY_HOWTO (211),
01521 EMPTY_HOWTO (212),
01522 EMPTY_HOWTO (213),
01523 EMPTY_HOWTO (214),
01524 EMPTY_HOWTO (215),
01525 EMPTY_HOWTO (216),
01526 EMPTY_HOWTO (217),
01527 EMPTY_HOWTO (218),
01528 EMPTY_HOWTO (219),
01529 EMPTY_HOWTO (220),
01530 EMPTY_HOWTO (221),
01531 EMPTY_HOWTO (222),
01532 EMPTY_HOWTO (223),
01533 EMPTY_HOWTO (224),
01534 EMPTY_HOWTO (225),
01535 EMPTY_HOWTO (226),
01536 EMPTY_HOWTO (227),
01537 EMPTY_HOWTO (228),
01538 EMPTY_HOWTO (229),
01539 EMPTY_HOWTO (230),
01540 EMPTY_HOWTO (231),
01541 EMPTY_HOWTO (232),
01542 EMPTY_HOWTO (233),
01543 EMPTY_HOWTO (234),
01544 EMPTY_HOWTO (235),
01545 EMPTY_HOWTO (236),
01546 EMPTY_HOWTO (237),
01547 EMPTY_HOWTO (238),
01548 EMPTY_HOWTO (239),
01549 EMPTY_HOWTO (240),
01550 EMPTY_HOWTO (241),
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561 HOWTO (R_SH_SHMEDIA_CODE,
01562 0,
01563 1,
01564 0,
01565 FALSE,
01566 0,
01567 complain_overflow_unsigned,
01568 sh_elf_ignore_reloc,
01569 "R_SH_SHMEDIA_CODE",
01570 FALSE,
01571 0,
01572 0,
01573 FALSE),
01574
01575
01576
01577
01578 HOWTO (R_SH_PT_16,
01579 2,
01580 2,
01581 18,
01582 TRUE,
01583 10,
01584 complain_overflow_signed,
01585 bfd_elf_generic_reloc,
01586 "R_SH_PT_16",
01587 FALSE,
01588 0,
01589 0x3fffc00,
01590 TRUE),
01591
01592
01593 HOWTO (R_SH_IMMS16,
01594 0,
01595 2,
01596 16,
01597 FALSE,
01598 10,
01599 complain_overflow_signed,
01600 bfd_elf_generic_reloc,
01601 "R_SH_IMMS16",
01602 FALSE,
01603 0,
01604 0x3fffc00,
01605 FALSE),
01606
01607
01608 HOWTO (R_SH_IMMU16,
01609 0,
01610 2,
01611 16,
01612 FALSE,
01613 10,
01614 complain_overflow_unsigned,
01615 bfd_elf_generic_reloc,
01616 "R_SH_IMMU16",
01617 FALSE,
01618 0,
01619 0x3fffc00,
01620 FALSE),
01621
01622
01623 HOWTO (R_SH_IMM_LOW16,
01624 0,
01625 2,
01626 64,
01627 FALSE,
01628 10,
01629 complain_overflow_dont,
01630 bfd_elf_generic_reloc,
01631 "R_SH_IMM_LOW16",
01632 FALSE,
01633 0,
01634 0x3fffc00,
01635 FALSE),
01636
01637
01638 HOWTO (R_SH_IMM_LOW16_PCREL,
01639 0,
01640 2,
01641 64,
01642 TRUE,
01643 10,
01644 complain_overflow_dont,
01645 bfd_elf_generic_reloc,
01646 "R_SH_IMM_LOW16_PCREL",
01647 FALSE,
01648 0,
01649 0x3fffc00,
01650 TRUE),
01651
01652
01653 HOWTO (R_SH_IMM_MEDLOW16,
01654 16,
01655 2,
01656 64,
01657 FALSE,
01658 10,
01659 complain_overflow_dont,
01660 bfd_elf_generic_reloc,
01661 "R_SH_IMM_MEDLOW16",
01662 FALSE,
01663 0,
01664 0x3fffc00,
01665 FALSE),
01666
01667
01668 HOWTO (R_SH_IMM_MEDLOW16_PCREL,
01669 16,
01670 2,
01671 64,
01672 TRUE,
01673 10,
01674 complain_overflow_dont,
01675 bfd_elf_generic_reloc,
01676 "R_SH_IMM_MEDLOW16_PCREL",
01677 FALSE,
01678 0,
01679 0x3fffc00,
01680 TRUE),
01681
01682
01683 HOWTO (R_SH_IMM_MEDHI16,
01684 32,
01685 2,
01686 64,
01687 FALSE,
01688 10,
01689 complain_overflow_dont,
01690 bfd_elf_generic_reloc,
01691 "R_SH_IMM_MEDHI16",
01692 FALSE,
01693 0,
01694 0x3fffc00,
01695 FALSE),
01696
01697
01698 HOWTO (R_SH_IMM_MEDHI16_PCREL,
01699 32,
01700 2,
01701 64,
01702 TRUE,
01703 10,
01704 complain_overflow_dont,
01705 bfd_elf_generic_reloc,
01706 "R_SH_IMM_MEDHI16_PCREL",
01707 FALSE,
01708 0,
01709 0x3fffc00,
01710 TRUE),
01711
01712
01713 HOWTO (R_SH_IMM_HI16,
01714 48,
01715 2,
01716 64,
01717 FALSE,
01718 10,
01719 complain_overflow_dont,
01720 bfd_elf_generic_reloc,
01721 "R_SH_IMM_HI16",
01722 FALSE,
01723 0,
01724 0x3fffc00,
01725 FALSE),
01726
01727
01728 HOWTO (R_SH_IMM_HI16_PCREL,
01729 48,
01730 2,
01731 64,
01732 TRUE,
01733 10,
01734 complain_overflow_dont,
01735 bfd_elf_generic_reloc,
01736 "R_SH_IMM_HI16_PCREL",
01737 FALSE,
01738 0,
01739 0x3fffc00,
01740 TRUE),
01741
01742
01743 HOWTO (R_SH_64,
01744 0,
01745 4,
01746 64,
01747 FALSE,
01748 0,
01749 complain_overflow_dont,
01750 bfd_elf_generic_reloc,
01751 "R_SH_64",
01752 FALSE,
01753 0,
01754 ((bfd_vma) 0) - 1,
01755 FALSE),
01756
01757
01758 HOWTO (R_SH_64_PCREL,
01759 48,
01760 2,
01761 64,
01762 TRUE,
01763 10,
01764 complain_overflow_dont,
01765 bfd_elf_generic_reloc,
01766 "R_SH_64_PCREL",
01767 FALSE,
01768 0,
01769 ((bfd_vma) 0) - 1,
01770 TRUE),
01771
01772 #endif
01773 };
01774
01775 static bfd_reloc_status_type
01776 sh_elf_reloc_loop (int r_type ATTRIBUTE_UNUSED, bfd *input_bfd,
01777 asection *input_section, bfd_byte *contents,
01778 bfd_vma addr, asection *symbol_section,
01779 bfd_vma start, bfd_vma end)
01780 {
01781 static bfd_vma last_addr;
01782 static asection *last_symbol_section;
01783 bfd_byte *start_ptr, *ptr, *last_ptr;
01784 int diff, cum_diff;
01785 bfd_signed_vma x;
01786 int insn;
01787
01788
01789 if (addr > bfd_get_section_limit (input_bfd, input_section))
01790 return bfd_reloc_outofrange;
01791
01792
01793
01794 if (! last_addr)
01795 {
01796 last_addr = addr;
01797 last_symbol_section = symbol_section;
01798 return bfd_reloc_ok;
01799 }
01800 if (last_addr != addr)
01801 abort ();
01802 last_addr = 0;
01803
01804 if (! symbol_section || last_symbol_section != symbol_section || end < start)
01805 return bfd_reloc_outofrange;
01806
01807
01808 if (symbol_section != input_section)
01809 {
01810 if (elf_section_data (symbol_section)->this_hdr.contents != NULL)
01811 contents = elf_section_data (symbol_section)->this_hdr.contents;
01812 else
01813 {
01814 if (!bfd_malloc_and_get_section (input_bfd, symbol_section,
01815 &contents))
01816 {
01817 if (contents != NULL)
01818 free (contents);
01819 return bfd_reloc_outofrange;
01820 }
01821 }
01822 }
01823 #define IS_PPI(PTR) ((bfd_get_16 (input_bfd, (PTR)) & 0xfc00) == 0xf800)
01824 start_ptr = contents + start;
01825 for (cum_diff = -6, ptr = contents + end; cum_diff < 0 && ptr > start_ptr;)
01826 {
01827 for (last_ptr = ptr, ptr -= 4; ptr >= start_ptr && IS_PPI (ptr);)
01828 ptr -= 2;
01829 ptr += 2;
01830 diff = (last_ptr - ptr) >> 1;
01831 cum_diff += diff & 1;
01832 cum_diff += diff;
01833 }
01834
01835
01836
01837 if (cum_diff >= 0)
01838 {
01839 start -= 4;
01840 end = (ptr + cum_diff * 2) - contents;
01841 }
01842 else
01843 {
01844 bfd_vma start0 = start - 4;
01845
01846 while (start0 && IS_PPI (contents + start0))
01847 start0 -= 2;
01848 start0 = start - 2 - ((start - start0) & 2);
01849 start = start0 - cum_diff - 2;
01850 end = start0;
01851 }
01852
01853 if (contents != NULL
01854 && elf_section_data (symbol_section)->this_hdr.contents != contents)
01855 free (contents);
01856
01857 insn = bfd_get_16 (input_bfd, contents + addr);
01858
01859 x = (insn & 0x200 ? end : start) - addr;
01860 if (input_section != symbol_section)
01861 x += ((symbol_section->output_section->vma + symbol_section->output_offset)
01862 - (input_section->output_section->vma
01863 + input_section->output_offset));
01864 x >>= 1;
01865 if (x < -128 || x > 127)
01866 return bfd_reloc_overflow;
01867
01868 x = (insn & ~0xff) | (x & 0xff);
01869 bfd_put_16 (input_bfd, (bfd_vma) x, contents + addr);
01870
01871 return bfd_reloc_ok;
01872 }
01873
01874
01875
01876
01877 static bfd_reloc_status_type
01878 sh_elf_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol_in,
01879 void *data, asection *input_section, bfd *output_bfd,
01880 char **error_message ATTRIBUTE_UNUSED)
01881 {
01882 unsigned long insn;
01883 bfd_vma sym_value;
01884 enum elf_sh_reloc_type r_type;
01885 bfd_vma addr = reloc_entry->address;
01886 bfd_byte *hit_data = addr + (bfd_byte *) data;
01887
01888 r_type = (enum elf_sh_reloc_type) reloc_entry->howto->type;
01889
01890 if (output_bfd != NULL)
01891 {
01892
01893 reloc_entry->address += input_section->output_offset;
01894 return bfd_reloc_ok;
01895 }
01896
01897
01898
01899 if (r_type == R_SH_IND12W && (symbol_in->flags & BSF_LOCAL) != 0)
01900 return bfd_reloc_ok;
01901
01902 if (symbol_in != NULL
01903 && bfd_is_und_section (symbol_in->section))
01904 return bfd_reloc_undefined;
01905
01906 if (bfd_is_com_section (symbol_in->section))
01907 sym_value = 0;
01908 else
01909 sym_value = (symbol_in->value +
01910 symbol_in->section->output_section->vma +
01911 symbol_in->section->output_offset);
01912
01913 switch (r_type)
01914 {
01915 case R_SH_DIR32:
01916 insn = bfd_get_32 (abfd, hit_data);
01917 insn += sym_value + reloc_entry->addend;
01918 bfd_put_32 (abfd, (bfd_vma) insn, hit_data);
01919 break;
01920 case R_SH_IND12W:
01921 insn = bfd_get_16 (abfd, hit_data);
01922 sym_value += reloc_entry->addend;
01923 sym_value -= (input_section->output_section->vma
01924 + input_section->output_offset
01925 + addr
01926 + 4);
01927 sym_value += (insn & 0xfff) << 1;
01928 if (insn & 0x800)
01929 sym_value -= 0x1000;
01930 insn = (insn & 0xf000) | (sym_value & 0xfff);
01931 bfd_put_16 (abfd, (bfd_vma) insn, hit_data);
01932 if (sym_value < (bfd_vma) -0x1000 || sym_value >= 0x1000)
01933 return bfd_reloc_overflow;
01934 break;
01935 default:
01936 abort ();
01937 break;
01938 }
01939
01940 return bfd_reloc_ok;
01941 }
01942
01943
01944
01945
01946 static bfd_reloc_status_type
01947 sh_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
01948 asymbol *symbol ATTRIBUTE_UNUSED,
01949 void *data ATTRIBUTE_UNUSED, asection *input_section,
01950 bfd *output_bfd,
01951 char **error_message ATTRIBUTE_UNUSED)
01952 {
01953 if (output_bfd != NULL)
01954 reloc_entry->address += input_section->output_offset;
01955 return bfd_reloc_ok;
01956 }
01957
01958
01959
01960 struct elf_reloc_map
01961 {
01962 bfd_reloc_code_real_type bfd_reloc_val;
01963 unsigned char elf_reloc_val;
01964 };
01965
01966
01967
01968 static const struct elf_reloc_map sh_reloc_map[] =
01969 {
01970 { BFD_RELOC_NONE, R_SH_NONE },
01971 { BFD_RELOC_32, R_SH_DIR32 },
01972 { BFD_RELOC_16, R_SH_DIR16 },
01973 { BFD_RELOC_8, R_SH_DIR8 },
01974 { BFD_RELOC_CTOR, R_SH_DIR32 },
01975 { BFD_RELOC_32_PCREL, R_SH_REL32 },
01976 { BFD_RELOC_SH_PCDISP8BY2, R_SH_DIR8WPN },
01977 { BFD_RELOC_SH_PCDISP12BY2, R_SH_IND12W },
01978 { BFD_RELOC_SH_PCRELIMM8BY2, R_SH_DIR8WPZ },
01979 { BFD_RELOC_SH_PCRELIMM8BY4, R_SH_DIR8WPL },
01980 { BFD_RELOC_8_PCREL, R_SH_SWITCH8 },
01981 { BFD_RELOC_SH_SWITCH16, R_SH_SWITCH16 },
01982 { BFD_RELOC_SH_SWITCH32, R_SH_SWITCH32 },
01983 { BFD_RELOC_SH_USES, R_SH_USES },
01984 { BFD_RELOC_SH_COUNT, R_SH_COUNT },
01985 { BFD_RELOC_SH_ALIGN, R_SH_ALIGN },
01986 { BFD_RELOC_SH_CODE, R_SH_CODE },
01987 { BFD_RELOC_SH_DATA, R_SH_DATA },
01988 { BFD_RELOC_SH_LABEL, R_SH_LABEL },
01989 { BFD_RELOC_VTABLE_INHERIT, R_SH_GNU_VTINHERIT },
01990 { BFD_RELOC_VTABLE_ENTRY, R_SH_GNU_VTENTRY },
01991 { BFD_RELOC_SH_LOOP_START, R_SH_LOOP_START },
01992 { BFD_RELOC_SH_LOOP_END, R_SH_LOOP_END },
01993 { BFD_RELOC_SH_TLS_GD_32, R_SH_TLS_GD_32 },
01994 { BFD_RELOC_SH_TLS_LD_32, R_SH_TLS_LD_32 },
01995 { BFD_RELOC_SH_TLS_LDO_32, R_SH_TLS_LDO_32 },
01996 { BFD_RELOC_SH_TLS_IE_32, R_SH_TLS_IE_32 },
01997 { BFD_RELOC_SH_TLS_LE_32, R_SH_TLS_LE_32 },
01998 { BFD_RELOC_SH_TLS_DTPMOD32, R_SH_TLS_DTPMOD32 },
01999 { BFD_RELOC_SH_TLS_DTPOFF32, R_SH_TLS_DTPOFF32 },
02000 { BFD_RELOC_SH_TLS_TPOFF32, R_SH_TLS_TPOFF32 },
02001 { BFD_RELOC_32_GOT_PCREL, R_SH_GOT32 },
02002 { BFD_RELOC_32_PLT_PCREL, R_SH_PLT32 },
02003 { BFD_RELOC_SH_COPY, R_SH_COPY },
02004 { BFD_RELOC_SH_GLOB_DAT, R_SH_GLOB_DAT },
02005 { BFD_RELOC_SH_JMP_SLOT, R_SH_JMP_SLOT },
02006 { BFD_RELOC_SH_RELATIVE, R_SH_RELATIVE },
02007 { BFD_RELOC_32_GOTOFF, R_SH_GOTOFF },
02008 { BFD_RELOC_SH_GOTPC, R_SH_GOTPC },
02009 { BFD_RELOC_SH_GOTPLT32, R_SH_GOTPLT32 },
02010 #ifdef INCLUDE_SHMEDIA
02011 { BFD_RELOC_SH_GOT_LOW16, R_SH_GOT_LOW16 },
02012 { BFD_RELOC_SH_GOT_MEDLOW16, R_SH_GOT_MEDLOW16 },
02013 { BFD_RELOC_SH_GOT_MEDHI16, R_SH_GOT_MEDHI16 },
02014 { BFD_RELOC_SH_GOT_HI16, R_SH_GOT_HI16 },
02015 { BFD_RELOC_SH_GOTPLT_LOW16, R_SH_GOTPLT_LOW16 },
02016 { BFD_RELOC_SH_GOTPLT_MEDLOW16, R_SH_GOTPLT_MEDLOW16 },
02017 { BFD_RELOC_SH_GOTPLT_MEDHI16, R_SH_GOTPLT_MEDHI16 },
02018 { BFD_RELOC_SH_GOTPLT_HI16, R_SH_GOTPLT_HI16 },
02019 { BFD_RELOC_SH_PLT_LOW16, R_SH_PLT_LOW16 },
02020 { BFD_RELOC_SH_PLT_MEDLOW16, R_SH_PLT_MEDLOW16 },
02021 { BFD_RELOC_SH_PLT_MEDHI16, R_SH_PLT_MEDHI16 },
02022 { BFD_RELOC_SH_PLT_HI16, R_SH_PLT_HI16 },
02023 { BFD_RELOC_SH_GOTOFF_LOW16, R_SH_GOTOFF_LOW16 },
02024 { BFD_RELOC_SH_GOTOFF_MEDLOW16, R_SH_GOTOFF_MEDLOW16 },
02025 { BFD_RELOC_SH_GOTOFF_MEDHI16, R_SH_GOTOFF_MEDHI16 },
02026 { BFD_RELOC_SH_GOTOFF_HI16, R_SH_GOTOFF_HI16 },
02027 { BFD_RELOC_SH_GOTPC_LOW16, R_SH_GOTPC_LOW16 },
02028 { BFD_RELOC_SH_GOTPC_MEDLOW16, R_SH_GOTPC_MEDLOW16 },
02029 { BFD_RELOC_SH_GOTPC_MEDHI16, R_SH_GOTPC_MEDHI16 },
02030 { BFD_RELOC_SH_GOTPC_HI16, R_SH_GOTPC_HI16 },
02031 { BFD_RELOC_SH_COPY64, R_SH_COPY64 },
02032 { BFD_RELOC_SH_GLOB_DAT64, R_SH_GLOB_DAT64 },
02033 { BFD_RELOC_SH_JMP_SLOT64, R_SH_JMP_SLOT64 },
02034 { BFD_RELOC_SH_RELATIVE64, R_SH_RELATIVE64 },
02035 { BFD_RELOC_SH_GOT10BY4, R_SH_GOT10BY4 },
02036 { BFD_RELOC_SH_GOT10BY8, R_SH_GOT10BY8 },
02037 { BFD_RELOC_SH_GOTPLT10BY4, R_SH_GOTPLT10BY4 },
02038 { BFD_RELOC_SH_GOTPLT10BY8, R_SH_GOTPLT10BY8 },
02039 { BFD_RELOC_SH_PT_16, R_SH_PT_16 },
02040 { BFD_RELOC_SH_SHMEDIA_CODE, R_SH_SHMEDIA_CODE },
02041 { BFD_RELOC_SH_IMMU5, R_SH_DIR5U },
02042 { BFD_RELOC_SH_IMMS6, R_SH_DIR6S },
02043 { BFD_RELOC_SH_IMMU6, R_SH_DIR6U },
02044 { BFD_RELOC_SH_IMMS10, R_SH_DIR10S },
02045 { BFD_RELOC_SH_IMMS10BY2, R_SH_DIR10SW },
02046 { BFD_RELOC_SH_IMMS10BY4, R_SH_DIR10SL },
02047 { BFD_RELOC_SH_IMMS10BY8, R_SH_DIR10SQ },
02048 { BFD_RELOC_SH_IMMS16, R_SH_IMMS16 },
02049 { BFD_RELOC_SH_IMMU16, R_SH_IMMU16 },
02050 { BFD_RELOC_SH_IMM_LOW16, R_SH_IMM_LOW16 },
02051 { BFD_RELOC_SH_IMM_LOW16_PCREL, R_SH_IMM_LOW16_PCREL },
02052 { BFD_RELOC_SH_IMM_MEDLOW16, R_SH_IMM_MEDLOW16 },
02053 { BFD_RELOC_SH_IMM_MEDLOW16_PCREL, R_SH_IMM_MEDLOW16_PCREL },
02054 { BFD_RELOC_SH_IMM_MEDHI16, R_SH_IMM_MEDHI16 },
02055 { BFD_RELOC_SH_IMM_MEDHI16_PCREL, R_SH_IMM_MEDHI16_PCREL },
02056 { BFD_RELOC_SH_IMM_HI16, R_SH_IMM_HI16 },
02057 { BFD_RELOC_SH_IMM_HI16_PCREL, R_SH_IMM_HI16_PCREL },
02058 { BFD_RELOC_64, R_SH_64 },
02059 { BFD_RELOC_64_PCREL, R_SH_64_PCREL },
02060 #endif
02061 };
02062
02063
02064
02065
02066 static reloc_howto_type *
02067 sh_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
02068 bfd_reloc_code_real_type code)
02069 {
02070 unsigned int i;
02071
02072 for (i = 0; i < sizeof (sh_reloc_map) / sizeof (struct elf_reloc_map); i++)
02073 {
02074 if (sh_reloc_map[i].bfd_reloc_val == code)
02075 return &sh_elf_howto_table[(int) sh_reloc_map[i].elf_reloc_val];
02076 }
02077
02078 return NULL;
02079 }
02080
02081
02082
02083 static void
02084 sh_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
02085 Elf_Internal_Rela *dst)
02086 {
02087 unsigned int r;
02088
02089 r = ELF32_R_TYPE (dst->r_info);
02090
02091 BFD_ASSERT (r < (unsigned int) R_SH_max);
02092 BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC || r > R_SH_LAST_INVALID_RELOC);
02093 BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_2 || r > R_SH_LAST_INVALID_RELOC_2);
02094 BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_3 || r > R_SH_LAST_INVALID_RELOC_3);
02095 BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_4 || r > R_SH_LAST_INVALID_RELOC_4);
02096 BFD_ASSERT (r < R_SH_FIRST_INVALID_RELOC_5 || r > R_SH_LAST_INVALID_RELOC_5);
02097
02098 cache_ptr->howto = &sh_elf_howto_table[r];
02099 }
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111 static bfd_boolean
02112 sh_elf_relax_section (bfd *abfd, asection *sec,
02113 struct bfd_link_info *link_info, bfd_boolean *again)
02114 {
02115 Elf_Internal_Shdr *symtab_hdr;
02116 Elf_Internal_Rela *internal_relocs;
02117 bfd_boolean have_code;
02118 Elf_Internal_Rela *irel, *irelend;
02119 bfd_byte *contents = NULL;
02120 Elf_Internal_Sym *isymbuf = NULL;
02121
02122 *again = FALSE;
02123
02124 if (link_info->relocatable
02125 || (sec->flags & SEC_RELOC) == 0
02126 || sec->reloc_count == 0)
02127 return TRUE;
02128
02129 #ifdef INCLUDE_SHMEDIA
02130 if (elf_section_data (sec)->this_hdr.sh_flags
02131 & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED))
02132 {
02133 return TRUE;
02134 }
02135 #endif
02136
02137 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
02138
02139 internal_relocs = (_bfd_elf_link_read_relocs
02140 (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
02141 link_info->keep_memory));
02142 if (internal_relocs == NULL)
02143 goto error_return;
02144
02145 have_code = FALSE;
02146
02147 irelend = internal_relocs + sec->reloc_count;
02148 for (irel = internal_relocs; irel < irelend; irel++)
02149 {
02150 bfd_vma laddr, paddr, symval;
02151 unsigned short insn;
02152 Elf_Internal_Rela *irelfn, *irelscan, *irelcount;
02153 bfd_signed_vma foff;
02154
02155 if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_CODE)
02156 have_code = TRUE;
02157
02158 if (ELF32_R_TYPE (irel->r_info) != (int) R_SH_USES)
02159 continue;
02160
02161
02162 if (contents == NULL)
02163 {
02164 if (elf_section_data (sec)->this_hdr.contents != NULL)
02165 contents = elf_section_data (sec)->this_hdr.contents;
02166 else
02167 {
02168 if (!bfd_malloc_and_get_section (abfd, sec, &contents))
02169 goto error_return;
02170 }
02171 }
02172
02173
02174
02175
02176
02177 laddr = irel->r_offset + 4 + irel->r_addend;
02178 if (laddr >= sec->size)
02179 {
02180 (*_bfd_error_handler) (_("%B: 0x%lx: warning: bad R_SH_USES offset"),
02181 abfd,
02182 (unsigned long) irel->r_offset);
02183 continue;
02184 }
02185 insn = bfd_get_16 (abfd, contents + laddr);
02186
02187
02188
02189 if ((insn & 0xf000) != 0xd000)
02190 {
02191 ((*_bfd_error_handler)
02192 (_("%B: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"),
02193 abfd, (unsigned long) irel->r_offset, insn));
02194 continue;
02195 }
02196
02197
02198
02199
02200
02201
02202
02203 paddr = insn & 0xff;
02204 paddr *= 4;
02205 paddr += (laddr + 4) &~ (bfd_vma) 3;
02206 if (paddr >= sec->size)
02207 {
02208 ((*_bfd_error_handler)
02209 (_("%B: 0x%lx: warning: bad R_SH_USES load offset"),
02210 abfd, (unsigned long) irel->r_offset));
02211 continue;
02212 }
02213
02214
02215
02216
02217 for (irelfn = internal_relocs; irelfn < irelend; irelfn++)
02218 if (irelfn->r_offset == paddr
02219 && ELF32_R_TYPE (irelfn->r_info) == (int) R_SH_DIR32)
02220 break;
02221 if (irelfn >= irelend)
02222 {
02223 ((*_bfd_error_handler)
02224 (_("%B: 0x%lx: warning: could not find expected reloc"),
02225 abfd, (unsigned long) paddr));
02226 continue;
02227 }
02228
02229
02230 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
02231 {
02232 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
02233 if (isymbuf == NULL)
02234 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
02235 symtab_hdr->sh_info, 0,
02236 NULL, NULL, NULL);
02237 if (isymbuf == NULL)
02238 goto error_return;
02239 }
02240
02241
02242 if (ELF32_R_SYM (irelfn->r_info) < symtab_hdr->sh_info)
02243 {
02244
02245 Elf_Internal_Sym *isym;
02246
02247 isym = isymbuf + ELF32_R_SYM (irelfn->r_info);
02248 if (isym->st_shndx
02249 != (unsigned int) _bfd_elf_section_from_bfd_section (abfd, sec))
02250 {
02251 ((*_bfd_error_handler)
02252 (_("%B: 0x%lx: warning: symbol in unexpected section"),
02253 abfd, (unsigned long) paddr));
02254 continue;
02255 }
02256
02257 symval = (isym->st_value
02258 + sec->output_section->vma
02259 + sec->output_offset);
02260 }
02261 else
02262 {
02263 unsigned long indx;
02264 struct elf_link_hash_entry *h;
02265
02266 indx = ELF32_R_SYM (irelfn->r_info) - symtab_hdr->sh_info;
02267 h = elf_sym_hashes (abfd)[indx];
02268 BFD_ASSERT (h != NULL);
02269 if (h->root.type != bfd_link_hash_defined
02270 && h->root.type != bfd_link_hash_defweak)
02271 {
02272
02273
02274
02275 continue;
02276 }
02277
02278 symval = (h->root.u.def.value
02279 + h->root.u.def.section->output_section->vma
02280 + h->root.u.def.section->output_offset);
02281 }
02282
02283 symval += bfd_get_32 (abfd, contents + paddr);
02284
02285
02286 foff = (symval
02287 - (irel->r_offset
02288 + sec->output_section->vma
02289 + sec->output_offset
02290 + 4));
02291 if (foff < -0x1000 || foff >= 0x1000)
02292 {
02293
02294 continue;
02295 }
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307 elf_section_data (sec)->relocs = internal_relocs;
02308 elf_section_data (sec)->this_hdr.contents = contents;
02309 symtab_hdr->contents = (unsigned char *) isymbuf;
02310
02311
02312
02313
02314
02315 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irelfn->r_info), R_SH_IND12W);
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325 bfd_put_16 (abfd, (bfd_vma) 0xb000, contents + irel->r_offset);
02326
02327 irel->r_addend = -4;
02328
02329
02330
02331 for (irelscan = internal_relocs; irelscan < irelend; irelscan++)
02332 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_SH_USES
02333 && laddr == irelscan->r_offset + 4 + irelscan->r_addend)
02334 break;
02335 if (irelscan < irelend)
02336 {
02337
02338
02339
02340
02341 continue;
02342 }
02343
02344
02345
02346
02347 for (irelcount = internal_relocs; irelcount < irelend; irelcount++)
02348 if (irelcount->r_offset == paddr
02349 && ELF32_R_TYPE (irelcount->r_info) == (int) R_SH_COUNT)
02350 break;
02351
02352
02353 if (! sh_elf_relax_delete_bytes (abfd, sec, laddr, 2))
02354 goto error_return;
02355
02356
02357
02358
02359 *again = TRUE;
02360
02361
02362 if (irelcount >= irelend)
02363 {
02364 ((*_bfd_error_handler)
02365 (_("%B: 0x%lx: warning: could not find expected COUNT reloc"),
02366 abfd, (unsigned long) paddr));
02367 continue;
02368 }
02369
02370
02371
02372 if (irelcount->r_addend == 0)
02373 {
02374 ((*_bfd_error_handler) (_("%B: 0x%lx: warning: bad count"),
02375 abfd,
02376 (unsigned long) paddr));
02377 continue;
02378 }
02379
02380 --irelcount->r_addend;
02381
02382
02383
02384
02385 if (irelcount->r_addend == 0)
02386 {
02387 if (! sh_elf_relax_delete_bytes (abfd, sec, irelfn->r_offset, 4))
02388 goto error_return;
02389 }
02390
02391
02392 }
02393
02394
02395
02396 if ((elf_elfheader (abfd)->e_flags & EF_SH_MACH_MASK) != EF_SH4
02397 && have_code)
02398 {
02399 bfd_boolean swapped;
02400
02401
02402 if (contents == NULL)
02403 {
02404 if (elf_section_data (sec)->this_hdr.contents != NULL)
02405 contents = elf_section_data (sec)->this_hdr.contents;
02406 else
02407 {
02408 if (!bfd_malloc_and_get_section (abfd, sec, &contents))
02409 goto error_return;
02410 }
02411 }
02412
02413 if (! sh_elf_align_loads (abfd, sec, internal_relocs, contents,
02414 &swapped))
02415 goto error_return;
02416
02417 if (swapped)
02418 {
02419 elf_section_data (sec)->relocs = internal_relocs;
02420 elf_section_data (sec)->this_hdr.contents = contents;
02421 symtab_hdr->contents = (unsigned char *) isymbuf;
02422 }
02423 }
02424
02425 if (isymbuf != NULL
02426 && symtab_hdr->contents != (unsigned char *) isymbuf)
02427 {
02428 if (! link_info->keep_memory)
02429 free (isymbuf);
02430 else
02431 {
02432
02433 symtab_hdr->contents = (unsigned char *) isymbuf;
02434 }
02435 }
02436
02437 if (contents != NULL
02438 && elf_section_data (sec)->this_hdr.contents != contents)
02439 {
02440 if (! link_info->keep_memory)
02441 free (contents);
02442 else
02443 {
02444
02445 elf_section_data (sec)->this_hdr.contents = contents;
02446 }
02447 }
02448
02449 if (internal_relocs != NULL
02450 && elf_section_data (sec)->relocs != internal_relocs)
02451 free (internal_relocs);
02452
02453 return TRUE;
02454
02455 error_return:
02456 if (isymbuf != NULL
02457 && symtab_hdr->contents != (unsigned char *) isymbuf)
02458 free (isymbuf);
02459 if (contents != NULL
02460 && elf_section_data (sec)->this_hdr.contents != contents)
02461 free (contents);
02462 if (internal_relocs != NULL
02463 && elf_section_data (sec)->relocs != internal_relocs)
02464 free (internal_relocs);
02465
02466 return FALSE;
02467 }
02468
02469
02470
02471
02472
02473 static bfd_boolean
02474 sh_elf_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr,
02475 int count)
02476 {
02477 Elf_Internal_Shdr *symtab_hdr;
02478 unsigned int sec_shndx;
02479 bfd_byte *contents;
02480 Elf_Internal_Rela *irel, *irelend;
02481 Elf_Internal_Rela *irelalign;
02482 bfd_vma toaddr;
02483 Elf_Internal_Sym *isymbuf, *isym, *isymend;
02484 struct elf_link_hash_entry **sym_hashes;
02485 struct elf_link_hash_entry **end_hashes;
02486 unsigned int symcount;
02487 asection *o;
02488
02489 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
02490 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
02491
02492 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
02493
02494 contents = elf_section_data (sec)->this_hdr.contents;
02495
02496
02497
02498
02499 irelalign = NULL;
02500 toaddr = sec->size;
02501
02502 irel = elf_section_data (sec)->relocs;
02503 irelend = irel + sec->reloc_count;
02504 for (; irel < irelend; irel++)
02505 {
02506 if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_ALIGN
02507 && irel->r_offset > addr
02508 && count < (1 << irel->r_addend))
02509 {
02510 irelalign = irel;
02511 toaddr = irel->r_offset;
02512 break;
02513 }
02514 }
02515
02516
02517 memmove (contents + addr, contents + addr + count,
02518 (size_t) (toaddr - addr - count));
02519 if (irelalign == NULL)
02520 sec->size -= count;
02521 else
02522 {
02523 int i;
02524
02525 #define NOP_OPCODE (0x0009)
02526
02527 BFD_ASSERT ((count & 1) == 0);
02528 for (i = 0; i < count; i += 2)
02529 bfd_put_16 (abfd, (bfd_vma) NOP_OPCODE, contents + toaddr - count + i);
02530 }
02531
02532
02533 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
02534 {
02535 bfd_vma nraddr, stop;
02536 bfd_vma start = 0;
02537 int insn = 0;
02538 int off, adjust, oinsn;
02539 bfd_signed_vma voff = 0;
02540 bfd_boolean overflow;
02541
02542
02543 nraddr = irel->r_offset;
02544 if ((irel->r_offset > addr
02545 && irel->r_offset < toaddr)
02546 || (ELF32_R_TYPE (irel->r_info) == (int) R_SH_ALIGN
02547 && irel->r_offset == toaddr))
02548 nraddr -= count;
02549
02550
02551
02552
02553 if (irel->r_offset >= addr
02554 && irel->r_offset < addr + count
02555 && ELF32_R_TYPE (irel->r_info) != (int) R_SH_ALIGN
02556 && ELF32_R_TYPE (irel->r_info) != (int) R_SH_CODE
02557 && ELF32_R_TYPE (irel->r_info) != (int) R_SH_DATA
02558 && ELF32_R_TYPE (irel->r_info) != (int) R_SH_LABEL)
02559 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
02560 (int) R_SH_NONE);
02561
02562
02563
02564 switch ((enum elf_sh_reloc_type) ELF32_R_TYPE (irel->r_info))
02565 {
02566 default:
02567 break;
02568
02569 case R_SH_DIR8WPN:
02570 case R_SH_IND12W:
02571 case R_SH_DIR8WPZ:
02572 case R_SH_DIR8WPL:
02573 start = irel->r_offset;
02574 insn = bfd_get_16 (abfd, contents + nraddr);
02575 break;
02576 }
02577
02578 switch ((enum elf_sh_reloc_type) ELF32_R_TYPE (irel->r_info))
02579 {
02580 default:
02581 start = stop = addr;
02582 break;
02583
02584 case R_SH_DIR32:
02585
02586
02587
02588
02589 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
02590 {
02591 isym = isymbuf + ELF32_R_SYM (irel->r_info);
02592 if (isym->st_shndx == sec_shndx
02593 && (isym->st_value <= addr
02594 || isym->st_value >= toaddr))
02595 {
02596 bfd_vma val;
02597
02598 val = bfd_get_32 (abfd, contents + nraddr);
02599 val += isym->st_value;
02600 if (val > addr && val < toaddr)
02601 bfd_put_32 (abfd, val - count, contents + nraddr);
02602 }
02603 }
02604 start = stop = addr;
02605 break;
02606
02607 case R_SH_DIR8WPN:
02608 off = insn & 0xff;
02609 if (off & 0x80)
02610 off -= 0x100;
02611 stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2);
02612 break;
02613
02614 case R_SH_IND12W:
02615 off = insn & 0xfff;
02616 if (! off)
02617 {
02618
02619
02620
02621 start = stop = addr;
02622 }
02623 else
02624 {
02625 if (off & 0x800)
02626 off -= 0x1000;
02627 stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2);
02628
02629
02630
02631
02632
02633
02634
02635 if (stop > addr && stop < toaddr)
02636 irel->r_addend -= count;
02637 }
02638 break;
02639
02640 case R_SH_DIR8WPZ:
02641 off = insn & 0xff;
02642 stop = start + 4 + off * 2;
02643 break;
02644
02645 case R_SH_DIR8WPL:
02646 off = insn & 0xff;
02647 stop = (start & ~(bfd_vma) 3) + 4 + off * 4;
02648 break;
02649
02650 case R_SH_SWITCH8:
02651 case R_SH_SWITCH16:
02652 case R_SH_SWITCH32:
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662 stop = irel->r_offset;
02663 start = (bfd_vma) ((bfd_signed_vma) stop - (long) irel->r_addend);
02664
02665 if (start > addr
02666 && start < toaddr
02667 && (stop <= addr || stop >= toaddr))
02668 irel->r_addend += count;
02669 else if (stop > addr
02670 && stop < toaddr
02671 && (start <= addr || start >= toaddr))
02672 irel->r_addend -= count;
02673
02674 if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_SWITCH16)
02675 voff = bfd_get_signed_16 (abfd, contents + nraddr);
02676 else if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_SWITCH8)
02677 voff = bfd_get_8 (abfd, contents + nraddr);
02678 else
02679 voff = bfd_get_signed_32 (abfd, contents + nraddr);
02680 stop = (bfd_vma) ((bfd_signed_vma) start + voff);
02681
02682 break;
02683
02684 case R_SH_USES:
02685 start = irel->r_offset;
02686 stop = (bfd_vma) ((bfd_signed_vma) start
02687 + (long) irel->r_addend
02688 + 4);
02689 break;
02690 }
02691
02692 if (start > addr
02693 && start < toaddr
02694 && (stop <= addr || stop >= toaddr))
02695 adjust = count;
02696 else if (stop > addr
02697 && stop < toaddr
02698 && (start <= addr || start >= toaddr))
02699 adjust = - count;
02700 else
02701 adjust = 0;
02702
02703 if (adjust != 0)
02704 {
02705 oinsn = insn;
02706 overflow = FALSE;
02707 switch ((enum elf_sh_reloc_type) ELF32_R_TYPE (irel->r_info))
02708 {
02709 default:
02710 abort ();
02711 break;
02712
02713 case R_SH_DIR8WPN:
02714 case R_SH_DIR8WPZ:
02715 insn += adjust / 2;
02716 if ((oinsn & 0xff00) != (insn & 0xff00))
02717 overflow = TRUE;
02718 bfd_put_16 (abfd, (bfd_vma) insn, contents + nraddr);
02719 break;
02720
02721 case R_SH_IND12W:
02722 insn += adjust / 2;
02723 if ((oinsn & 0xf000) != (insn & 0xf000))
02724 overflow = TRUE;
02725 bfd_put_16 (abfd, (bfd_vma) insn, contents + nraddr);
02726 break;
02727
02728 case R_SH_DIR8WPL:
02729 BFD_ASSERT (adjust == count || count >= 4);
02730 if (count >= 4)
02731 insn += adjust / 4;
02732 else
02733 {
02734 if ((irel->r_offset & 3) == 0)
02735 ++insn;
02736 }
02737 if ((oinsn & 0xff00) != (insn & 0xff00))
02738 overflow = TRUE;
02739 bfd_put_16 (abfd, (bfd_vma) insn, contents + nraddr);
02740 break;
02741
02742 case R_SH_SWITCH8:
02743 voff += adjust;
02744 if (voff < 0 || voff >= 0xff)
02745 overflow = TRUE;
02746 bfd_put_8 (abfd, voff, contents + nraddr);
02747 break;
02748
02749 case R_SH_SWITCH16:
02750 voff += adjust;
02751 if (voff < - 0x8000 || voff >= 0x8000)
02752 overflow = TRUE;
02753 bfd_put_signed_16 (abfd, (bfd_vma) voff, contents + nraddr);
02754 break;
02755
02756 case R_SH_SWITCH32:
02757 voff += adjust;
02758 bfd_put_signed_32 (abfd, (bfd_vma) voff, contents + nraddr);
02759 break;
02760
02761 case R_SH_USES:
02762 irel->r_addend += adjust;
02763 break;
02764 }
02765
02766 if (overflow)
02767 {
02768 ((*_bfd_error_handler)
02769 (_("%B: 0x%lx: fatal: reloc overflow while relaxing"),
02770 abfd, (unsigned long) irel->r_offset));
02771 bfd_set_error (bfd_error_bad_value);
02772 return FALSE;
02773 }
02774 }
02775
02776 irel->r_offset = nraddr;
02777 }
02778
02779
02780
02781
02782 for (o = abfd->sections; o != NULL; o = o->next)
02783 {
02784 Elf_Internal_Rela *internal_relocs;
02785 Elf_Internal_Rela *irelscan, *irelscanend;
02786 bfd_byte *ocontents;
02787
02788 if (o == sec
02789 || (o->flags & SEC_RELOC) == 0
02790 || o->reloc_count == 0)
02791 continue;
02792
02793
02794
02795
02796 internal_relocs = (_bfd_elf_link_read_relocs
02797 (abfd, o, NULL, (Elf_Internal_Rela *) NULL, TRUE));
02798 if (internal_relocs == NULL)
02799 return FALSE;
02800
02801 ocontents = NULL;
02802 irelscanend = internal_relocs + o->reloc_count;
02803 for (irelscan = internal_relocs; irelscan < irelscanend; irelscan++)
02804 {
02805
02806 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_SH_SWITCH32)
02807 {
02808 bfd_vma start, stop;
02809 bfd_signed_vma voff;
02810
02811 if (ocontents == NULL)
02812 {
02813 if (elf_section_data (o)->this_hdr.contents != NULL)
02814 ocontents = elf_section_data (o)->this_hdr.contents;
02815 else
02816 {
02817
02818
02819
02820
02821 if (!bfd_malloc_and_get_section (abfd, o, &ocontents))
02822 {
02823 if (ocontents != NULL)
02824 free (ocontents);
02825 return FALSE;
02826 }
02827
02828 elf_section_data (o)->this_hdr.contents = ocontents;
02829 }
02830 }
02831
02832 stop = irelscan->r_offset;
02833 start
02834 = (bfd_vma) ((bfd_signed_vma) stop - (long) irelscan->r_addend);
02835
02836
02837 if (start > addr && start < toaddr)
02838 irelscan->r_addend += count;
02839
02840 voff = bfd_get_signed_32 (abfd, ocontents + irelscan->r_offset);
02841 stop = (bfd_vma) ((bfd_signed_vma) start + voff);
02842
02843 if (start > addr
02844 && start < toaddr
02845 && (stop <= addr || stop >= toaddr))
02846 bfd_put_signed_32 (abfd, (bfd_vma) voff + count,
02847 ocontents + irelscan->r_offset);
02848 else if (stop > addr
02849 && stop < toaddr
02850 && (start <= addr || start >= toaddr))
02851 bfd_put_signed_32 (abfd, (bfd_vma) voff - count,
02852 ocontents + irelscan->r_offset);
02853 }
02854
02855 if (ELF32_R_TYPE (irelscan->r_info) != (int) R_SH_DIR32)
02856 continue;
02857
02858 if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
02859 continue;
02860
02861
02862 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
02863 if (isym->st_shndx == sec_shndx
02864 && (isym->st_value <= addr
02865 || isym->st_value >= toaddr))
02866 {
02867 bfd_vma val;
02868
02869 if (ocontents == NULL)
02870 {
02871 if (elf_section_data (o)->this_hdr.contents != NULL)
02872 ocontents = elf_section_data (o)->this_hdr.contents;
02873 else
02874 {
02875
02876
02877
02878
02879 if (!bfd_malloc_and_get_section (abfd, o, &ocontents))
02880 {
02881 if (ocontents != NULL)
02882 free (ocontents);
02883 return FALSE;
02884 }
02885
02886 elf_section_data (o)->this_hdr.contents = ocontents;
02887 }
02888 }
02889
02890 val = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
02891 val += isym->st_value;
02892 if (val > addr && val < toaddr)
02893 bfd_put_32 (abfd, val - count,
02894 ocontents + irelscan->r_offset);
02895 }
02896 }
02897 }
02898
02899
02900 isymend = isymbuf + symtab_hdr->sh_info;
02901 for (isym = isymbuf; isym < isymend; isym++)
02902 {
02903 if (isym->st_shndx == sec_shndx
02904 && isym->st_value > addr
02905 && isym->st_value < toaddr)
02906 isym->st_value -= count;
02907 }
02908
02909
02910 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
02911 - symtab_hdr->sh_info);
02912 sym_hashes = elf_sym_hashes (abfd);
02913 end_hashes = sym_hashes + symcount;
02914 for (; sym_hashes < end_hashes; sym_hashes++)
02915 {
02916 struct elf_link_hash_entry *sym_hash = *sym_hashes;
02917 if ((sym_hash->root.type == bfd_link_hash_defined
02918 || sym_hash->root.type == bfd_link_hash_defweak)
02919 && sym_hash->root.u.def.section == sec
02920 && sym_hash->root.u.def.value > addr
02921 && sym_hash->root.u.def.value < toaddr)
02922 {
02923 sym_hash->root.u.def.value -= count;
02924 }
02925 }
02926
02927
02928
02929 if (irelalign != NULL)
02930 {
02931 bfd_vma alignto, alignaddr;
02932
02933 alignto = BFD_ALIGN (toaddr, 1 << irelalign->r_addend);
02934 alignaddr = BFD_ALIGN (irelalign->r_offset,
02935 1 << irelalign->r_addend);
02936 if (alignto != alignaddr)
02937 {
02938
02939 return sh_elf_relax_delete_bytes (abfd, sec, alignaddr,
02940 (int) (alignto - alignaddr));
02941 }
02942 }
02943
02944 return TRUE;
02945 }
02946
02947
02948
02949
02950 static bfd_boolean
02951 sh_elf_align_loads (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
02952 Elf_Internal_Rela *internal_relocs,
02953 bfd_byte *contents ATTRIBUTE_UNUSED,
02954 bfd_boolean *pswapped)
02955 {
02956 Elf_Internal_Rela *irel, *irelend;
02957 bfd_vma *labels = NULL;
02958 bfd_vma *label, *label_end;
02959 bfd_size_type amt;
02960
02961 *pswapped = FALSE;
02962
02963 irelend = internal_relocs + sec->reloc_count;
02964
02965
02966 amt = sec->reloc_count;
02967 amt *= sizeof (bfd_vma);
02968 labels = (bfd_vma *) bfd_malloc (amt);
02969 if (labels == NULL)
02970 goto error_return;
02971 label_end = labels;
02972 for (irel = internal_relocs; irel < irelend; irel++)
02973 {
02974 if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_LABEL)
02975 {
02976 *label_end = irel->r_offset;
02977 ++label_end;
02978 }
02979 }
02980
02981
02982
02983
02984
02985 label = labels;
02986
02987 for (irel = internal_relocs; irel < irelend; irel++)
02988 {
02989 bfd_vma start, stop;
02990
02991 if (ELF32_R_TYPE (irel->r_info) != (int) R_SH_CODE)
02992 continue;
02993
02994 start = irel->r_offset;
02995
02996 for (irel++; irel < irelend; irel++)
02997 if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_DATA)
02998 break;
02999 if (irel < irelend)
03000 stop = irel->r_offset;
03001 else
03002 stop = sec->size;
03003
03004 if (! _bfd_sh_align_load_span (abfd, sec, contents, sh_elf_swap_insns,
03005 internal_relocs, &label,
03006 label_end, start, stop, pswapped))
03007 goto error_return;
03008 }
03009
03010 free (labels);
03011
03012 return TRUE;
03013
03014 error_return:
03015 if (labels != NULL)
03016 free (labels);
03017 return FALSE;
03018 }
03019
03020 #ifndef SH64_ELF
03021
03022
03023 static bfd_boolean
03024 sh_elf_swap_insns (bfd *abfd, asection *sec, void *relocs,
03025 bfd_byte *contents, bfd_vma addr)
03026 {
03027 Elf_Internal_Rela *internal_relocs = (Elf_Internal_Rela *) relocs;
03028 unsigned short i1, i2;
03029 Elf_Internal_Rela *irel, *irelend;
03030
03031
03032 i1 = bfd_get_16 (abfd, contents + addr);
03033 i2 = bfd_get_16 (abfd, contents + addr + 2);
03034 bfd_put_16 (abfd, (bfd_vma) i2, contents + addr);
03035 bfd_put_16 (abfd, (bfd_vma) i1, contents + addr + 2);
03036
03037
03038 irelend = internal_relocs + sec->reloc_count;
03039 for (irel = internal_relocs; irel < irelend; irel++)
03040 {
03041 enum elf_sh_reloc_type type;
03042 int add;
03043
03044
03045
03046
03047 type = (enum elf_sh_reloc_type) ELF32_R_TYPE (irel->r_info);
03048 if (type == R_SH_ALIGN
03049 || type == R_SH_CODE
03050 || type == R_SH_DATA
03051 || type == R_SH_LABEL)
03052 continue;
03053
03054
03055
03056
03057
03058
03059
03060 if (type == R_SH_USES)
03061 {
03062 bfd_vma off;
03063
03064 off = irel->r_offset + 4 + irel->r_addend;
03065 if (off == addr)
03066 irel->r_offset += 2;
03067 else if (off == addr + 2)
03068 irel->r_offset -= 2;
03069 }
03070
03071 if (irel->r_offset == addr)
03072 {
03073 irel->r_offset += 2;
03074 add = -2;
03075 }
03076 else if (irel->r_offset == addr + 2)
03077 {
03078 irel->r_offset -= 2;
03079 add = 2;
03080 }
03081 else
03082 add = 0;
03083
03084 if (add != 0)
03085 {
03086 bfd_byte *loc;
03087 unsigned short insn, oinsn;
03088 bfd_boolean overflow;
03089
03090 loc = contents + irel->r_offset;
03091 overflow = FALSE;
03092 switch (type)
03093 {
03094 default:
03095 break;
03096
03097 case R_SH_DIR8WPN:
03098 case R_SH_DIR8WPZ:
03099 insn = bfd_get_16 (abfd, loc);
03100 oinsn = insn;
03101 insn += add / 2;
03102 if ((oinsn & 0xff00) != (insn & 0xff00))
03103 overflow = TRUE;
03104 bfd_put_16 (abfd, (bfd_vma) insn, loc);
03105 break;
03106
03107 case R_SH_IND12W:
03108 insn = bfd_get_16 (abfd, loc);
03109 oinsn = insn;
03110 insn += add / 2;
03111 if ((oinsn & 0xf000) != (insn & 0xf000))
03112 overflow = TRUE;
03113 bfd_put_16 (abfd, (bfd_vma) insn, loc);
03114 break;
03115
03116 case R_SH_DIR8WPL:
03117
03118
03119
03120
03121
03122
03123 if ((addr & 3) != 0)
03124 {
03125 insn = bfd_get_16 (abfd, loc);
03126 oinsn = insn;
03127 insn += add / 2;
03128 if ((oinsn & 0xff00) != (insn & 0xff00))
03129 overflow = TRUE;
03130 bfd_put_16 (abfd, (bfd_vma) insn, loc);
03131 }
03132
03133 break;
03134 }
03135
03136 if (overflow)
03137 {
03138 ((*_bfd_error_handler)
03139 (_("%B: 0x%lx: fatal: reloc overflow while relaxing"),
03140 abfd, (unsigned long) irel->r_offset));
03141 bfd_set_error (bfd_error_bad_value);
03142 return FALSE;
03143 }
03144 }
03145 }
03146
03147 return TRUE;
03148 }
03149 #endif
03150
03151 #ifdef INCLUDE_SHMEDIA
03152
03153
03154
03155 #define PLT_ENTRY_SIZE 64
03156
03157
03158
03159 static const bfd_byte elf_sh_plt0_entry_be[PLT_ENTRY_SIZE] =
03160 {
03161 0xcc, 0x00, 0x01, 0x10,
03162 0xc8, 0x00, 0x01, 0x10,
03163 0x89, 0x10, 0x09, 0x90,
03164 0x6b, 0xf1, 0x66, 0x00,
03165 0x89, 0x10, 0x05, 0x10,
03166 0x44, 0x01, 0xff, 0xf0,
03167 0x6f, 0xf0, 0xff, 0xf0,
03168 0x6f, 0xf0, 0xff, 0xf0,
03169 0x6f, 0xf0, 0xff, 0xf0,
03170 0x6f, 0xf0, 0xff, 0xf0,
03171 0x6f, 0xf0, 0xff, 0xf0,
03172 0x6f, 0xf0, 0xff, 0xf0,
03173 0x6f, 0xf0, 0xff, 0xf0,
03174 0x6f, 0xf0, 0xff, 0xf0,
03175 0x6f, 0xf0, 0xff, 0xf0,
03176 0x6f, 0xf0, 0xff, 0xf0,
03177 };
03178
03179 static const bfd_byte elf_sh_plt0_entry_le[PLT_ENTRY_SIZE] =
03180 {
03181 0x10, 0x01, 0x00, 0xcc,
03182 0x10, 0x01, 0x00, 0xc8,
03183 0x90, 0x09, 0x10, 0x89,
03184 0x00, 0x66, 0xf1, 0x6b,
03185 0x10, 0x05, 0x10, 0x89,
03186 0xf0, 0xff, 0x01, 0x44,
03187 0xf0, 0xff, 0xf0, 0x6f,
03188 0xf0, 0xff, 0xf0, 0x6f,
03189 0xf0, 0xff, 0xf0, 0x6f,
03190 0xf0, 0xff, 0xf0, 0x6f,
03191 0xf0, 0xff, 0xf0, 0x6f,
03192 0xf0, 0xff, 0xf0, 0x6f,
03193 0xf0, 0xff, 0xf0, 0x6f,
03194 0xf0, 0xff, 0xf0, 0x6f,
03195 0xf0, 0xff, 0xf0, 0x6f,
03196 0xf0, 0xff, 0xf0, 0x6f,
03197 };
03198
03199
03200
03201
03202 static const bfd_byte elf_sh_plt_entry_be[PLT_ENTRY_SIZE] =
03203 {
03204 0xcc, 0x00, 0x01, 0x90,
03205 0xc8, 0x00, 0x01, 0x90,
03206 0x89, 0x90, 0x01, 0x90,
03207 0x6b, 0xf1, 0x66, 0x00,
03208 0x44, 0x01, 0xff, 0xf0,
03209 0x6f, 0xf0, 0xff, 0xf0,
03210 0x6f, 0xf0, 0xff, 0xf0,
03211 0x6f, 0xf0, 0xff, 0xf0,
03212 0xcc, 0x00, 0x01, 0x90,
03213 0xc8, 0x00, 0x01, 0x90,
03214 0x6b, 0xf1, 0x66, 0x00,
03215 0xcc, 0x00, 0x01, 0x50,
03216 0xc8, 0x00, 0x01, 0x50,
03217 0x44, 0x01, 0xff, 0xf0,
03218 0x6f, 0xf0, 0xff, 0xf0,
03219 0x6f, 0xf0, 0xff, 0xf0,
03220 };
03221
03222 static const bfd_byte elf_sh_plt_entry_le[PLT_ENTRY_SIZE] =
03223 {
03224 0x90, 0x01, 0x00, 0xcc,
03225 0x90, 0x01, 0x00, 0xc8,
03226 0x90, 0x01, 0x90, 0x89,
03227 0x00, 0x66, 0xf1, 0x6b,
03228 0xf0, 0xff, 0x01, 0x44,
03229 0xf0, 0xff, 0xf0, 0x6f,
03230 0xf0, 0xff, 0xf0, 0x6f,
03231 0xf0, 0xff, 0xf0, 0x6f,
03232 0x90, 0x01, 0x00, 0xcc,
03233 0x90, 0x01, 0x00, 0xc8,
03234 0x00, 0x66, 0xf1, 0x6b,
03235 0x50, 0x01, 0x00, 0xcc,
03236 0x50, 0x01, 0x00, 0xc8,
03237 0xf0, 0xff, 0x01, 0x44,
03238 0xf0, 0xff, 0xf0, 0x6f,
03239 0xf0, 0xff, 0xf0, 0x6f,
03240 };
03241
03242
03243
03244 static const bfd_byte elf_sh_pic_plt_entry_be[PLT_ENTRY_SIZE] =
03245 {
03246 0xcc, 0x00, 0x01, 0x90,
03247 0xc8, 0x00, 0x01, 0x90,
03248 0x40, 0xc2, 0x65, 0x90,
03249 0x6b, 0xf1, 0x66, 0x00,
03250 0x44, 0x01, 0xff, 0xf0,
03251 0x6f, 0xf0, 0xff, 0xf0,
03252 0x6f, 0xf0, 0xff, 0xf0,
03253 0x6f, 0xf0, 0xff, 0xf0,
03254 0xce, 0x00, 0x01, 0x10,
03255 0x00, 0xc8, 0x45, 0x10,
03256 0x89, 0x10, 0x09, 0x90,
03257 0x6b, 0xf1, 0x66, 0x00,
03258 0x89, 0x10, 0x05, 0x10,
03259 0xcc, 0x00, 0x01, 0x50,
03260 0xc8, 0x00, 0x01, 0x50,
03261 0x44, 0x01, 0xff, 0xf0,
03262 };
03263
03264 static const bfd_byte elf_sh_pic_plt_entry_le[PLT_ENTRY_SIZE] =
03265 {
03266 0x90, 0x01, 0x00, 0xcc,
03267 0x90, 0x01, 0x00, 0xc8,
03268 0x90, 0x65, 0xc2, 0x40,
03269 0x00, 0x66, 0xf1, 0x6b,
03270 0xf0, 0xff, 0x01, 0x44,
03271 0xf0, 0xff, 0xf0, 0x6f,
03272 0xf0, 0xff, 0xf0, 0x6f,
03273 0xf0, 0xff, 0xf0, 0x6f,
03274 0x10, 0x01, 0x00, 0xce,
03275 0x10, 0x45, 0xc8, 0x00,
03276 0x90, 0x09, 0x10, 0x89,
03277 0x00, 0x66, 0xf1, 0x6b,
03278 0x10, 0x05, 0x10, 0x89,
03279 0x50, 0x01, 0x00, 0xcc,
03280 0x50, 0x01, 0x00, 0xc8,
03281 0xf0, 0xff, 0x01, 0x44,
03282 };
03283
03284 static const bfd_byte *elf_sh_plt0_entry;
03285 static const bfd_byte *elf_sh_plt_entry;
03286 static const bfd_byte *elf_sh_pic_plt_entry;
03287
03288
03289 #define elf_sh_sizeof_plt(info) PLT_ENTRY_SIZE
03290
03291
03292 #define elf_sh_plt_plt0_offset(info) 32
03293
03294
03295 #define elf_sh_plt0_gotplt_offset(info) 0
03296
03297
03298 #define elf_sh_plt_temp_offset(info) 33
03299
03300
03301 #define elf_sh_plt_symbol_offset(info) 0
03302
03303
03304 #define elf_sh_plt_reloc_offset(info) (info->shared ? 52 : 44)
03305
03306 inline static void
03307 movi_shori_putval (bfd *output_bfd, unsigned long value, bfd_byte *addr)
03308 {
03309 bfd_put_32 (output_bfd,
03310 bfd_get_32 (output_bfd, addr)
03311 | ((value >> 6) & 0x3fffc00),
03312 addr);
03313 bfd_put_32 (output_bfd,
03314 bfd_get_32 (output_bfd, addr + 4)
03315 | ((value << 10) & 0x3fffc00),
03316 addr + 4);
03317 }
03318
03319 #else
03320
03321
03322 #define PLT_ENTRY_SIZE 28
03323
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334 static const bfd_byte elf_sh_plt0_entry_be[PLT_ENTRY_SIZE] =
03335 {
03336 0xd0, 0x05,
03337 0x60, 0x02,
03338 0x2f, 0x06,
03339 0xd0, 0x03,
03340 0x60, 0x02,
03341 0x40, 0x2b,
03342 0x60, 0xf6,
03343 0x00, 0x09,
03344 0x00, 0x09,
03345 0x00, 0x09,
03346 0, 0, 0, 0,
03347 0, 0, 0, 0,
03348 };
03349
03350 static const bfd_byte elf_sh_plt0_entry_le[PLT_ENTRY_SIZE] =
03351 {
03352 0x05, 0xd0,
03353 0x02, 0x60,
03354 0x06, 0x2f,
03355 0x03, 0xd0,
03356 0x02, 0x60,
03357 0x2b, 0x40,
03358 0xf6, 0x60,
03359 0x09, 0x00,
03360 0x09, 0x00,
03361 0x09, 0x00,
03362 0, 0, 0, 0,
03363 0, 0, 0, 0,
03364 };
03365
03366
03367
03368
03369 static const bfd_byte elf_sh_plt_entry_be[PLT_ENTRY_SIZE] =
03370 {
03371 0xd0, 0x04,
03372 0x60, 0x02,
03373 0xd1, 0x02,
03374 0x40, 0x2b,
03375 0x60, 0x13,
03376 0xd1, 0x03,
03377 0x40, 0x2b,
03378 0x00, 0x09,
03379 0, 0, 0, 0,
03380 0, 0, 0, 0,
03381 0, 0, 0, 0,
03382 };
03383
03384 static const bfd_byte elf_sh_plt_entry_le[PLT_ENTRY_SIZE] =
03385 {
03386 0x04, 0xd0,
03387 0x02, 0x60,
03388 0x02, 0xd1,
03389 0x2b, 0x40,
03390 0x13, 0x60,
03391 0x03, 0xd1,
03392 0x2b, 0x40,
03393 0x09, 0x00,
03394 0, 0, 0, 0,
03395 0, 0, 0, 0,
03396 0, 0, 0, 0,
03397 };
03398
03399
03400
03401 static const bfd_byte elf_sh_pic_plt_entry_be[PLT_ENTRY_SIZE] =
03402 {
03403 0xd0, 0x04,
03404 0x00, 0xce,
03405 0x40, 0x2b,
03406 0x00, 0x09,
03407 0x50, 0xc2,
03408 0xd1, 0x03,
03409 0x40, 0x2b,
03410 0x50, 0xc1,
03411 0x00, 0x09,
03412 0x00, 0x09,
03413 0, 0, 0, 0,
03414 0, 0, 0, 0
03415 };
03416
03417 static const bfd_byte elf_sh_pic_plt_entry_le[PLT_ENTRY_SIZE] =
03418 {
03419 0x04, 0xd0,
03420 0xce, 0x00,
03421 0x2b, 0x40,
03422 0x09, 0x00,
03423 0xc2, 0x50,
03424 0x03, 0xd1,
03425 0x2b, 0x40,
03426 0xc1, 0x50,
03427 0x09, 0x00,
03428 0x09, 0x00,
03429 0, 0, 0, 0,
03430 0, 0, 0, 0
03431 };
03432
03433 static const bfd_byte *elf_sh_plt0_entry;
03434 static const bfd_byte *elf_sh_plt_entry;
03435 static const bfd_byte *elf_sh_pic_plt_entry;
03436
03437
03438 #define elf_sh_sizeof_plt(info) PLT_ENTRY_SIZE
03439
03440
03441 #define elf_sh_plt_plt0_offset(info) 16
03442
03443
03444 #define elf_sh_plt0_linker_offset(info) 20
03445
03446
03447 #define elf_sh_plt0_gotid_offset(info) 24
03448
03449
03450 #define elf_sh_plt_temp_offset(info) 8
03451
03452
03453 #define elf_sh_plt_symbol_offset(info) 20
03454
03455
03456 #define elf_sh_plt_reloc_offset(info) 24
03457 #endif
03458
03459
03460
03461
03462
03463
03464
03465 struct elf_sh_dyn_relocs
03466 {
03467 struct elf_sh_dyn_relocs *next;
03468
03469
03470 asection *sec;
03471
03472
03473 bfd_size_type count;
03474
03475
03476 bfd_size_type pc_count;
03477 };
03478
03479
03480
03481 struct elf_sh_link_hash_entry
03482 {
03483 struct elf_link_hash_entry root;
03484
03485 #ifdef INCLUDE_SHMEDIA
03486 union
03487 {
03488 bfd_signed_vma refcount;
03489 bfd_vma offset;
03490 } datalabel_got;
03491 #endif
03492
03493
03494 struct elf_sh_dyn_relocs *dyn_relocs;
03495
03496 bfd_signed_vma gotplt_refcount;
03497
03498 enum {
03499 GOT_UNKNOWN = 0, GOT_NORMAL, GOT_TLS_GD, GOT_TLS_IE
03500 } tls_type;
03501 };
03502
03503 #define sh_elf_hash_entry(ent) ((struct elf_sh_link_hash_entry *)(ent))
03504
03505 struct sh_elf_obj_tdata
03506 {
03507 struct elf_obj_tdata root;
03508
03509
03510 char *local_got_tls_type;
03511 };
03512
03513 #define sh_elf_tdata(abfd) \
03514 ((struct sh_elf_obj_tdata *) (abfd)->tdata.any)
03515
03516 #define sh_elf_local_got_tls_type(abfd) \
03517 (sh_elf_tdata (abfd)->local_got_tls_type)
03518
03519
03520
03521
03522 static bfd_boolean
03523 sh_elf_mkobject (bfd *abfd)
03524 {
03525 bfd_size_type amt = sizeof (struct sh_elf_obj_tdata);
03526 abfd->tdata.any = bfd_zalloc (abfd, amt);
03527 if (abfd->tdata.any == NULL)
03528 return FALSE;
03529 return TRUE;
03530 }
03531
03532
03533
03534 struct elf_sh_link_hash_table
03535 {
03536 struct elf_link_hash_table root;
03537
03538
03539 asection *sgot;
03540 asection *sgotplt;
03541 asection *srelgot;
03542 asection *splt;
03543 asection *srelplt;
03544 asection *sdynbss;
03545 asection *srelbss;
03546
03547
03548 struct sym_sec_cache sym_sec;
03549
03550
03551 union
03552 {
03553 bfd_signed_vma refcount;
03554 bfd_vma offset;
03555 } tls_ldm_got;
03556 };
03557
03558
03559
03560 #define sh_elf_link_hash_traverse(table, func, info) \
03561 (elf_link_hash_traverse \
03562 (&(table)->root, \
03563 (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func), \
03564 (info)))
03565
03566
03567
03568 #define sh_elf_hash_table(p) \
03569 ((struct elf_sh_link_hash_table *) ((p)->hash))
03570
03571
03572
03573 static struct bfd_hash_entry *
03574 sh_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
03575 struct bfd_hash_table *table,
03576 const char *string)
03577 {
03578 struct elf_sh_link_hash_entry *ret =
03579 (struct elf_sh_link_hash_entry *) entry;
03580
03581
03582
03583 if (ret == (struct elf_sh_link_hash_entry *) NULL)
03584 ret = ((struct elf_sh_link_hash_entry *)
03585 bfd_hash_allocate (table,
03586 sizeof (struct elf_sh_link_hash_entry)));
03587 if (ret == (struct elf_sh_link_hash_entry *) NULL)
03588 return (struct bfd_hash_entry *) ret;
03589
03590
03591 ret = ((struct elf_sh_link_hash_entry *)
03592 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
03593 table, string));
03594 if (ret != (struct elf_sh_link_hash_entry *) NULL)
03595 {
03596 ret->dyn_relocs = NULL;
03597 ret->gotplt_refcount = 0;
03598 #ifdef INCLUDE_SHMEDIA
03599 ret->datalabel_got.refcount = ret->root.got.refcount;
03600 #endif
03601 ret->tls_type = GOT_UNKNOWN;
03602 }
03603
03604 return (struct bfd_hash_entry *) ret;
03605 }
03606
03607
03608
03609 static struct bfd_link_hash_table *
03610 sh_elf_link_hash_table_create (bfd *abfd)
03611 {
03612 struct elf_sh_link_hash_table *ret;
03613 bfd_size_type amt = sizeof (struct elf_sh_link_hash_table);
03614
03615 ret = (struct elf_sh_link_hash_table *) bfd_malloc (amt);
03616 if (ret == (struct elf_sh_link_hash_table *) NULL)
03617 return NULL;
03618
03619 if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
03620 sh_elf_link_hash_newfunc))
03621 {
03622 free (ret);
03623 return NULL;
03624 }
03625
03626 ret->sgot = NULL;
03627 ret->sgotplt = NULL;
03628 ret->srelgot = NULL;
03629 ret->splt = NULL;
03630 ret->srelplt = NULL;
03631 ret->sdynbss = NULL;
03632 ret->srelbss = NULL;
03633 ret->sym_sec.abfd = NULL;
03634 ret->tls_ldm_got.refcount = 0;
03635
03636 return &ret->root.root;
03637 }
03638
03639
03640
03641
03642 static bfd_boolean
03643 create_got_section (bfd *dynobj, struct bfd_link_info *info)
03644 {
03645 struct elf_sh_link_hash_table *htab;
03646
03647 if (! _bfd_elf_create_got_section (dynobj, info))
03648 return FALSE;
03649
03650 htab = sh_elf_hash_table (info);
03651 htab->sgot = bfd_get_section_by_name (dynobj, ".got");
03652 htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
03653 if (! htab->sgot || ! htab->sgotplt)
03654 abort ();
03655
03656 htab->srelgot = bfd_make_section (dynobj, ".rela.got");
03657 if (htab->srelgot == NULL
03658 || ! bfd_set_section_flags (dynobj, htab->srelgot,
03659 (SEC_ALLOC
03660 | SEC_LOAD
03661 | SEC_HAS_CONTENTS
03662 | SEC_IN_MEMORY
03663 | SEC_LINKER_CREATED
03664 | SEC_READONLY))
03665 || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
03666 return FALSE;
03667 return TRUE;
03668 }
03669
03670
03671
03672 static bfd_boolean
03673 sh_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
03674 {
03675 struct elf_sh_link_hash_table *htab;
03676 flagword flags, pltflags;
03677 register asection *s;
03678 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
03679 int ptralign = 0;
03680
03681 switch (bed->s->arch_size)
03682 {
03683 case 32:
03684 ptralign = 2;
03685 break;
03686
03687 case 64:
03688 ptralign = 3;
03689 break;
03690
03691 default:
03692 bfd_set_error (bfd_error_bad_value);
03693 return FALSE;
03694 }
03695
03696 htab = sh_elf_hash_table (info);
03697 if (htab->root.dynamic_sections_created)
03698 return TRUE;
03699
03700
03701
03702
03703 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
03704 | SEC_LINKER_CREATED);
03705
03706 pltflags = flags;
03707 pltflags |= SEC_CODE;
03708 if (bed->plt_not_loaded)
03709 pltflags &= ~ (SEC_LOAD | SEC_HAS_CONTENTS);
03710 if (bed->plt_readonly)
03711 pltflags |= SEC_READONLY;
03712
03713 s = bfd_make_section (abfd, ".plt");
03714 htab->splt = s;
03715 if (s == NULL
03716 || ! bfd_set_section_flags (abfd, s, pltflags)
03717 || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
03718 return FALSE;
03719
03720 if (bed->want_plt_sym)
03721 {
03722
03723
03724 struct elf_link_hash_entry *h;
03725 struct bfd_link_hash_entry *bh = NULL;
03726
03727 if (! (_bfd_generic_link_add_one_symbol
03728 (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
03729 (bfd_vma) 0, (const char *) NULL, FALSE,
03730 get_elf_backend_data (abfd)->collect, &bh)))
03731 return FALSE;
03732
03733 h = (struct elf_link_hash_entry *) bh;
03734 h->def_regular = 1;
03735 h->type = STT_OBJECT;
03736
03737 if (info->shared
03738 && ! bfd_elf_link_record_dynamic_symbol (info, h))
03739 return FALSE;
03740 }
03741
03742 s = bfd_make_section (abfd,
03743 bed->default_use_rela_p ? ".rela.plt" : ".rel.plt");
03744 htab->srelplt = s;
03745 if (s == NULL
03746 || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
03747 || ! bfd_set_section_alignment (abfd, s, ptralign))
03748 return FALSE;
03749
03750 if (htab->sgot == NULL
03751 && !create_got_section (abfd, info))
03752 return FALSE;
03753
03754 {
03755 const char *secname;
03756 char *relname;
03757 flagword secflags;
03758 asection *sec;
03759
03760 for (sec = abfd->sections; sec; sec = sec->next)
03761 {
03762 secflags = bfd_get_section_flags (abfd, sec);
03763 if ((secflags & (SEC_DATA | SEC_LINKER_CREATED))
03764 || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS))
03765 continue;
03766 secname = bfd_get_section_name (abfd, sec);
03767 relname = (char *) bfd_malloc ((bfd_size_type) strlen (secname) + 6);
03768 strcpy (relname, ".rela");
03769 strcat (relname, secname);
03770 if (bfd_get_section_by_name (abfd, secname))
03771 continue;
03772 s = bfd_make_section (abfd, relname);
03773 if (s == NULL
03774 || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
03775 || ! bfd_set_section_alignment (abfd, s, ptralign))
03776 return FALSE;
03777 }
03778 }
03779
03780 if (bed->want_dynbss)
03781 {
03782
03783
03784
03785
03786
03787
03788 s = bfd_make_section (abfd, ".dynbss");
03789 htab->sdynbss = s;
03790 if (s == NULL
03791 || ! bfd_set_section_flags (abfd, s, SEC_ALLOC))
03792 return FALSE;
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805 if (! info->shared)
03806 {
03807 s = bfd_make_section (abfd,
03808 (bed->default_use_rela_p
03809 ? ".rela.bss" : ".rel.bss"));
03810 htab->srelbss = s;
03811 if (s == NULL
03812 || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
03813 || ! bfd_set_section_alignment (abfd, s, ptralign))
03814 return FALSE;
03815 }
03816 }
03817
03818 return TRUE;
03819 }
03820
03821
03822
03823
03824
03825
03826
03827 static bfd_boolean
03828 sh_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
03829 struct elf_link_hash_entry *h)
03830 {
03831 struct elf_sh_link_hash_table *htab;
03832 struct elf_sh_link_hash_entry *eh;
03833 struct elf_sh_dyn_relocs *p;
03834 asection *s;
03835 unsigned int power_of_two;
03836
03837 htab = sh_elf_hash_table (info);
03838
03839
03840 BFD_ASSERT (htab->root.dynobj != NULL
03841 && (h->needs_plt
03842 || h->u.weakdef != NULL
03843 || (h->def_dynamic
03844 && h->ref_regular
03845 && !h->def_regular)));
03846
03847
03848
03849
03850 if (h->type == STT_FUNC
03851 || h->needs_plt)
03852 {
03853 if (h->plt.refcount <= 0
03854 || SYMBOL_CALLS_LOCAL (info, h)
03855 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
03856 && h->root.type == bfd_link_hash_undefweak))
03857 {
03858
03859
03860
03861
03862
03863 h->plt.offset = (bfd_vma) -1;
03864 h->needs_plt = 0;
03865 }
03866
03867 return TRUE;
03868 }
03869 else
03870 h->plt.offset = (bfd_vma) -1;
03871
03872
03873
03874
03875 if (h->u.weakdef != NULL)
03876 {
03877 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
03878 || h->u.weakdef->root.type == bfd_link_hash_defweak);
03879 h->root.u.def.section = h->u.weakdef->root.u.def.section;
03880 h->root.u.def.value = h->u.weakdef->root.u.def.value;
03881 if (info->nocopyreloc)
03882 h->non_got_ref = h->u.weakdef->non_got_ref;
03883 return TRUE;
03884 }
03885
03886
03887
03888
03889
03890
03891
03892
03893 if (info->shared)
03894 return TRUE;
03895
03896
03897
03898 if (!h->non_got_ref)
03899 return TRUE;
03900
03901
03902 if (info->nocopyreloc)
03903 {
03904 h->non_got_ref = 0;
03905 return TRUE;
03906 }
03907
03908 eh = (struct elf_sh_link_hash_entry *) h;
03909 for (p = eh->dyn_relocs; p != NULL; p = p->next)
03910 {
03911 s = p->sec->output_section;
03912 if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
03913 break;
03914 }
03915
03916
03917
03918
03919 if (p == NULL)
03920 {
03921 h->non_got_ref = 0;
03922 return TRUE;
03923 }
03924
03925
03926
03927
03928
03929
03930
03931
03932
03933
03934
03935 s = htab->sdynbss;
03936 BFD_ASSERT (s != NULL);
03937
03938
03939
03940
03941
03942 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
03943 {
03944 asection *srel;
03945
03946 srel = htab->srelbss;
03947 BFD_ASSERT (srel != NULL);
03948 srel->size += sizeof (Elf32_External_Rela);
03949 h->needs_copy = 1;
03950 }
03951
03952
03953
03954 power_of_two = bfd_log2 (h->size);
03955 if (power_of_two > 3)
03956 power_of_two = 3;
03957
03958
03959 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
03960 if (power_of_two > bfd_get_section_alignment (htab->root.dynobj, s))
03961 {
03962 if (! bfd_set_section_alignment (htab->root.dynobj, s, power_of_two))
03963 return FALSE;
03964 }
03965
03966
03967 h->root.u.def.section = s;
03968 h->root.u.def.value = s->size;
03969
03970
03971 s->size += h->size;
03972
03973 return TRUE;
03974 }
03975
03976
03977
03978
03979 static bfd_boolean
03980 allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
03981 {
03982 struct bfd_link_info *info;
03983 struct elf_sh_link_hash_table *htab;
03984 struct elf_sh_link_hash_entry *eh;
03985 struct elf_sh_dyn_relocs *p;
03986
03987 if (h->root.type == bfd_link_hash_indirect)
03988 return TRUE;
03989
03990 if (h->root.type == bfd_link_hash_warning)
03991
03992
03993
03994 h = (struct elf_link_hash_entry *) h->root.u.i.link;
03995
03996 info = (struct bfd_link_info *) inf;
03997 htab = sh_elf_hash_table (info);
03998
03999 eh = (struct elf_sh_link_hash_entry *) h;
04000 if ((h->got.refcount > 0
04001 || h->forced_local)
04002 && eh->gotplt_refcount > 0)
04003 {
04004
04005
04006 h->got.refcount += eh->gotplt_refcount;
04007 if (h->plt.refcount >= eh->gotplt_refcount)
04008 h->plt.refcount -= eh->gotplt_refcount;
04009 }
04010
04011 if (htab->root.dynamic_sections_created
04012 && h->plt.refcount > 0
04013 && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
04014 || h->root.type != bfd_link_hash_undefweak))
04015 {
04016
04017
04018 if (h->dynindx == -1
04019 && !h->forced_local)
04020 {
04021 if (! bfd_elf_link_record_dynamic_symbol (info, h))
04022 return FALSE;
04023 }
04024
04025 if (info->shared
04026 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
04027 {
04028 asection *s = htab->splt;
04029
04030
04031
04032 if (s->size == 0)
04033 s->size += PLT_ENTRY_SIZE;
04034
04035 h->plt.offset = s->size;
04036
04037
04038
04039
04040
04041
04042 if (! info->shared
04043 && !h->def_regular)
04044 {
04045 h->root.u.def.section = s;
04046 h->root.u.def.value = h->plt.offset;
04047 }
04048
04049
04050 s->size += PLT_ENTRY_SIZE;
04051
04052
04053
04054 htab->sgotplt->size += 4;
04055
04056
04057 htab->srelplt->size += sizeof (Elf32_External_Rela);
04058 }
04059 else
04060 {
04061 h->plt.offset = (bfd_vma) -1;
04062 h->needs_plt = 0;
04063 }
04064 }
04065 else
04066 {
04067 h->plt.offset = (bfd_vma) -1;
04068 h->needs_plt = 0;
04069 }
04070
04071 if (h->got.refcount > 0)
04072 {
04073 asection *s;
04074 bfd_boolean dyn;
04075 int tls_type = sh_elf_hash_entry (h)->tls_type;
04076
04077
04078
04079 if (h->dynindx == -1
04080 && !h->forced_local)
04081 {
04082 if (! bfd_elf_link_record_dynamic_symbol (info, h))
04083 return FALSE;
04084 }
04085
04086 s = htab->sgot;
04087 h->got.offset = s->size;
04088 s->size += 4;
04089
04090 if (tls_type == GOT_TLS_GD)
04091 s->size += 4;
04092 dyn = htab->root.dynamic_sections_created;
04093
04094
04095 if ((tls_type == GOT_TLS_GD && h->dynindx == -1)
04096 || (tls_type == GOT_TLS_IE && dyn))
04097 htab->srelgot->size += sizeof (Elf32_External_Rela);
04098 else if (tls_type == GOT_TLS_GD)
04099 htab->srelgot->size += 2 * sizeof (Elf32_External_Rela);
04100 else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
04101 || h->root.type != bfd_link_hash_undefweak)
04102 && (info->shared
04103 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
04104 htab->srelgot->size += sizeof (Elf32_External_Rela);
04105 }
04106 else
04107 h->got.offset = (bfd_vma) -1;
04108
04109 #ifdef INCLUDE_SHMEDIA
04110 if (eh->datalabel_got.refcount > 0)
04111 {
04112 asection *s;
04113 bfd_boolean dyn;
04114
04115
04116
04117 if (h->dynindx == -1
04118 && !h->forced_local)
04119 {
04120 if (! bfd_elf_link_record_dynamic_symbol (info, h))
04121 return FALSE;
04122 }
04123
04124 s = htab->sgot;
04125 eh->datalabel_got.offset = s->size;
04126 s->size += 4;
04127 dyn = htab->root.dynamic_sections_created;
04128 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h))
04129 htab->srelgot->size += sizeof (Elf32_External_Rela);
04130 }
04131 else
04132 eh->datalabel_got.offset = (bfd_vma) -1;
04133 #endif
04134
04135 if (eh->dyn_relocs == NULL)
04136 return TRUE;
04137
04138
04139
04140
04141
04142
04143
04144 if (info->shared)
04145 {
04146 if (SYMBOL_CALLS_LOCAL (info, h))
04147 {
04148 struct elf_sh_dyn_relocs **pp;
04149
04150 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
04151 {
04152 p->count -= p->pc_count;
04153 p->pc_count = 0;
04154 if (p->count == 0)
04155 *pp = p->next;
04156 else
04157 pp = &p->next;
04158 }
04159 }
04160
04161
04162
04163 if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
04164 && h->root.type == bfd_link_hash_undefweak)
04165 eh->dyn_relocs = NULL;
04166 }
04167 else
04168 {
04169
04170
04171
04172
04173 if (!h->non_got_ref
04174 && ((h->def_dynamic
04175 && !h->def_regular)
04176 || (htab->root.dynamic_sections_created
04177 && (h->root.type == bfd_link_hash_undefweak
04178 || h->root.type == bfd_link_hash_undefined))))
04179 {
04180
04181
04182 if (h->dynindx == -1
04183 && !h->forced_local)
04184 {
04185 if (! bfd_elf_link_record_dynamic_symbol (info, h))
04186 return FALSE;
04187 }
04188
04189
04190
04191 if (h->dynindx != -1)
04192 goto keep;
04193 }
04194
04195 eh->dyn_relocs = NULL;
04196
04197 keep: ;
04198 }
04199
04200
04201 for (p = eh->dyn_relocs; p != NULL; p = p->next)
04202 {
04203 asection *sreloc = elf_section_data (p->sec)->sreloc;
04204 sreloc->size += p->count * sizeof (Elf32_External_Rela);
04205 }
04206
04207 return TRUE;
04208 }
04209
04210
04211
04212 static bfd_boolean
04213 readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
04214 {
04215 struct elf_sh_link_hash_entry *eh;
04216 struct elf_sh_dyn_relocs *p;
04217
04218 if (h->root.type == bfd_link_hash_warning)
04219 h = (struct elf_link_hash_entry *) h->root.u.i.link;
04220
04221 eh = (struct elf_sh_link_hash_entry *) h;
04222 for (p = eh->dyn_relocs; p != NULL; p = p->next)
04223 {
04224 asection *s = p->sec->output_section;
04225
04226 if (s != NULL && (s->flags & SEC_READONLY) != 0)
04227 {
04228 struct bfd_link_info *info = (struct bfd_link_info *) inf;
04229
04230 info->flags |= DF_TEXTREL;
04231
04232
04233 return FALSE;
04234 }
04235 }
04236 return TRUE;
04237 }
04238
04239
04240
04241 static bfd_boolean
04242 sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
04243 struct bfd_link_info *info)
04244 {
04245 struct elf_sh_link_hash_table *htab;
04246 bfd *dynobj;
04247 asection *s;
04248 bfd_boolean relocs;
04249 bfd *ibfd;
04250
04251 htab = sh_elf_hash_table (info);
04252 dynobj = htab->root.dynobj;
04253 BFD_ASSERT (dynobj != NULL);
04254
04255 if (htab->root.dynamic_sections_created)
04256 {
04257
04258 if (info->executable)
04259 {
04260 s = bfd_get_section_by_name (dynobj, ".interp");
04261 BFD_ASSERT (s != NULL);
04262 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
04263 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
04264 }
04265 }
04266
04267
04268
04269 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
04270 {
04271 bfd_signed_vma *local_got;
04272 bfd_signed_vma *end_local_got;
04273 char *local_tls_type;
04274 bfd_size_type locsymcount;
04275 Elf_Internal_Shdr *symtab_hdr;
04276 asection *srel;
04277
04278 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
04279 continue;
04280
04281 for (s = ibfd->sections; s != NULL; s = s->next)
04282 {
04283 struct elf_sh_dyn_relocs *p;
04284
04285 for (p = ((struct elf_sh_dyn_relocs *)
04286 elf_section_data (s)->local_dynrel);
04287 p != NULL;
04288 p = p->next)
04289 {
04290 if (! bfd_is_abs_section (p->sec)
04291 && bfd_is_abs_section (p->sec->output_section))
04292 {
04293
04294
04295
04296
04297 }
04298 else if (p->count != 0)
04299 {
04300 srel = elf_section_data (p->sec)->sreloc;
04301 srel->size += p->count * sizeof (Elf32_External_Rela);
04302 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
04303 info->flags |= DF_TEXTREL;
04304 }
04305 }
04306 }
04307
04308 local_got = elf_local_got_refcounts (ibfd);
04309 if (!local_got)
04310 continue;
04311
04312 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
04313 locsymcount = symtab_hdr->sh_info;
04314 #ifdef INCLUDE_SHMEDIA
04315
04316 locsymcount *= 2;
04317 #endif
04318 end_local_got = local_got + locsymcount;
04319 local_tls_type = sh_elf_local_got_tls_type (ibfd);
04320 s = htab->sgot;
04321 srel = htab->srelgot;
04322 for (; local_got < end_local_got; ++local_got)
04323 {
04324 if (*local_got > 0)
04325 {
04326 *local_got = s->size;
04327 s->size += 4;
04328 if (*local_tls_type == GOT_TLS_GD)
04329 s->size += 4;
04330 if (info->shared)
04331 srel->size += sizeof (Elf32_External_Rela);
04332 }
04333 else
04334 *local_got = (bfd_vma) -1;
04335 ++local_tls_type;
04336 }
04337 }
04338
04339 if (htab->tls_ldm_got.refcount > 0)
04340 {
04341
04342
04343 htab->tls_ldm_got.offset = htab->sgot->size;
04344 htab->sgot->size += 8;
04345 htab->srelgot->size += sizeof (Elf32_External_Rela);
04346 }
04347 else
04348 htab->tls_ldm_got.offset = -1;
04349
04350
04351
04352 elf_link_hash_traverse (&htab->root, allocate_dynrelocs, info);
04353
04354
04355
04356 relocs = FALSE;
04357 for (s = dynobj->sections; s != NULL; s = s->next)
04358 {
04359 if ((s->flags & SEC_LINKER_CREATED) == 0)
04360 continue;
04361
04362 if (s == htab->splt
04363 || s == htab->sgot
04364 || s == htab->sgotplt)
04365 {
04366
04367
04368 }
04369 else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
04370 {
04371 if (s->size != 0 && s != htab->srelplt)
04372 relocs = TRUE;
04373
04374
04375
04376 s->reloc_count = 0;
04377 }
04378 else
04379 {
04380
04381 continue;
04382 }
04383
04384 if (s->size == 0)
04385 {
04386
04387
04388
04389
04390
04391
04392
04393
04394
04395
04396 _bfd_strip_section_from_output (info, s);
04397 continue;
04398 }
04399
04400
04401
04402
04403
04404
04405 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
04406 if (s->contents == NULL)
04407 return FALSE;
04408 }
04409
04410 if (htab->root.dynamic_sections_created)
04411 {
04412
04413
04414
04415
04416
04417 #define add_dynamic_entry(TAG, VAL) \
04418 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
04419
04420 if (info->executable)
04421 {
04422 if (! add_dynamic_entry (DT_DEBUG, 0))
04423 return FALSE;
04424 }
04425
04426 if (htab->splt->size != 0)
04427 {
04428 if (! add_dynamic_entry (DT_PLTGOT, 0)
04429 || ! add_dynamic_entry (DT_PLTRELSZ, 0)
04430 || ! add_dynamic_entry (DT_PLTREL, DT_RELA)
04431 || ! add_dynamic_entry (DT_JMPREL, 0))
04432 return FALSE;
04433 }
04434
04435 if (relocs)
04436 {
04437 if (! add_dynamic_entry (DT_RELA, 0)
04438 || ! add_dynamic_entry (DT_RELASZ, 0)
04439 || ! add_dynamic_entry (DT_RELAENT,
04440 sizeof (Elf32_External_Rela)))
04441 return FALSE;
04442
04443
04444
04445 if ((info->flags & DF_TEXTREL) == 0)
04446 elf_link_hash_traverse (&htab->root, readonly_dynrelocs, info);
04447
04448 if ((info->flags & DF_TEXTREL) != 0)
04449 {
04450 if (! add_dynamic_entry (DT_TEXTREL, 0))
04451 return FALSE;
04452 }
04453 }
04454 }
04455 #undef add_dynamic_entry
04456
04457 return TRUE;
04458 }
04459
04460
04461
04462 static bfd_boolean
04463 sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
04464 bfd *input_bfd, asection *input_section,
04465 bfd_byte *contents, Elf_Internal_Rela *relocs,
04466 Elf_Internal_Sym *local_syms,
04467 asection **local_sections)
04468 {
04469 struct elf_sh_link_hash_table *htab;
04470 Elf_Internal_Shdr *symtab_hdr;
04471 struct elf_link_hash_entry **sym_hashes;
04472 Elf_Internal_Rela *rel, *relend;
04473 bfd *dynobj;
04474 bfd_vma *local_got_offsets;
04475 asection *sgot;
04476 asection *sgotplt;
04477 asection *splt;
04478 asection *sreloc;
04479 asection *srelgot;
04480
04481 htab = sh_elf_hash_table (info);
04482 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
04483 sym_hashes = elf_sym_hashes (input_bfd);
04484 dynobj = htab->root.dynobj;
04485 local_got_offsets = elf_local_got_offsets (input_bfd);
04486
04487 sgot = htab->sgot;
04488 sgotplt = htab->sgotplt;
04489 splt = htab->splt;
04490 sreloc = NULL;
04491 srelgot = NULL;
04492
04493 rel = relocs;
04494 relend = relocs + input_section->reloc_count;
04495 for (; rel < relend; rel++)
04496 {
04497 int r_type;
04498 reloc_howto_type *howto;
04499 unsigned long r_symndx;
04500 Elf_Internal_Sym *sym;
04501 asection *sec;
04502 struct elf_link_hash_entry *h;
04503 bfd_vma relocation;
04504 bfd_vma addend = (bfd_vma) 0;
04505 bfd_reloc_status_type r;
04506 int seen_stt_datalabel = 0;
04507 bfd_vma off;
04508 int tls_type;
04509
04510 r_symndx = ELF32_R_SYM (rel->r_info);
04511
04512 r_type = ELF32_R_TYPE (rel->r_info);
04513
04514
04515
04516 if (r_type >= (int) R_SH_GNU_VTINHERIT
04517 && r_type <= (int) R_SH_LABEL)
04518 continue;
04519 if (r_type == (int) R_SH_NONE)
04520 continue;
04521
04522 if (r_type < 0
04523 || r_type >= R_SH_max
04524 || (r_type >= (int) R_SH_FIRST_INVALID_RELOC
04525 && r_type <= (int) R_SH_LAST_INVALID_RELOC)
04526 || ( r_type >= (int) R_SH_FIRST_INVALID_RELOC_3
04527 && r_type <= (int) R_SH_LAST_INVALID_RELOC_3)
04528 || ( r_type >= (int) R_SH_FIRST_INVALID_RELOC_4
04529 && r_type <= (int) R_SH_LAST_INVALID_RELOC_4)
04530 || ( r_type >= (int) R_SH_FIRST_INVALID_RELOC_5
04531 && r_type <= (int) R_SH_LAST_INVALID_RELOC_5)
04532 || (r_type >= (int) R_SH_FIRST_INVALID_RELOC_2
04533 && r_type <= (int) R_SH_LAST_INVALID_RELOC_2))
04534 {
04535 bfd_set_error (bfd_error_bad_value);
04536 return FALSE;
04537 }
04538
04539 howto = sh_elf_howto_table + r_type;
04540
04541
04542
04543 if (! howto->partial_inplace)
04544 addend = rel->r_addend;
04545
04546 h = NULL;
04547 sym = NULL;
04548 sec = NULL;
04549 if (r_symndx < symtab_hdr->sh_info)
04550 {
04551 sym = local_syms + r_symndx;
04552 sec = local_sections[r_symndx];
04553 relocation = (sec->output_section->vma
04554 + sec->output_offset
04555 + sym->st_value);
04556
04557
04558
04559 if ((sym->st_other & STO_SH5_ISA32) != 0)
04560 ((*info->callbacks->reloc_dangerous)
04561 (info,
04562 _("Unexpected STO_SH5_ISA32 on local symbol is not handled"),
04563 input_bfd, input_section, rel->r_offset));
04564 if (info->relocatable)
04565 {
04566
04567
04568
04569
04570 sym = local_syms + r_symndx;
04571 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
04572 {
04573 if (! howto->partial_inplace)
04574 {
04575
04576
04577
04578
04579 rel->r_addend += sec->output_offset + sym->st_value;
04580
04581 continue;
04582 }
04583
04584
04585
04586
04587
04588
04589
04590
04591
04592 r = _bfd_relocate_contents (howto, input_bfd,
04593 sec->output_offset
04594 + sym->st_value,
04595 contents + rel->r_offset);
04596 goto relocation_done;
04597 }
04598
04599 continue;
04600 }
04601 else if (! howto->partial_inplace)
04602 {
04603 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
04604 addend = rel->r_addend;
04605 }
04606 else if ((sec->flags & SEC_MERGE)
04607 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
04608 {
04609 asection *msec;
04610
04611 if (howto->rightshift || howto->src_mask != 0xffffffff)
04612 {
04613 (*_bfd_error_handler)
04614 (_("%B(%A+0x%lx): %s relocation against SEC_MERGE section"),
04615 input_bfd, input_section,
04616 (long) rel->r_offset, howto->name);
04617 return FALSE;
04618 }
04619
04620 addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
04621 msec = sec;
04622 addend =
04623 _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend)
04624 - relocation;
04625 addend += msec->output_section->vma + msec->output_offset;
04626 bfd_put_32 (input_bfd, addend, contents + rel->r_offset);
04627 addend = 0;
04628 }
04629 }
04630 else
04631 {
04632
04633
04634
04635
04636
04637 if (info->relocatable)
04638 continue;
04639
04640 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
04641 while (h->root.type == bfd_link_hash_indirect
04642 || h->root.type == bfd_link_hash_warning)
04643 {
04644 #ifdef INCLUDE_SHMEDIA
04645
04646
04647
04648 seen_stt_datalabel |= h->type == STT_DATALABEL;
04649 #endif
04650 h = (struct elf_link_hash_entry *) h->root.u.i.link;
04651 }
04652 if (h->root.type == bfd_link_hash_defined
04653 || h->root.type == bfd_link_hash_defweak)
04654 {
04655 bfd_boolean dyn;
04656
04657 dyn = htab->root.dynamic_sections_created;
04658 sec = h->root.u.def.section;
04659
04660
04661
04662 if (r_type == R_SH_GOTPC
04663 || r_type == R_SH_GOTPC_LOW16
04664 || r_type == R_SH_GOTPC_MEDLOW16
04665 || r_type == R_SH_GOTPC_MEDHI16
04666 || r_type == R_SH_GOTPC_HI16
04667 || ((r_type == R_SH_PLT32
04668 || r_type == R_SH_PLT_LOW16
04669 || r_type == R_SH_PLT_MEDLOW16
04670 || r_type == R_SH_PLT_MEDHI16
04671 || r_type == R_SH_PLT_HI16)
04672 && h->plt.offset != (bfd_vma) -1)
04673 || ((r_type == R_SH_GOT32
04674 || r_type == R_SH_GOT_LOW16
04675 || r_type == R_SH_GOT_MEDLOW16
04676 || r_type == R_SH_GOT_MEDHI16
04677 || r_type == R_SH_GOT_HI16)
04678 && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
04679 && (! info->shared
04680 || (! info->symbolic && h->dynindx != -1)
04681 || !h->def_regular))
04682
04683
04684
04685
04686
04687 || (info->shared
04688 && ((! info->symbolic && h->dynindx != -1)
04689 || !h->def_regular)
04690 && ((r_type == R_SH_DIR32
04691 && !h->forced_local)
04692 || r_type == R_SH_REL32)
04693 && ((input_section->flags & SEC_ALLOC) != 0
04694
04695
04696
04697
04698 || ((input_section->flags & SEC_DEBUGGING) != 0
04699 && h->def_dynamic)))
04700
04701
04702
04703 || (sec->output_section == NULL
04704 && ((input_section->flags & SEC_DEBUGGING) != 0
04705 && h->def_dynamic))
04706 || (sec->output_section == NULL
04707 && (sh_elf_hash_entry (h)->tls_type == GOT_TLS_IE
04708 || sh_elf_hash_entry (h)->tls_type == GOT_TLS_GD)))
04709 relocation = 0;
04710 else if (sec->output_section == NULL)
04711 {
04712 (*_bfd_error_handler)
04713 (_("%B(%A): unresolvable relocation against symbol `%s'"),
04714 input_bfd, input_section, h->root.root.string);
04715 return FALSE;
04716 }
04717 else
04718 relocation = ((h->root.u.def.value
04719 + sec->output_section->vma
04720 + sec->output_offset)
04721
04722
04723
04724 | ((h->other & STO_SH5_ISA32) != 0
04725 && ! seen_stt_datalabel));
04726 }
04727 else if (h->root.type == bfd_link_hash_undefweak)
04728 relocation = 0;
04729 else if (info->unresolved_syms_in_objects == RM_IGNORE
04730 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
04731 relocation = 0;
04732 else
04733 {
04734 if (! info->callbacks->undefined_symbol
04735 (info, h->root.root.string, input_bfd,
04736 input_section, rel->r_offset,
04737 (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
04738 || ELF_ST_VISIBILITY (h->other))))
04739 return FALSE;
04740 relocation = 0;
04741 }
04742 }
04743
04744 switch ((int) r_type)
04745 {
04746 final_link_relocate:
04747
04748
04749 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
04750 contents, rel->r_offset,
04751 relocation, addend);
04752 break;
04753
04754 case R_SH_IND12W:
04755 goto final_link_relocate;
04756
04757 case R_SH_DIR8WPN:
04758 case R_SH_DIR8WPZ:
04759 case R_SH_DIR8WPL:
04760
04761
04762
04763
04764
04765 if (input_section->output_section->vma + input_section->output_offset
04766 != relocation)
04767 {
04768 int disp = (relocation
04769 - input_section->output_section->vma
04770 - input_section->output_offset
04771 - rel->r_offset);
04772 int mask = 0;
04773 switch (r_type)
04774 {
04775 case R_SH_DIR8WPN:
04776 case R_SH_DIR8WPZ: mask = 1; break;
04777 case R_SH_DIR8WPL: mask = 3; break;
04778 default: mask = 0; break;
04779 }
04780 if (disp & mask)
04781 {
04782 ((*_bfd_error_handler)
04783 (_("%B: 0x%lx: fatal: unaligned branch target for relax-support relocation"),
04784 input_section->owner,
04785 (unsigned long) rel->r_offset));
04786 bfd_set_error (bfd_error_bad_value);
04787 return FALSE;
04788 }
04789 relocation -= 4;
04790 goto final_link_relocate;
04791 }
04792 r = bfd_reloc_ok;
04793 break;
04794
04795 default:
04796 #ifdef INCLUDE_SHMEDIA
04797 if (shmedia_prepare_reloc (info, input_bfd, input_section,
04798 contents, rel, &relocation))
04799 goto final_link_relocate;
04800 #endif
04801 bfd_set_error (bfd_error_bad_value);
04802 return FALSE;
04803
04804 case R_SH_DIR16:
04805 case R_SH_DIR8:
04806 case R_SH_DIR8U:
04807 case R_SH_DIR8S:
04808 case R_SH_DIR4U:
04809 goto final_link_relocate;
04810
04811 case R_SH_DIR8UL:
04812 case R_SH_DIR4UL:
04813 if (relocation & 3)
04814 {
04815 ((*_bfd_error_handler)
04816 (_("%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"),
04817 input_section->owner,
04818 (unsigned long) rel->r_offset, howto->name,
04819 (unsigned long) relocation));
04820 bfd_set_error (bfd_error_bad_value);
04821 return FALSE;
04822 }
04823 goto final_link_relocate;
04824
04825 case R_SH_DIR8UW:
04826 case R_SH_DIR8SW:
04827 case R_SH_DIR4UW:
04828 if (relocation & 1)
04829 {
04830 ((*_bfd_error_handler)
04831 (_("%B: 0x%lx: fatal: unaligned %s relocation 0x%lx"),
04832 input_section->owner,
04833 (unsigned long) rel->r_offset, howto->name,
04834 (unsigned long) relocation));
04835 bfd_set_error (bfd_error_bad_value);
04836 return FALSE;
04837 }
04838 goto final_link_relocate;
04839
04840 case R_SH_PSHA:
04841 if ((signed int)relocation < -32
04842 || (signed int)relocation > 32)
04843 {
04844 ((*_bfd_error_handler)
04845 (_("%B: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32"),
04846 input_section->owner,
04847 (unsigned long) rel->r_offset,
04848 (unsigned long) relocation));
04849 bfd_set_error (bfd_error_bad_value);
04850 return FALSE;
04851 }
04852 goto final_link_relocate;
04853
04854 case R_SH_PSHL:
04855 if ((signed int)relocation < -16
04856 || (signed int)relocation > 16)
04857 {
04858 ((*_bfd_error_handler)
04859 (_("%B: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"),
04860 input_section->owner,
04861 (unsigned long) rel->r_offset,
04862 (unsigned long) relocation));
04863 bfd_set_error (bfd_error_bad_value);
04864 return FALSE;
04865 }
04866 goto final_link_relocate;
04867
04868 case R_SH_DIR32:
04869 case R_SH_REL32:
04870 #ifdef INCLUDE_SHMEDIA
04871 case R_SH_IMM_LOW16_PCREL:
04872 case R_SH_IMM_MEDLOW16_PCREL:
04873 case R_SH_IMM_MEDHI16_PCREL:
04874 case R_SH_IMM_HI16_PCREL:
04875 #endif
04876 if (info->shared
04877 && (h == NULL
04878 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
04879 || h->root.type != bfd_link_hash_undefweak)
04880 && r_symndx != 0
04881 && (input_section->flags & SEC_ALLOC) != 0
04882 && (r_type == R_SH_DIR32
04883 || !SYMBOL_CALLS_LOCAL (info, h)))
04884 {
04885 Elf_Internal_Rela outrel;
04886 bfd_byte *loc;
04887 bfd_boolean skip, relocate;
04888
04889
04890
04891
04892
04893 if (sreloc == NULL)
04894 {
04895 const char *name;
04896
04897 name = (bfd_elf_string_from_elf_section
04898 (input_bfd,
04899 elf_elfheader (input_bfd)->e_shstrndx,
04900 elf_section_data (input_section)->rel_hdr.sh_name));
04901 if (name == NULL)
04902 return FALSE;
04903
04904 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
04905 && strcmp (bfd_get_section_name (input_bfd,
04906 input_section),
04907 name + 5) == 0);
04908
04909 sreloc = bfd_get_section_by_name (dynobj, name);
04910 BFD_ASSERT (sreloc != NULL);
04911 }
04912
04913 skip = FALSE;
04914 relocate = FALSE;
04915
04916 outrel.r_offset =
04917 _bfd_elf_section_offset (output_bfd, info, input_section,
04918 rel->r_offset);
04919 if (outrel.r_offset == (bfd_vma) -1)
04920 skip = TRUE;
04921 else if (outrel.r_offset == (bfd_vma) -2)
04922 skip = TRUE, relocate = TRUE;
04923 outrel.r_offset += (input_section->output_section->vma
04924 + input_section->output_offset);
04925
04926 if (skip)
04927 memset (&outrel, 0, sizeof outrel);
04928 else if (r_type == R_SH_REL32)
04929 {
04930 BFD_ASSERT (h != NULL && h->dynindx != -1);
04931 outrel.r_info = ELF32_R_INFO (h->dynindx, R_SH_REL32);
04932 outrel.r_addend
04933 = bfd_get_32 (input_bfd, contents + rel->r_offset);
04934 }
04935 #ifdef INCLUDE_SHMEDIA
04936 else if (r_type == R_SH_IMM_LOW16_PCREL
04937 || r_type == R_SH_IMM_MEDLOW16_PCREL
04938 || r_type == R_SH_IMM_MEDHI16_PCREL
04939 || r_type == R_SH_IMM_HI16_PCREL)
04940 {
04941 BFD_ASSERT (h != NULL && h->dynindx != -1);
04942 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
04943 outrel.r_addend = addend;
04944 }
04945 #endif
04946 else
04947 {
04948
04949
04950 if (h == NULL
04951 || ((info->symbolic || h->dynindx == -1)
04952 && h->def_regular))
04953 {
04954 relocate = TRUE;
04955 outrel.r_info = ELF32_R_INFO (0, R_SH_RELATIVE);
04956 outrel.r_addend
04957 = relocation + bfd_get_32 (input_bfd,
04958 contents + rel->r_offset);
04959 }
04960 else
04961 {
04962 BFD_ASSERT (h->dynindx != -1);
04963 outrel.r_info = ELF32_R_INFO (h->dynindx, R_SH_DIR32);
04964 outrel.r_addend
04965 = relocation + bfd_get_32 (input_bfd,
04966 contents + rel->r_offset);
04967 }
04968 }
04969
04970 loc = sreloc->contents;
04971 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
04972 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
04973
04974
04975
04976
04977
04978 if (! relocate)
04979 continue;
04980 }
04981 goto final_link_relocate;
04982
04983 case R_SH_GOTPLT32:
04984 #ifdef INCLUDE_SHMEDIA
04985 case R_SH_GOTPLT_LOW16:
04986 case R_SH_GOTPLT_MEDLOW16:
04987 case R_SH_GOTPLT_MEDHI16:
04988 case R_SH_GOTPLT_HI16:
04989 case R_SH_GOTPLT10BY4:
04990 case R_SH_GOTPLT10BY8:
04991 #endif
04992
04993
04994
04995 if (h == NULL
04996 || h->forced_local
04997 || ! info->shared
04998 || info->symbolic
04999 || h->dynindx == -1
05000 || h->plt.offset == (bfd_vma) -1
05001 || h->got.offset != (bfd_vma) -1)
05002 goto force_got;
05003
05004
05005
05006
05007 BFD_ASSERT (sgotplt != NULL);
05008 relocation = (sgotplt->output_offset
05009 + ((h->plt.offset / elf_sh_sizeof_plt (info)
05010 - 1 + 3) * 4));
05011
05012 #ifdef GOT_BIAS
05013 relocation -= GOT_BIAS;
05014 #endif
05015
05016 goto final_link_relocate;
05017
05018 force_got:
05019 case R_SH_GOT32:
05020 #ifdef INCLUDE_SHMEDIA
05021 case R_SH_GOT_LOW16:
05022 case R_SH_GOT_MEDLOW16:
05023 case R_SH_GOT_MEDHI16:
05024 case R_SH_GOT_HI16:
05025 case R_SH_GOT10BY4:
05026 case R_SH_GOT10BY8:
05027 #endif
05028
05029
05030
05031 BFD_ASSERT (sgot != NULL);
05032
05033 if (h != NULL)
05034 {
05035 bfd_boolean dyn;
05036
05037 off = h->got.offset;
05038 #ifdef INCLUDE_SHMEDIA
05039 if (seen_stt_datalabel)
05040 {
05041 struct elf_sh_link_hash_entry *hsh;
05042
05043 hsh = (struct elf_sh_link_hash_entry *)h;
05044 off = hsh->datalabel_got.offset;
05045 }
05046 #endif
05047 BFD_ASSERT (off != (bfd_vma) -1);
05048
05049 dyn = htab->root.dynamic_sections_created;
05050 if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
05051 || (info->shared
05052 && SYMBOL_REFERENCES_LOCAL (info, h))
05053 || (ELF_ST_VISIBILITY (h->other)
05054 && h->root.type == bfd_link_hash_undefweak))
05055 {
05056
05057
05058
05059
05060
05061
05062
05063
05064
05065
05066
05067
05068 if ((off & 1) != 0)
05069 off &= ~1;
05070 else
05071 {
05072 bfd_put_32 (output_bfd, relocation,
05073 sgot->contents + off);
05074 #ifdef INCLUDE_SHMEDIA
05075 if (seen_stt_datalabel)
05076 {
05077 struct elf_sh_link_hash_entry *hsh;
05078
05079 hsh = (struct elf_sh_link_hash_entry *)h;
05080 hsh->datalabel_got.offset |= 1;
05081 }
05082 else
05083 #endif
05084 h->got.offset |= 1;
05085 }
05086 }
05087
05088 relocation = sgot->output_offset + off;
05089 }
05090 else
05091 {
05092 #ifdef INCLUDE_SHMEDIA
05093 if (rel->r_addend)
05094 {
05095 BFD_ASSERT (local_got_offsets != NULL
05096 && (local_got_offsets[symtab_hdr->sh_info
05097 + r_symndx]
05098 != (bfd_vma) -1));
05099
05100 off = local_got_offsets[symtab_hdr->sh_info
05101 + r_symndx];
05102 }
05103 else
05104 {
05105 #endif
05106 BFD_ASSERT (local_got_offsets != NULL
05107 && local_got_offsets[r_symndx] != (bfd_vma) -1);
05108
05109 off = local_got_offsets[r_symndx];
05110 #ifdef INCLUDE_SHMEDIA
05111 }
05112 #endif
05113
05114
05115
05116
05117 if ((off & 1) != 0)
05118 off &= ~1;
05119 else
05120 {
05121 bfd_put_32 (output_bfd, relocation, sgot->contents + off);
05122
05123 if (info->shared)
05124 {
05125 Elf_Internal_Rela outrel;
05126 bfd_byte *loc;
05127
05128 if (srelgot == NULL)
05129 {
05130 srelgot = bfd_get_section_by_name (dynobj,
05131 ".rela.got");
05132 BFD_ASSERT (srelgot != NULL);
05133 }
05134
05135 outrel.r_offset = (sgot->output_section->vma
05136 + sgot->output_offset
05137 + off);
05138 outrel.r_info = ELF32_R_INFO (0, R_SH_RELATIVE);
05139 outrel.r_addend = relocation;
05140 loc = srelgot->contents;
05141 loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
05142 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
05143 }
05144
05145 #ifdef INCLUDE_SHMEDIA
05146 if (rel->r_addend)
05147 local_got_offsets[symtab_hdr->sh_info + r_symndx] |= 1;
05148 else
05149 #endif
05150 local_got_offsets[r_symndx] |= 1;
05151 }
05152
05153 relocation = sgot->output_offset + off;
05154 }
05155
05156 #ifdef GOT_BIAS
05157 relocation -= GOT_BIAS;
05158 #endif
05159
05160 goto final_link_relocate;
05161
05162 case R_SH_GOTOFF:
05163 #ifdef INCLUDE_SHMEDIA
05164 case R_SH_GOTOFF_LOW16:
05165 case R_SH_GOTOFF_MEDLOW16:
05166 case R_SH_GOTOFF_MEDHI16:
05167 case R_SH_GOTOFF_HI16:
05168 #endif
05169
05170
05171
05172 BFD_ASSERT (sgot != NULL);
05173
05174
05175
05176
05177
05178
05179 relocation -= sgot->output_section->vma;
05180
05181 #ifdef GOT_BIAS
05182 relocation -= GOT_BIAS;
05183 #endif
05184
05185 addend = rel->r_addend;
05186
05187 goto final_link_relocate;
05188
05189 case R_SH_GOTPC:
05190 #ifdef INCLUDE_SHMEDIA
05191 case R_SH_GOTPC_LOW16:
05192 case R_SH_GOTPC_MEDLOW16:
05193 case R_SH_GOTPC_MEDHI16:
05194 case R_SH_GOTPC_HI16:
05195 #endif
05196
05197
05198 BFD_ASSERT (sgot != NULL);
05199 relocation = sgot->output_section->vma;
05200
05201 #ifdef GOT_BIAS
05202 relocation += GOT_BIAS;
05203 #endif
05204
05205 addend = rel->r_addend;
05206
05207 goto final_link_relocate;
05208
05209 case R_SH_PLT32:
05210 #ifdef INCLUDE_SHMEDIA
05211 case R_SH_PLT_LOW16:
05212 case R_SH_PLT_MEDLOW16:
05213 case R_SH_PLT_MEDHI16:
05214 case R_SH_PLT_HI16:
05215 #endif
05216
05217
05218
05219
05220
05221 if (h == NULL)
05222 goto final_link_relocate;
05223
05224 if (h->forced_local)
05225 goto final_link_relocate;
05226
05227 if (h->plt.offset == (bfd_vma) -1)
05228 {
05229
05230
05231
05232 goto final_link_relocate;
05233 }
05234
05235 BFD_ASSERT (splt != NULL);
05236 relocation = (splt->output_section->vma
05237 + splt->output_offset
05238 + h->plt.offset);
05239
05240 #ifdef INCLUDE_SHMEDIA
05241 relocation++;
05242 #endif
05243
05244 addend = rel->r_addend;
05245
05246 goto final_link_relocate;
05247
05248 case R_SH_LOOP_START:
05249 {
05250 static bfd_vma start, end;
05251
05252 start = (relocation + rel->r_addend
05253 - (sec->output_section->vma + sec->output_offset));
05254 r = sh_elf_reloc_loop (r_type, input_bfd, input_section, contents,
05255 rel->r_offset, sec, start, end);
05256 break;
05257
05258 case R_SH_LOOP_END:
05259 end = (relocation + rel->r_addend
05260 - (sec->output_section->vma + sec->output_offset));
05261 r = sh_elf_reloc_loop (r_type, input_bfd, input_section, contents,
05262 rel->r_offset, sec, start, end);
05263 break;
05264 }
05265
05266 case R_SH_TLS_GD_32:
05267 case R_SH_TLS_IE_32:
05268 r_type = sh_elf_optimized_tls_reloc (info, r_type, h == NULL);
05269 tls_type = GOT_UNKNOWN;
05270 if (h == NULL && local_got_offsets)
05271 tls_type = sh_elf_local_got_tls_type (input_bfd) [r_symndx];
05272 else if (h != NULL)
05273 {
05274 tls_type = sh_elf_hash_entry (h)->tls_type;
05275 if (! info->shared
05276 && (h->dynindx == -1
05277 || h->def_regular))
05278 r_type = R_SH_TLS_LE_32;
05279 }
05280
05281 if (r_type == R_SH_TLS_GD_32 && tls_type == GOT_TLS_IE)
05282 r_type = R_SH_TLS_IE_32;
05283
05284 if (r_type == R_SH_TLS_LE_32)
05285 {
05286 bfd_vma offset;
05287 unsigned short insn;
05288
05289 if (ELF32_R_TYPE (rel->r_info) == R_SH_TLS_GD_32)
05290 {
05291
05292
05293
05294
05295
05296
05297
05298
05299
05300 offset = rel->r_offset;
05301 BFD_ASSERT (offset >= 16);
05302
05303 offset -= 16;
05304 insn = bfd_get_16 (input_bfd, contents + offset + 0);
05305 if ((insn & 0xff00) == 0xc700)
05306 {
05307 BFD_ASSERT (offset >= 2);
05308 offset -= 2;
05309 insn = bfd_get_16 (input_bfd, contents + offset + 0);
05310 }
05311
05312 BFD_ASSERT ((insn & 0xff00) == 0xd400);
05313 insn = bfd_get_16 (input_bfd, contents + offset + 2);
05314 BFD_ASSERT ((insn & 0xff00) == 0xc700);
05315 insn = bfd_get_16 (input_bfd, contents + offset + 4);
05316 BFD_ASSERT ((insn & 0xff00) == 0xd100);
05317 insn = bfd_get_16 (input_bfd, contents + offset + 6);
05318 BFD_ASSERT (insn == 0x310c);
05319 insn = bfd_get_16 (input_bfd, contents + offset + 8);
05320 BFD_ASSERT (insn == 0x410b);
05321 insn = bfd_get_16 (input_bfd, contents + offset + 10);
05322 BFD_ASSERT (insn == 0x34cc);
05323
05324 bfd_put_16 (output_bfd, 0x0012, contents + offset + 2);
05325 bfd_put_16 (output_bfd, 0x304c, contents + offset + 4);
05326 bfd_put_16 (output_bfd, 0x0009, contents + offset + 6);
05327 bfd_put_16 (output_bfd, 0x0009, contents + offset + 8);
05328 bfd_put_16 (output_bfd, 0x0009, contents + offset + 10);
05329 }
05330 else
05331 {
05332 int index;
05333
05334
05335
05336
05337
05338
05339
05340
05341 offset = rel->r_offset;
05342 BFD_ASSERT (offset >= 16);
05343
05344 offset -= 10;
05345 insn = bfd_get_16 (input_bfd, contents + offset + 0);
05346 if ((insn & 0xf0ff) == 0x0012)
05347 {
05348 BFD_ASSERT (offset >= 2);
05349 offset -= 2;
05350 insn = bfd_get_16 (input_bfd, contents + offset + 0);
05351 }
05352
05353 BFD_ASSERT ((insn & 0xff00) == 0xd000);
05354 index = insn & 0x00ff;
05355 insn = bfd_get_16 (input_bfd, contents + offset + 2);
05356 BFD_ASSERT ((insn & 0xf0ff) == 0x0012);
05357 insn = bfd_get_16 (input_bfd, contents + offset + 4);
05358 BFD_ASSERT ((insn & 0xf0ff) == 0x00ce);
05359 insn = 0xd000 | (insn & 0x0f00) | index;
05360 bfd_put_16 (output_bfd, insn, contents + offset + 0);
05361 bfd_put_16 (output_bfd, 0x0009, contents + offset + 4);
05362 }
05363
05364 bfd_put_32 (output_bfd, tpoff (info, relocation),
05365 contents + rel->r_offset);
05366 continue;
05367 }
05368
05369 sgot = htab->sgot;
05370 if (sgot == NULL)
05371 abort ();
05372
05373 if (h != NULL)
05374 off = h->got.offset;
05375 else
05376 {
05377 if (local_got_offsets == NULL)
05378 abort ();
05379
05380 off = local_got_offsets[r_symndx];
05381 }
05382
05383
05384 if (r_type == R_SH_TLS_IE_32
05385 && ! htab->root.dynamic_sections_created)
05386 {
05387 off &= ~1;
05388 bfd_put_32 (output_bfd, tpoff (info, relocation),
05389 sgot->contents + off);
05390 bfd_put_32 (output_bfd, sgot->output_offset + off,
05391 contents + rel->r_offset);
05392 continue;
05393 }
05394
05395 if ((off & 1) != 0)
05396 off &= ~1;
05397 else
05398 {
05399 Elf_Internal_Rela outrel;
05400 bfd_byte *loc;
05401 int dr_type, indx;
05402
05403 if (srelgot == NULL)
05404 {
05405 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
05406 BFD_ASSERT (srelgot != NULL);
05407 }
05408
05409 outrel.r_offset = (sgot->output_section->vma
05410 + sgot->output_offset + off);
05411
05412 if (h == NULL || h->dynindx == -1)
05413 indx = 0;
05414 else
05415 indx = h->dynindx;
05416
05417 dr_type = (r_type == R_SH_TLS_GD_32 ? R_SH_TLS_DTPMOD32 :
05418 R_SH_TLS_TPOFF32);
05419 if (dr_type == R_SH_TLS_TPOFF32 && indx == 0)
05420 outrel.r_addend = relocation - dtpoff_base (info);
05421 else
05422 outrel.r_addend = 0;
05423 outrel.r_info = ELF32_R_INFO (indx, dr_type);
05424 loc = srelgot->contents;
05425 loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
05426 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
05427
05428 if (r_type == R_SH_TLS_GD_32)
05429 {
05430 if (indx == 0)
05431 {
05432 bfd_put_32 (output_bfd,
05433 relocation - dtpoff_base (info),
05434 sgot->contents + off + 4);
05435 }
05436 else
05437 {
05438 outrel.r_info = ELF32_R_INFO (indx,
05439 R_SH_TLS_DTPOFF32);
05440 outrel.r_offset += 4;
05441 outrel.r_addend = 0;
05442 srelgot->reloc_count++;
05443 loc += sizeof (Elf32_External_Rela);
05444 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
05445 }
05446 }
05447
05448 if (h != NULL)
05449 h->got.offset |= 1;
05450 else
05451 local_got_offsets[r_symndx] |= 1;
05452 }
05453
05454 if (off >= (bfd_vma) -2)
05455 abort ();
05456
05457 if (r_type == (int) ELF32_R_TYPE (rel->r_info))
05458 relocation = sgot->output_offset + off;
05459 else
05460 {
05461 bfd_vma offset;
05462 unsigned short insn;
05463
05464
05465
05466
05467
05468
05469
05470
05471
05472
05473 offset = rel->r_offset;
05474 BFD_ASSERT (offset >= 16);
05475
05476 offset -= 16;
05477 insn = bfd_get_16 (input_bfd, contents + offset + 0);
05478 if ((insn & 0xff00) == 0xc700)
05479 {
05480 BFD_ASSERT (offset >= 2);
05481 offset -= 2;
05482 insn = bfd_get_16 (input_bfd, contents + offset + 0);
05483 }
05484
05485 BFD_ASSERT ((insn & 0xff00) == 0xd400);
05486
05487
05488 bfd_put_16 (output_bfd, insn & 0xf0ff, contents + offset);
05489
05490 insn = bfd_get_16 (input_bfd, contents + offset + 2);
05491 BFD_ASSERT ((insn & 0xff00) == 0xc700);
05492 insn = bfd_get_16 (input_bfd, contents + offset + 4);
05493 BFD_ASSERT ((insn & 0xff00) == 0xd100);
05494 insn = bfd_get_16 (input_bfd, contents + offset + 6);
05495 BFD_ASSERT (insn == 0x310c);
05496 insn = bfd_get_16 (input_bfd, contents + offset + 8);
05497 BFD_ASSERT (insn == 0x410b);
05498 insn = bfd_get_16 (input_bfd, contents + offset + 10);
05499 BFD_ASSERT (insn == 0x34cc);
05500
05501 bfd_put_16 (output_bfd, 0x0412, contents + offset + 2);
05502 bfd_put_16 (output_bfd, 0x00ce, contents + offset + 4);
05503 bfd_put_16 (output_bfd, 0x304c, contents + offset + 6);
05504 bfd_put_16 (output_bfd, 0x0009, contents + offset + 8);
05505 bfd_put_16 (output_bfd, 0x0009, contents + offset + 10);
05506
05507 bfd_put_32 (output_bfd, sgot->output_offset + off,
05508 contents + rel->r_offset);
05509
05510 continue;
05511 }
05512
05513 addend = rel->r_addend;
05514
05515 goto final_link_relocate;
05516
05517 case R_SH_TLS_LD_32:
05518 if (! info->shared)
05519 {
05520 bfd_vma offset;
05521 unsigned short insn;
05522
05523
05524
05525
05526
05527
05528
05529
05530
05531 offset = rel->r_offset;
05532 BFD_ASSERT (offset >= 16);
05533
05534 offset -= 16;
05535 insn = bfd_get_16 (input_bfd, contents + offset + 0);
05536 if ((insn & 0xff00) == 0xc700)
05537 {
05538 BFD_ASSERT (offset >= 2);
05539 offset -= 2;
05540 insn = bfd_get_16 (input_bfd, contents + offset + 0);
05541 }
05542
05543 BFD_ASSERT ((insn & 0xff00) == 0xd400);
05544 insn = bfd_get_16 (input_bfd, contents + offset + 2);
05545 BFD_ASSERT ((insn & 0xff00) == 0xc700);
05546 insn = bfd_get_16 (input_bfd, contents + offset + 4);
05547 BFD_ASSERT ((insn & 0xff00) == 0xd100);
05548 insn = bfd_get_16 (input_bfd, contents + offset + 6);
05549 BFD_ASSERT (insn == 0x310c);
05550 insn = bfd_get_16 (input_bfd, contents + offset + 8);
05551 BFD_ASSERT (insn == 0x410b);
05552 insn = bfd_get_16 (input_bfd, contents + offset + 10);
05553 BFD_ASSERT (insn == 0x34cc);
05554
05555 bfd_put_16 (output_bfd, 0x0012, contents + offset + 0);
05556 bfd_put_16 (output_bfd, 0x0009, contents + offset + 2);
05557 bfd_put_16 (output_bfd, 0x0009, contents + offset + 4);
05558 bfd_put_16 (output_bfd, 0x0009, contents + offset + 6);
05559 bfd_put_16 (output_bfd, 0x0009, contents + offset + 8);
05560 bfd_put_16 (output_bfd, 0x0009, contents + offset + 10);
05561
05562 continue;
05563 }
05564
05565 sgot = htab->sgot;
05566 if (sgot == NULL)
05567 abort ();
05568
05569 off = htab->tls_ldm_got.offset;
05570 if (off & 1)
05571 off &= ~1;
05572 else
05573 {
05574 Elf_Internal_Rela outrel;
05575 bfd_byte *loc;
05576
05577 srelgot = htab->srelgot;
05578 if (srelgot == NULL)
05579 abort ();
05580
05581 outrel.r_offset = (sgot->output_section->vma
05582 + sgot->output_offset + off);
05583 outrel.r_addend = 0;
05584 outrel.r_info = ELF32_R_INFO (0, R_SH_TLS_DTPMOD32);
05585 loc = srelgot->contents;
05586 loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
05587 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
05588 htab->tls_ldm_got.offset |= 1;
05589 }
05590
05591 relocation = sgot->output_offset + off;
05592 addend = rel->r_addend;
05593
05594 goto final_link_relocate;
05595
05596 case R_SH_TLS_LDO_32:
05597 if (! info->shared)
05598 relocation = tpoff (info, relocation);
05599 else
05600 relocation -= dtpoff_base (info);
05601
05602 addend = rel->r_addend;
05603 goto final_link_relocate;
05604
05605 case R_SH_TLS_LE_32:
05606 {
05607 int indx;
05608 Elf_Internal_Rela outrel;
05609 bfd_byte *loc;
05610
05611 if (! info->shared)
05612 {
05613 relocation = tpoff (info, relocation);
05614 addend = rel->r_addend;
05615 goto final_link_relocate;
05616 }
05617
05618 if (sreloc == NULL)
05619 {
05620 const char *name;
05621
05622 name = (bfd_elf_string_from_elf_section
05623 (input_bfd,
05624 elf_elfheader (input_bfd)->e_shstrndx,
05625 elf_section_data (input_section)->rel_hdr.sh_name));
05626 if (name == NULL)
05627 return FALSE;
05628
05629 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
05630 && strcmp (bfd_get_section_name (input_bfd,
05631 input_section),
05632 name + 5) == 0);
05633
05634 sreloc = bfd_get_section_by_name (dynobj, name);
05635 BFD_ASSERT (sreloc != NULL);
05636 }
05637
05638 if (h == NULL || h->dynindx == -1)
05639 indx = 0;
05640 else
05641 indx = h->dynindx;
05642
05643 outrel.r_offset = (input_section->output_section->vma
05644 + input_section->output_offset
05645 + rel->r_offset);
05646 outrel.r_info = ELF32_R_INFO (indx, R_SH_TLS_TPOFF32);
05647 if (indx == 0)
05648 outrel.r_addend = relocation - dtpoff_base (info);
05649 else
05650 outrel.r_addend = 0;
05651
05652 loc = sreloc->contents;
05653 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
05654 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
05655 continue;
05656 }
05657 }
05658
05659 relocation_done:
05660 if (r != bfd_reloc_ok)
05661 {
05662 switch (r)
05663 {
05664 default:
05665 case bfd_reloc_outofrange:
05666 abort ();
05667 case bfd_reloc_overflow:
05668 {
05669 const char *name;
05670
05671 if (h != NULL)
05672 name = NULL;
05673 else
05674 {
05675 name = (bfd_elf_string_from_elf_section
05676 (input_bfd, symtab_hdr->sh_link, sym->st_name));
05677 if (name == NULL)
05678 return FALSE;
05679 if (*name == '\0')
05680 name = bfd_section_name (input_bfd, sec);
05681 }
05682 if (! ((*info->callbacks->reloc_overflow)
05683 (info, (h ? &h->root : NULL), name, howto->name,
05684 (bfd_vma) 0, input_bfd, input_section,
05685 rel->r_offset)))
05686 return FALSE;
05687 }
05688 break;
05689 }
05690 }
05691 }
05692
05693 return TRUE;
05694 }
05695
05696
05697
05698
05699 static bfd_byte *
05700 sh_elf_get_relocated_section_contents (bfd *output_bfd,
05701 struct bfd_link_info *link_info,
05702 struct bfd_link_order *link_order,
05703 bfd_byte *data,
05704 bfd_boolean relocatable,
05705 asymbol **symbols)
05706 {
05707 Elf_Internal_Shdr *symtab_hdr;
05708 asection *input_section = link_order->u.indirect.section;
05709 bfd *input_bfd = input_section->owner;
05710 asection **sections = NULL;
05711 Elf_Internal_Rela *internal_relocs = NULL;
05712 Elf_Internal_Sym *isymbuf = NULL;
05713
05714
05715
05716 if (relocatable
05717 || elf_section_data (input_section)->this_hdr.contents == NULL)
05718 return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
05719 link_order, data,
05720 relocatable,
05721 symbols);
05722
05723 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
05724
05725 memcpy (data, elf_section_data (input_section)->this_hdr.contents,
05726 (size_t) input_section->size);
05727
05728 if ((input_section->flags & SEC_RELOC) != 0
05729 && input_section->reloc_count > 0)
05730 {
05731 asection **secpp;
05732 Elf_Internal_Sym *isym, *isymend;
05733 bfd_size_type amt;
05734
05735 internal_relocs = (_bfd_elf_link_read_relocs
05736 (input_bfd, input_section, NULL,
05737 (Elf_Internal_Rela *) NULL, FALSE));
05738 if (internal_relocs == NULL)
05739 goto error_return;
05740
05741 if (symtab_hdr->sh_info != 0)
05742 {
05743 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
05744 if (isymbuf == NULL)
05745 isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
05746 symtab_hdr->sh_info, 0,
05747 NULL, NULL, NULL);
05748 if (isymbuf == NULL)
05749 goto error_return;
05750 }
05751
05752 amt = symtab_hdr->sh_info;
05753 amt *= sizeof (asection *);
05754 sections = (asection **) bfd_malloc (amt);
05755 if (sections == NULL && amt != 0)
05756 goto error_return;
05757
05758 isymend = isymbuf + symtab_hdr->sh_info;
05759 for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
05760 {
05761 asection *isec;
05762
05763 if (isym->st_shndx == SHN_UNDEF)
05764 isec = bfd_und_section_ptr;
05765 else if (isym->st_shndx == SHN_ABS)
05766 isec = bfd_abs_section_ptr;
05767 else if (isym->st_shndx == SHN_COMMON)
05768 isec = bfd_com_section_ptr;
05769 else
05770 isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
05771
05772 *secpp = isec;
05773 }
05774
05775 if (! sh_elf_relocate_section (output_bfd, link_info, input_bfd,
05776 input_section, data, internal_relocs,
05777 isymbuf, sections))
05778 goto error_return;
05779
05780 if (sections != NULL)
05781 free (sections);
05782 if (isymbuf != NULL
05783 && symtab_hdr->contents != (unsigned char *) isymbuf)
05784 free (isymbuf);
05785 if (elf_section_data (input_section)->relocs != internal_relocs)
05786 free (internal_relocs);
05787 }
05788
05789 return data;
05790
05791 error_return:
05792 if (sections != NULL)
05793 free (sections);
05794 if (isymbuf != NULL
05795 && symtab_hdr->contents != (unsigned char *) isymbuf)
05796 free (isymbuf);
05797 if (internal_relocs != NULL
05798 && elf_section_data (input_section)->relocs != internal_relocs)
05799 free (internal_relocs);
05800 return NULL;
05801 }
05802
05803
05804
05805
05806
05807 static bfd_vma
05808 dtpoff_base (struct bfd_link_info *info)
05809 {
05810
05811 if (elf_hash_table (info)->tls_sec == NULL)
05812 return 0;
05813 return elf_hash_table (info)->tls_sec->vma;
05814 }
05815
05816
05817
05818 static bfd_vma
05819 tpoff (struct bfd_link_info *info, bfd_vma address)
05820 {
05821
05822 if (elf_hash_table (info)->tls_sec == NULL)
05823 return 0;
05824
05825
05826 return (address - elf_hash_table (info)->tls_sec->vma
05827 + align_power ((bfd_vma) 8,
05828 elf_hash_table (info)->tls_sec->alignment_power));
05829 }
05830
05831 static asection *
05832 sh_elf_gc_mark_hook (asection *sec,
05833 struct bfd_link_info *info ATTRIBUTE_UNUSED,
05834 Elf_Internal_Rela *rel, struct elf_link_hash_entry *h,
05835 Elf_Internal_Sym *sym)
05836 {
05837 if (h != NULL)
05838 {
05839 switch (ELF32_R_TYPE (rel->r_info))
05840 {
05841 case R_SH_GNU_VTINHERIT:
05842 case R_SH_GNU_VTENTRY:
05843 break;
05844
05845 default:
05846 #ifdef INCLUDE_SHMEDIA
05847 while (h->root.type == bfd_link_hash_indirect
05848 && h->root.u.i.link)
05849 h = (struct elf_link_hash_entry *) h->root.u.i.link;
05850 #endif
05851 switch (h->root.type)
05852 {
05853 case bfd_link_hash_defined:
05854 case bfd_link_hash_defweak:
05855 return h->root.u.def.section;
05856
05857 case bfd_link_hash_common:
05858 return h->root.u.c.p->section;
05859
05860 default:
05861 break;
05862 }
05863 }
05864 }
05865 else
05866 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
05867
05868 return NULL;
05869 }
05870
05871
05872
05873 static bfd_boolean
05874 sh_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
05875 asection *sec, const Elf_Internal_Rela *relocs)
05876 {
05877 Elf_Internal_Shdr *symtab_hdr;
05878 struct elf_link_hash_entry **sym_hashes;
05879 bfd_signed_vma *local_got_refcounts;
05880 const Elf_Internal_Rela *rel, *relend;
05881
05882 elf_section_data (sec)->local_dynrel = NULL;
05883
05884 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
05885 sym_hashes = elf_sym_hashes (abfd);
05886 local_got_refcounts = elf_local_got_refcounts (abfd);
05887
05888 relend = relocs + sec->reloc_count;
05889 for (rel = relocs; rel < relend; rel++)
05890 {
05891 unsigned long r_symndx;
05892 unsigned int r_type;
05893 struct elf_link_hash_entry *h = NULL;
05894 #ifdef INCLUDE_SHMEDIA
05895 int seen_stt_datalabel = 0;
05896 #endif
05897
05898 r_symndx = ELF32_R_SYM (rel->r_info);
05899 if (r_symndx >= symtab_hdr->sh_info)
05900 {
05901 struct elf_sh_link_hash_entry *eh;
05902 struct elf_sh_dyn_relocs **pp;
05903 struct elf_sh_dyn_relocs *p;
05904
05905 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
05906 while (h->root.type == bfd_link_hash_indirect
05907 || h->root.type == bfd_link_hash_warning)
05908 {
05909 #ifdef INCLUDE_SHMEDIA
05910 seen_stt_datalabel |= h->type == STT_DATALABEL;
05911 #endif
05912 h = (struct elf_link_hash_entry *) h->root.u.i.link;
05913 }
05914 eh = (struct elf_sh_link_hash_entry *) h;
05915 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
05916 if (p->sec == sec)
05917 {
05918
05919 *pp = p->next;
05920 break;
05921 }
05922 }
05923
05924 r_type = ELF32_R_TYPE (rel->r_info);
05925 switch (sh_elf_optimized_tls_reloc (info, r_type, h != NULL))
05926 {
05927 case R_SH_TLS_LD_32:
05928 if (sh_elf_hash_table (info)->tls_ldm_got.refcount > 0)
05929 sh_elf_hash_table (info)->tls_ldm_got.refcount -= 1;
05930 break;
05931
05932 case R_SH_GOT32:
05933 case R_SH_GOTOFF:
05934 case R_SH_GOTPC:
05935 #ifdef INCLUDE_SHMEDIA
05936 case R_SH_GOT_LOW16:
05937 case R_SH_GOT_MEDLOW16:
05938 case R_SH_GOT_MEDHI16:
05939 case R_SH_GOT_HI16:
05940 case R_SH_GOT10BY4:
05941 case R_SH_GOT10BY8:
05942 case R_SH_GOTOFF_LOW16:
05943 case R_SH_GOTOFF_MEDLOW16:
05944 case R_SH_GOTOFF_MEDHI16:
05945 case R_SH_GOTOFF_HI16:
05946 case R_SH_GOTPC_LOW16:
05947 case R_SH_GOTPC_MEDLOW16:
05948 case R_SH_GOTPC_MEDHI16:
05949 case R_SH_GOTPC_HI16:
05950 #endif
05951 case R_SH_TLS_GD_32:
05952 case R_SH_TLS_IE_32:
05953 if (h != NULL)
05954 {
05955 #ifdef INCLUDE_SHMEDIA
05956 if (seen_stt_datalabel)
05957 {
05958 struct elf_sh_link_hash_entry *eh;
05959 eh = (struct elf_sh_link_hash_entry *) h;
05960 if (eh->datalabel_got.refcount > 0)
05961 eh->datalabel_got.refcount -= 1;
05962 }
05963 else
05964 #endif
05965 if (h->got.refcount > 0)
05966 h->got.refcount -= 1;
05967 }
05968 else if (local_got_refcounts != NULL)
05969 {
05970 #ifdef INCLUDE_SHMEDIA
05971 if (rel->r_addend & 1)
05972 {
05973 if (local_got_refcounts[symtab_hdr->sh_info + r_symndx] > 0)
05974 local_got_refcounts[symtab_hdr->sh_info + r_symndx] -= 1;
05975 }
05976 else
05977 #endif
05978 if (local_got_refcounts[r_symndx] > 0)
05979 local_got_refcounts[r_symndx] -= 1;
05980 }
05981 break;
05982
05983 case R_SH_DIR32:
05984 case R_SH_REL32:
05985 if (info->shared)
05986 break;
05987
05988
05989 case R_SH_PLT32:
05990 #ifdef INCLUDE_SHMEDIA
05991 case R_SH_PLT_LOW16:
05992 case R_SH_PLT_MEDLOW16:
05993 case R_SH_PLT_MEDHI16:
05994 case R_SH_PLT_HI16:
05995 #endif
05996 if (h != NULL)
05997 {
05998 if (h->plt.refcount > 0)
05999 h->plt.refcount -= 1;
06000 }
06001 break;
06002
06003 case R_SH_GOTPLT32:
06004 #ifdef INCLUDE_SHMEDIA
06005 case R_SH_GOTPLT_LOW16:
06006 case R_SH_GOTPLT_MEDLOW16:
06007 case R_SH_GOTPLT_MEDHI16:
06008 case R_SH_GOTPLT_HI16:
06009 case R_SH_GOTPLT10BY4:
06010 case R_SH_GOTPLT10BY8:
06011 #endif
06012 if (h != NULL)
06013 {
06014 struct elf_sh_link_hash_entry *eh;
06015 eh = (struct elf_sh_link_hash_entry *) h;
06016 if (eh->gotplt_refcount > 0)
06017 {
06018 eh->gotplt_refcount -= 1;
06019 if (h->plt.refcount > 0)
06020 h->plt.refcount -= 1;
06021 }
06022 #ifdef INCLUDE_SHMEDIA
06023 else if (seen_stt_datalabel)
06024 {
06025 if (eh->datalabel_got.refcount > 0)
06026 eh->datalabel_got.refcount -= 1;
06027 }
06028 #endif
06029 else if (h->got.refcount > 0)
06030 h->got.refcount -= 1;
06031 }
06032 else if (local_got_refcounts != NULL)
06033 {
06034 #ifdef INCLUDE_SHMEDIA
06035 if (rel->r_addend & 1)
06036 {
06037 if (local_got_refcounts[symtab_hdr->sh_info + r_symndx] > 0)
06038 local_got_refcounts[symtab_hdr->sh_info + r_symndx] -= 1;
06039 }
06040 else
06041 #endif
06042 if (local_got_refcounts[r_symndx] > 0)
06043 local_got_refcounts[r_symndx] -= 1;
06044 }
06045 break;
06046
06047 default:
06048 break;
06049 }
06050 }
06051
06052 return TRUE;
06053 }
06054
06055
06056
06057 static void
06058 sh_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
06059 struct elf_link_hash_entry *dir,
06060 struct elf_link_hash_entry *ind)
06061 {
06062 struct elf_sh_link_hash_entry *edir, *eind;
06063 #ifdef INCLUDE_SHMEDIA
06064 bfd_signed_vma tmp;
06065 #endif
06066
06067 edir = (struct elf_sh_link_hash_entry *) dir;
06068 eind = (struct elf_sh_link_hash_entry *) ind;
06069
06070 if (eind->dyn_relocs != NULL)
06071 {
06072 if (edir->dyn_relocs != NULL)
06073 {
06074 struct elf_sh_dyn_relocs **pp;
06075 struct elf_sh_dyn_relocs *p;
06076
06077 BFD_ASSERT (ind->root.type != bfd_link_hash_indirect);
06078
06079
06080
06081 for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
06082 {
06083 struct elf_sh_dyn_relocs *q;
06084
06085 for (q = edir->dyn_relocs; q != NULL; q = q->next)
06086 if (q->sec == p->sec)
06087 {
06088 q->pc_count += p->pc_count;
06089 q->count += p->count;
06090 *pp = p->next;
06091 break;
06092 }
06093 if (q == NULL)
06094 pp = &p->next;
06095 }
06096 *pp = edir->dyn_relocs;
06097 }
06098
06099 edir->dyn_relocs = eind->dyn_relocs;
06100 eind->dyn_relocs = NULL;
06101 }
06102 edir->gotplt_refcount = eind->gotplt_refcount;
06103 eind->gotplt_refcount = 0;
06104 #ifdef INCLUDE_SHMEDIA
06105 tmp = edir->datalabel_got.refcount;
06106 if (tmp < 1)
06107 {
06108 edir->datalabel_got.refcount = eind->datalabel_got.refcount;
06109 eind->datalabel_got.refcount = tmp;
06110 }
06111 else
06112 BFD_ASSERT (eind->datalabel_got.refcount < 1);
06113 #endif
06114
06115 if (ind->root.type == bfd_link_hash_indirect
06116 && dir->got.refcount <= 0)
06117 {
06118 edir->tls_type = eind->tls_type;
06119 eind->tls_type = GOT_UNKNOWN;
06120 }
06121
06122 if (ind->root.type != bfd_link_hash_indirect
06123 && dir->dynamic_adjusted)
06124 {
06125
06126
06127
06128 dir->ref_dynamic |= ind->ref_dynamic;
06129 dir->ref_regular |= ind->ref_regular;
06130 dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
06131 dir->needs_plt |= ind->needs_plt;
06132 }
06133 else
06134 _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
06135 }
06136
06137 static int
06138 sh_elf_optimized_tls_reloc (struct bfd_link_info *info, int r_type,
06139 int is_local)
06140 {
06141 if (info->shared)
06142 return r_type;
06143
06144 switch (r_type)
06145 {
06146 case R_SH_TLS_GD_32:
06147 case R_SH_TLS_IE_32:
06148 if (is_local)
06149 return R_SH_TLS_LE_32;
06150 return R_SH_TLS_IE_32;
06151 case R_SH_TLS_LD_32:
06152 return R_SH_TLS_LE_32;
06153 }
06154
06155 return r_type;
06156 }
06157
06158
06159
06160
06161
06162 static bfd_boolean
06163 sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
06164 const Elf_Internal_Rela *relocs)
06165 {
06166 Elf_Internal_Shdr *symtab_hdr;
06167 struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
06168 struct elf_sh_link_hash_table *htab;
06169 const Elf_Internal_Rela *rel;
06170 const Elf_Internal_Rela *rel_end;
06171 bfd_vma *local_got_offsets;
06172 asection *sgot;
06173 asection *srelgot;
06174 asection *sreloc;
06175 unsigned int r_type;
06176 int tls_type, old_tls_type;
06177
06178 sgot = NULL;
06179 srelgot = NULL;
06180 sreloc = NULL;
06181
06182 if (info->relocatable)
06183 return TRUE;
06184
06185 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
06186 sym_hashes = elf_sym_hashes (abfd);
06187 sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
06188 if (!elf_bad_symtab (abfd))
06189 sym_hashes_end -= symtab_hdr->sh_info;
06190
06191 htab = sh_elf_hash_table (info);
06192 local_got_offsets = elf_local_got_offsets (abfd);
06193
06194 rel_end = relocs + sec->reloc_count;
06195 for (rel = relocs; rel < rel_end; rel++)
06196 {
06197 struct elf_link_hash_entry *h;
06198 unsigned long r_symndx;
06199 #ifdef INCLUDE_SHMEDIA
06200 int seen_stt_datalabel = 0;
06201 #endif
06202
06203 r_symndx = ELF32_R_SYM (rel->r_info);
06204 r_type = ELF32_R_TYPE (rel->r_info);
06205
06206 if (r_symndx < symtab_hdr->sh_info)
06207 h = NULL;
06208 else
06209 {
06210 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
06211 #ifdef INCLUDE_SHMEDIA
06212 while (h->root.type == bfd_link_hash_indirect
06213 || h->root.type == bfd_link_hash_warning)
06214 {
06215 seen_stt_datalabel |= h->type == STT_DATALABEL;
06216 h = (struct elf_link_hash_entry *) h->root.u.i.link;
06217 }
06218 #endif
06219 }
06220
06221 r_type = sh_elf_optimized_tls_reloc (info, r_type, h == NULL);
06222 if (! info->shared
06223 && r_type == R_SH_TLS_IE_32
06224 && h != NULL
06225 && h->root.type != bfd_link_hash_undefined
06226 && h->root.type != bfd_link_hash_undefweak
06227 && (h->dynindx == -1
06228 || h->def_regular))
06229 r_type = R_SH_TLS_LE_32;
06230
06231
06232 if (htab->sgot == NULL)
06233 {
06234 switch (r_type)
06235 {
06236 case R_SH_GOTPLT32:
06237 case R_SH_GOT32:
06238 case R_SH_GOTOFF:
06239 case R_SH_GOTPC:
06240 #ifdef INCLUDE_SHMEDIA
06241 case R_SH_GOTPLT_LOW16:
06242 case R_SH_GOTPLT_MEDLOW16:
06243 case R_SH_GOTPLT_MEDHI16:
06244 case R_SH_GOTPLT_HI16:
06245 case R_SH_GOTPLT10BY4:
06246 case R_SH_GOTPLT10BY8:
06247 case R_SH_GOT_LOW16:
06248 case R_SH_GOT_MEDLOW16:
06249 case R_SH_GOT_MEDHI16:
06250 case R_SH_GOT_HI16:
06251 case R_SH_GOT10BY4:
06252 case R_SH_GOT10BY8:
06253 case R_SH_GOTOFF_LOW16:
06254 case R_SH_GOTOFF_MEDLOW16:
06255 case R_SH_GOTOFF_MEDHI16:
06256 case R_SH_GOTOFF_HI16:
06257 case R_SH_GOTPC_LOW16:
06258 case R_SH_GOTPC_MEDLOW16:
06259 case R_SH_GOTPC_MEDHI16:
06260 case R_SH_GOTPC_HI16:
06261 #endif
06262 case R_SH_TLS_GD_32:
06263 case R_SH_TLS_LD_32:
06264 case R_SH_TLS_IE_32:
06265 if (htab->sgot == NULL)
06266 {
06267 if (htab->root.dynobj == NULL)
06268 htab->root.dynobj = abfd;
06269 if (!create_got_section (htab->root.dynobj, info))
06270 return FALSE;
06271 }
06272 break;
06273
06274 default:
06275 break;
06276 }
06277 }
06278
06279 switch (r_type)
06280 {
06281
06282
06283 case R_SH_GNU_VTINHERIT:
06284 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
06285 return FALSE;
06286 break;
06287
06288
06289
06290 case R_SH_GNU_VTENTRY:
06291 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
06292 return FALSE;
06293 break;
06294
06295 case R_SH_TLS_IE_32:
06296 if (info->shared)
06297 info->flags |= DF_STATIC_TLS;
06298
06299
06300 force_got:
06301 case R_SH_TLS_GD_32:
06302 case R_SH_GOT32:
06303 #ifdef INCLUDE_SHMEDIA
06304 case R_SH_GOT_LOW16:
06305 case R_SH_GOT_MEDLOW16:
06306 case R_SH_GOT_MEDHI16:
06307 case R_SH_GOT_HI16:
06308 case R_SH_GOT10BY4:
06309 case R_SH_GOT10BY8:
06310 #endif
06311 switch (r_type)
06312 {
06313 default:
06314 tls_type = GOT_NORMAL;
06315 break;
06316 case R_SH_TLS_GD_32:
06317 tls_type = GOT_TLS_GD;
06318 break;
06319 case R_SH_TLS_IE_32:
06320 tls_type = GOT_TLS_IE;
06321 break;
06322 }
06323
06324 if (h != NULL)
06325 {
06326 #ifdef INCLUDE_SHMEDIA
06327 if (seen_stt_datalabel)
06328 {
06329 struct elf_sh_link_hash_entry *eh
06330 = (struct elf_sh_link_hash_entry *) h;
06331
06332 eh->datalabel_got.refcount += 1;
06333 }
06334 else
06335 #endif
06336 h->got.refcount += 1;
06337 old_tls_type = sh_elf_hash_entry (h)->tls_type;
06338 }
06339 else
06340 {
06341 bfd_signed_vma *local_got_refcounts;
06342
06343
06344
06345 local_got_refcounts = elf_local_got_refcounts (abfd);
06346 if (local_got_refcounts == NULL)
06347 {
06348 bfd_size_type size;
06349
06350 size = symtab_hdr->sh_info;
06351 size *= sizeof (bfd_signed_vma);
06352 #ifdef INCLUDE_SHMEDIA
06353
06354
06355 size *= 2;
06356 #endif
06357 size += symtab_hdr->sh_info;
06358 local_got_refcounts = ((bfd_signed_vma *)
06359 bfd_zalloc (abfd, size));
06360 if (local_got_refcounts == NULL)
06361 return FALSE;
06362 elf_local_got_refcounts (abfd) = local_got_refcounts;
06363 #ifdef INCLUDE_SHMEDIA
06364
06365
06366 sh_elf_local_got_tls_type (abfd)
06367 = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
06368 #else
06369 sh_elf_local_got_tls_type (abfd)
06370 = (char *) (local_got_refcounts + symtab_hdr->sh_info);
06371 #endif
06372 }
06373 #ifdef INCLUDE_SHMEDIA
06374 if (rel->r_addend & 1)
06375 local_got_refcounts[symtab_hdr->sh_info + r_symndx] += 1;
06376 else
06377 #endif
06378 local_got_refcounts[r_symndx] += 1;
06379 old_tls_type = sh_elf_local_got_tls_type (abfd) [r_symndx];
06380 }
06381
06382
06383
06384 if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
06385 && (old_tls_type != GOT_TLS_GD || tls_type != GOT_TLS_IE))
06386 {
06387 if (old_tls_type == GOT_TLS_IE && tls_type == GOT_TLS_GD)
06388 tls_type = GOT_TLS_IE;
06389 else
06390 {
06391 (*_bfd_error_handler)
06392 (_("%B: `%s' accessed both as normal and thread local symbol"),
06393 abfd, h->root.root.string);
06394 return FALSE;
06395 }
06396 }
06397
06398 if (old_tls_type != tls_type)
06399 {
06400 if (h != NULL)
06401 sh_elf_hash_entry (h)->tls_type = tls_type;
06402 else
06403 sh_elf_local_got_tls_type (abfd) [r_symndx] = tls_type;
06404 }
06405
06406 break;
06407
06408 case R_SH_TLS_LD_32:
06409 sh_elf_hash_table(info)->tls_ldm_got.refcount += 1;
06410 break;
06411
06412 case R_SH_GOTPLT32:
06413 #ifdef INCLUDE_SHMEDIA
06414 case R_SH_GOTPLT_LOW16:
06415 case R_SH_GOTPLT_MEDLOW16:
06416 case R_SH_GOTPLT_MEDHI16:
06417 case R_SH_GOTPLT_HI16:
06418 case R_SH_GOTPLT10BY4:
06419 case R_SH_GOTPLT10BY8:
06420 #endif
06421
06422
06423
06424 if (h == NULL
06425 || h->forced_local
06426 || ! info->shared
06427 || info->symbolic
06428 || h->dynindx == -1)
06429 goto force_got;
06430
06431 h->needs_plt = 1;
06432 h->plt.refcount += 1;
06433 ((struct elf_sh_link_hash_entry *) h)->gotplt_refcount += 1;
06434
06435 break;
06436
06437 case R_SH_PLT32:
06438 #ifdef INCLUDE_SHMEDIA
06439 case R_SH_PLT_LOW16:
06440 case R_SH_PLT_MEDLOW16:
06441 case R_SH_PLT_MEDHI16:
06442 case R_SH_PLT_HI16:
06443 #endif
06444
06445
06446
06447
06448
06449
06450
06451
06452
06453 if (h == NULL)
06454 continue;
06455
06456 if (h->forced_local)
06457 break;
06458
06459 h->needs_plt = 1;
06460 h->plt.refcount += 1;
06461 break;
06462
06463 case R_SH_DIR32:
06464 case R_SH_REL32:
06465 #ifdef INCLUDE_SHMEDIA
06466 case R_SH_IMM_LOW16_PCREL:
06467 case R_SH_IMM_MEDLOW16_PCREL:
06468 case R_SH_IMM_MEDHI16_PCREL:
06469 case R_SH_IMM_HI16_PCREL:
06470 #endif
06471 if (h != NULL && ! info->shared)
06472 {
06473 h->non_got_ref = 1;
06474 h->plt.refcount += 1;
06475 }
06476
06477
06478
06479
06480
06481
06482
06483
06484
06485
06486
06487
06488
06489
06490
06491
06492
06493
06494
06495
06496 if ((info->shared
06497 && (sec->flags & SEC_ALLOC) != 0
06498 && (r_type != R_SH_REL32
06499 || (h != NULL
06500 && (! info->symbolic
06501 || h->root.type == bfd_link_hash_defweak
06502 || !h->def_regular))))
06503 || (! info->shared
06504 && (sec->flags & SEC_ALLOC) != 0
06505 && h != NULL
06506 && (h->root.type == bfd_link_hash_defweak
06507 || !h->def_regular)))
06508 {
06509 struct elf_sh_dyn_relocs *p;
06510 struct elf_sh_dyn_relocs **head;
06511
06512 if (htab->root.dynobj == NULL)
06513 htab->root.dynobj = abfd;
06514
06515
06516
06517
06518 if (sreloc == NULL)
06519 {
06520 const char *name;
06521
06522 name = (bfd_elf_string_from_elf_section
06523 (abfd,
06524 elf_elfheader (abfd)->e_shstrndx,
06525 elf_section_data (sec)->rel_hdr.sh_name));
06526 if (name == NULL)
06527 return FALSE;
06528
06529 BFD_ASSERT (strncmp (name, ".rela", 5) == 0
06530 && strcmp (bfd_get_section_name (abfd, sec),
06531 name + 5) == 0);
06532
06533 sreloc = bfd_get_section_by_name (htab->root.dynobj, name);
06534 if (sreloc == NULL)
06535 {
06536 flagword flags;
06537
06538 sreloc = bfd_make_section (htab->root.dynobj, name);
06539 flags = (SEC_HAS_CONTENTS | SEC_READONLY
06540 | SEC_IN_MEMORY | SEC_LINKER_CREATED);
06541 if ((sec->flags & SEC_ALLOC) != 0)
06542 flags |= SEC_ALLOC | SEC_LOAD;
06543 if (sreloc == NULL
06544 || ! bfd_set_section_flags (htab->root.dynobj,
06545 sreloc, flags)
06546 || ! bfd_set_section_alignment (htab->root.dynobj,
06547 sreloc, 2))
06548 return FALSE;
06549 }
06550 elf_section_data (sec)->sreloc = sreloc;
06551 }
06552
06553
06554
06555 if (h != NULL)
06556 head = &((struct elf_sh_link_hash_entry *) h)->dyn_relocs;
06557 else
06558 {
06559 asection *s;
06560
06561
06562 s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
06563 sec, r_symndx);
06564 if (s == NULL)
06565 return FALSE;
06566
06567 head = ((struct elf_sh_dyn_relocs **)
06568 &elf_section_data (s)->local_dynrel);
06569 }
06570
06571 p = *head;
06572 if (p == NULL || p->sec != sec)
06573 {
06574 bfd_size_type amt = sizeof (*p);
06575 p = bfd_alloc (htab->root.dynobj, amt);
06576 if (p == NULL)
06577 return FALSE;
06578 p->next = *head;
06579 *head = p;
06580 p->sec = sec;
06581 p->count = 0;
06582 p->pc_count = 0;
06583 }
06584
06585 p->count += 1;
06586 if (r_type == R_SH_REL32
06587 #ifdef INCLUDE_SHMEDIA
06588 || r_type == R_SH_IMM_LOW16_PCREL
06589 || r_type == R_SH_IMM_MEDLOW16_PCREL
06590 || r_type == R_SH_IMM_MEDHI16_PCREL
06591 || r_type == R_SH_IMM_HI16_PCREL
06592 #endif
06593 )
06594 p->pc_count += 1;
06595 }
06596
06597 break;
06598
06599 case R_SH_TLS_LE_32:
06600 if (info->shared)
06601 {
06602 (*_bfd_error_handler)
06603 (_("%B: TLS local exec code cannot be linked into shared objects"),
06604 abfd);
06605 return FALSE;
06606 }
06607
06608 break;
06609
06610 case R_SH_TLS_LDO_32:
06611
06612 break;
06613
06614 default:
06615 break;
06616 }
06617 }
06618
06619 return TRUE;
06620 }
06621
06622 #ifndef sh_elf_set_mach_from_flags
06623 static unsigned int sh_ef_bfd_table[] = { EF_SH_BFD_TABLE };
06624
06625 static bfd_boolean
06626 sh_elf_set_mach_from_flags (bfd *abfd)
06627 {
06628 flagword flags = elf_elfheader (abfd)->e_flags & EF_SH_MACH_MASK;
06629
06630 if (flags >= sizeof(sh_ef_bfd_table))
06631 return FALSE;
06632
06633 if (sh_ef_bfd_table[flags] == 0)
06634 return FALSE;
06635
06636 bfd_default_set_arch_mach (abfd, bfd_arch_sh, sh_ef_bfd_table[flags]);
06637
06638 return TRUE;
06639 }
06640
06641
06642
06643
06644
06645
06646
06647 int
06648 sh_elf_get_flags_from_mach (unsigned long mach)
06649 {
06650 int i = ARRAY_SIZE (sh_ef_bfd_table);
06651
06652 for (; i>0; i--)
06653 if (sh_ef_bfd_table[i] == mach)
06654 return i;
06655
06656
06657 BFD_FAIL();
06658
06659 return -1;
06660 }
06661 #endif
06662
06663 #ifndef sh_elf_set_private_flags
06664
06665
06666 static bfd_boolean
06667 sh_elf_set_private_flags (bfd *abfd, flagword flags)
06668 {
06669 BFD_ASSERT (! elf_flags_init (abfd)
06670 || elf_elfheader (abfd)->e_flags == flags);
06671
06672 elf_elfheader (abfd)->e_flags = flags;
06673 elf_flags_init (abfd) = TRUE;
06674 return sh_elf_set_mach_from_flags (abfd);
06675 }
06676 #endif
06677
06678 #ifndef sh_elf_copy_private_data
06679
06680
06681 static bfd_boolean
06682 sh_elf_copy_private_data (bfd * ibfd, bfd * obfd)
06683 {
06684 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
06685 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
06686 return TRUE;
06687
06688 return sh_elf_set_private_flags (obfd, elf_elfheader (ibfd)->e_flags);
06689 }
06690 #endif
06691
06692 #ifndef sh_elf_merge_private_data
06693
06694
06695
06696
06697 int
06698 sh_find_elf_flags (unsigned int arch_set)
06699 {
06700 extern unsigned long sh_get_bfd_mach_from_arch_set (unsigned int);
06701 unsigned long bfd_mach = sh_get_bfd_mach_from_arch_set (arch_set);
06702
06703 return sh_elf_get_flags_from_mach (bfd_mach);
06704 }
06705
06706
06707
06708
06709 static bfd_boolean
06710 sh_elf_merge_private_data (bfd *ibfd, bfd *obfd)
06711 {
06712 extern bfd_boolean sh_merge_bfd_arch (bfd *, bfd *);
06713
06714 if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour
06715 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
06716 return TRUE;
06717
06718 if (! elf_flags_init (obfd))
06719 {
06720
06721 elf_flags_init (obfd) = TRUE;
06722 elf_elfheader (obfd)->e_flags = EF_SH1;
06723 sh_elf_set_mach_from_flags (obfd);
06724 }
06725
06726 if (! sh_merge_bfd_arch (ibfd, obfd))
06727 {
06728 _bfd_error_handler ("%B: uses instructions which are incompatible "
06729 "with instructions used in previous modules",
06730 ibfd);
06731 bfd_set_error (bfd_error_bad_value);
06732 return FALSE;
06733 }
06734
06735 elf_elfheader (obfd)->e_flags =
06736 sh_elf_get_flags_from_mach (bfd_get_mach (obfd));
06737
06738 return TRUE;
06739 }
06740 #endif
06741
06742
06743
06744
06745
06746 static bfd_boolean
06747 sh_elf_object_p (bfd *abfd)
06748 {
06749 return sh_elf_set_mach_from_flags (abfd);
06750 }
06751
06752
06753
06754
06755 static bfd_boolean
06756 sh_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
06757 struct elf_link_hash_entry *h,
06758 Elf_Internal_Sym *sym)
06759 {
06760 struct elf_sh_link_hash_table *htab;
06761
06762 htab = sh_elf_hash_table (info);
06763
06764 if (h->plt.offset != (bfd_vma) -1)
06765 {
06766 asection *splt;
06767 asection *sgot;
06768 asection *srel;
06769
06770 bfd_vma plt_index;
06771 bfd_vma got_offset;
06772 Elf_Internal_Rela rel;
06773 bfd_byte *loc;
06774
06775
06776
06777
06778 BFD_ASSERT (h->dynindx != -1);
06779
06780 splt = htab->splt;
06781 sgot = htab->sgotplt;
06782 srel = htab->srelplt;
06783 BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
06784
06785
06786
06787
06788
06789 plt_index = h->plt.offset / elf_sh_sizeof_plt (info) - 1;
06790
06791
06792
06793
06794 got_offset = (plt_index + 3) * 4;
06795
06796 #ifdef GOT_BIAS
06797 if (info->shared)
06798 got_offset -= GOT_BIAS;
06799 #endif
06800
06801
06802 if (! info->shared)
06803 {
06804 if (elf_sh_plt_entry == NULL)
06805 {
06806 elf_sh_plt_entry = (bfd_big_endian (output_bfd) ?
06807 elf_sh_plt_entry_be : elf_sh_plt_entry_le);
06808 }
06809 memcpy (splt->contents + h->plt.offset, elf_sh_plt_entry,
06810 elf_sh_sizeof_plt (info));
06811 #ifdef INCLUDE_SHMEDIA
06812 movi_shori_putval (output_bfd,
06813 (sgot->output_section->vma
06814 + sgot->output_offset
06815 + got_offset),
06816 (splt->contents + h->plt.offset
06817 + elf_sh_plt_symbol_offset (info)));
06818
06819
06820 movi_shori_putval (output_bfd,
06821 (splt->output_section->vma + splt->output_offset)
06822 | 1,
06823 (splt->contents + h->plt.offset
06824 + elf_sh_plt_plt0_offset (info)));
06825 #else
06826 bfd_put_32 (output_bfd,
06827 (sgot->output_section->vma
06828 + sgot->output_offset
06829 + got_offset),
06830 (splt->contents + h->plt.offset
06831 + elf_sh_plt_symbol_offset (info)));
06832
06833 bfd_put_32 (output_bfd,
06834 (splt->output_section->vma + splt->output_offset),
06835 (splt->contents + h->plt.offset
06836 + elf_sh_plt_plt0_offset (info)));
06837 #endif
06838 }
06839 else
06840 {
06841 if (elf_sh_pic_plt_entry == NULL)
06842 {
06843 elf_sh_pic_plt_entry = (bfd_big_endian (output_bfd) ?
06844 elf_sh_pic_plt_entry_be :
06845 elf_sh_pic_plt_entry_le);
06846 }
06847 memcpy (splt->contents + h->plt.offset, elf_sh_pic_plt_entry,
06848 elf_sh_sizeof_plt (info));
06849 #ifdef INCLUDE_SHMEDIA
06850 movi_shori_putval (output_bfd, got_offset,
06851 (splt->contents + h->plt.offset
06852 + elf_sh_plt_symbol_offset (info)));
06853 #else
06854 bfd_put_32 (output_bfd, got_offset,
06855 (splt->contents + h->plt.offset
06856 + elf_sh_plt_symbol_offset (info)));
06857 #endif
06858 }
06859
06860 #ifdef GOT_BIAS
06861 if (info->shared)
06862 got_offset += GOT_BIAS;
06863 #endif
06864
06865 #ifdef INCLUDE_SHMEDIA
06866 movi_shori_putval (output_bfd,
06867 plt_index * sizeof (Elf32_External_Rela),
06868 (splt->contents + h->plt.offset
06869 + elf_sh_plt_reloc_offset (info)));
06870 #else
06871 bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
06872 (splt->contents + h->plt.offset
06873 + elf_sh_plt_reloc_offset (info)));
06874 #endif
06875
06876
06877 bfd_put_32 (output_bfd,
06878 (splt->output_section->vma
06879 + splt->output_offset
06880 + h->plt.offset
06881 + elf_sh_plt_temp_offset (info)),
06882 sgot->contents + got_offset);
06883
06884
06885 rel.r_offset = (sgot->output_section->vma
06886 + sgot->output_offset
06887 + got_offset);
06888 rel.r_info = ELF32_R_INFO (h->dynindx, R_SH_JMP_SLOT);
06889 rel.r_addend = 0;
06890 #ifdef GOT_BIAS
06891 rel.r_addend = GOT_BIAS;
06892 #endif
06893 loc = srel->contents + plt_index * sizeof (Elf32_External_Rela);
06894 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
06895
06896 if (!h->def_regular)
06897 {
06898
06899
06900 sym->st_shndx = SHN_UNDEF;
06901 }
06902 }
06903
06904 if (h->got.offset != (bfd_vma) -1
06905 && sh_elf_hash_entry (h)->tls_type != GOT_TLS_GD
06906 && sh_elf_hash_entry (h)->tls_type != GOT_TLS_IE)
06907 {
06908 asection *sgot;
06909 asection *srel;
06910 Elf_Internal_Rela rel;
06911 bfd_byte *loc;
06912
06913
06914
06915
06916 sgot = htab->sgot;
06917 srel = htab->srelgot;
06918 BFD_ASSERT (sgot != NULL && srel != NULL);
06919
06920 rel.r_offset = (sgot->output_section->vma
06921 + sgot->output_offset
06922 + (h->got.offset &~ (bfd_vma) 1));
06923
06924
06925
06926
06927
06928
06929 if (info->shared
06930 && SYMBOL_REFERENCES_LOCAL (info, h))
06931 {
06932 rel.r_info = ELF32_R_INFO (0, R_SH_RELATIVE);
06933 rel.r_addend = (h->root.u.def.value
06934 + h->root.u.def.section->output_section->vma
06935 + h->root.u.def.section->output_offset);
06936 }
06937 else
06938 {
06939 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
06940 rel.r_info = ELF32_R_INFO (h->dynindx, R_SH_GLOB_DAT);
06941 rel.r_addend = 0;
06942 }
06943
06944 loc = srel->contents;
06945 loc += srel->reloc_count++ * sizeof (Elf32_External_Rela);
06946 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
06947 }
06948
06949 #ifdef INCLUDE_SHMEDIA
06950 {
06951 struct elf_sh_link_hash_entry *eh;
06952
06953 eh = (struct elf_sh_link_hash_entry *) h;
06954 if (eh->datalabel_got.offset != (bfd_vma) -1)
06955 {
06956 asection *sgot;
06957 asection *srel;
06958 Elf_Internal_Rela rel;
06959 bfd_byte *loc;
06960
06961
06962
06963
06964 sgot = htab->sgot;
06965 srel = htab->srelgot;
06966 BFD_ASSERT (sgot != NULL && srel != NULL);
06967
06968 rel.r_offset = (sgot->output_section->vma
06969 + sgot->output_offset
06970 + (eh->datalabel_got.offset &~ (bfd_vma) 1));
06971
06972
06973
06974
06975
06976
06977 if (info->shared
06978 && SYMBOL_REFERENCES_LOCAL (info, h))
06979 {
06980 rel.r_info = ELF32_R_INFO (0, R_SH_RELATIVE);
06981 rel.r_addend = (h->root.u.def.value
06982 + h->root.u.def.section->output_section->vma
06983 + h->root.u.def.section->output_offset);
06984 }
06985 else
06986 {
06987 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents
06988 + eh->datalabel_got.offset);
06989 rel.r_info = ELF32_R_INFO (h->dynindx, R_SH_GLOB_DAT);
06990 rel.r_addend = 0;
06991 }
06992
06993 loc = srel->contents;
06994 loc += srel->reloc_count++ * sizeof (Elf32_External_Rela);
06995 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
06996 }
06997 }
06998 #endif
06999
07000 if (h->needs_copy)
07001 {
07002 asection *s;
07003 Elf_Internal_Rela rel;
07004 bfd_byte *loc;
07005
07006
07007
07008 BFD_ASSERT (h->dynindx != -1
07009 && (h->root.type == bfd_link_hash_defined
07010 || h->root.type == bfd_link_hash_defweak));
07011
07012 s = bfd_get_section_by_name (h->root.u.def.section->owner,
07013 ".rela.bss");
07014 BFD_ASSERT (s != NULL);
07015
07016 rel.r_offset = (h->root.u.def.value
07017 + h->root.u.def.section->output_section->vma
07018 + h->root.u.def.section->output_offset);
07019 rel.r_info = ELF32_R_INFO (h->dynindx, R_SH_COPY);
07020 rel.r_addend = 0;
07021 loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
07022 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
07023 }
07024
07025
07026 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
07027 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
07028 sym->st_shndx = SHN_ABS;
07029
07030 return TRUE;
07031 }
07032
07033
07034
07035 static bfd_boolean
07036 sh_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
07037 {
07038 struct elf_sh_link_hash_table *htab;
07039 asection *sgot;
07040 asection *sdyn;
07041
07042 htab = sh_elf_hash_table (info);
07043 sgot = htab->sgotplt;
07044 sdyn = bfd_get_section_by_name (htab->root.dynobj, ".dynamic");
07045
07046 if (htab->root.dynamic_sections_created)
07047 {
07048 asection *splt;
07049 Elf32_External_Dyn *dyncon, *dynconend;
07050
07051 BFD_ASSERT (sgot != NULL && sdyn != NULL);
07052
07053 dyncon = (Elf32_External_Dyn *) sdyn->contents;
07054 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
07055 for (; dyncon < dynconend; dyncon++)
07056 {
07057 Elf_Internal_Dyn dyn;
07058 asection *s;
07059 #ifdef INCLUDE_SHMEDIA
07060 const char *name;
07061 #endif
07062
07063 bfd_elf32_swap_dyn_in (htab->root.dynobj, dyncon, &dyn);
07064
07065 switch (dyn.d_tag)
07066 {
07067 default:
07068 break;
07069
07070 #ifdef INCLUDE_SHMEDIA
07071 case DT_INIT:
07072 name = info->init_function;
07073 goto get_sym;
07074
07075 case DT_FINI:
07076 name = info->fini_function;
07077 get_sym:
07078 if (dyn.d_un.d_val != 0)
07079 {
07080 struct elf_link_hash_entry *h;
07081
07082 h = elf_link_hash_lookup (&htab->root, name,
07083 FALSE, FALSE, TRUE);
07084 if (h != NULL && (h->other & STO_SH5_ISA32))
07085 {
07086 dyn.d_un.d_val |= 1;
07087 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
07088 }
07089 }
07090 break;
07091 #endif
07092
07093 case DT_PLTGOT:
07094 s = htab->sgot->output_section;
07095 goto get_vma;
07096
07097 case DT_JMPREL:
07098 s = htab->srelplt->output_section;
07099 get_vma:
07100 BFD_ASSERT (s != NULL);
07101 dyn.d_un.d_ptr = s->vma;
07102 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
07103 break;
07104
07105 case DT_PLTRELSZ:
07106 s = htab->srelplt->output_section;
07107 BFD_ASSERT (s != NULL);
07108 dyn.d_un.d_val = s->size;
07109 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
07110 break;
07111
07112 case DT_RELASZ:
07113
07114
07115
07116
07117
07118
07119
07120
07121
07122 if (htab->srelplt != NULL)
07123 {
07124 s = htab->srelplt->output_section;
07125 dyn.d_un.d_val -= s->size;
07126 }
07127 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
07128 break;
07129 }
07130 }
07131
07132
07133 splt = htab->splt;
07134 if (splt && splt->size > 0)
07135 {
07136 if (info->shared)
07137 {
07138 if (elf_sh_pic_plt_entry == NULL)
07139 {
07140 elf_sh_pic_plt_entry = (bfd_big_endian (output_bfd) ?
07141 elf_sh_pic_plt_entry_be :
07142 elf_sh_pic_plt_entry_le);
07143 }
07144 memcpy (splt->contents, elf_sh_pic_plt_entry,
07145 elf_sh_sizeof_plt (info));
07146 }
07147 else
07148 {
07149 if (elf_sh_plt0_entry == NULL)
07150 {
07151 elf_sh_plt0_entry = (bfd_big_endian (output_bfd) ?
07152 elf_sh_plt0_entry_be :
07153 elf_sh_plt0_entry_le);
07154 }
07155 memcpy (splt->contents, elf_sh_plt0_entry, PLT_ENTRY_SIZE);
07156 #ifdef INCLUDE_SHMEDIA
07157 movi_shori_putval (output_bfd,
07158 sgot->output_section->vma
07159 + sgot->output_offset,
07160 splt->contents
07161 + elf_sh_plt0_gotplt_offset (info));
07162 #else
07163 bfd_put_32 (output_bfd,
07164 sgot->output_section->vma + sgot->output_offset + 4,
07165 splt->contents + elf_sh_plt0_gotid_offset (info));
07166 bfd_put_32 (output_bfd,
07167 sgot->output_section->vma + sgot->output_offset + 8,
07168 splt->contents + elf_sh_plt0_linker_offset (info));
07169 #endif
07170 }
07171
07172
07173
07174 elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
07175 }
07176 }
07177
07178
07179 if (sgot && sgot->size > 0)
07180 {
07181 if (sdyn == NULL)
07182 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
07183 else
07184 bfd_put_32 (output_bfd,
07185 sdyn->output_section->vma + sdyn->output_offset,
07186 sgot->contents);
07187 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4);
07188 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
07189
07190 elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
07191 }
07192
07193 return TRUE;
07194 }
07195
07196 static enum elf_reloc_type_class
07197 sh_elf_reloc_type_class (const Elf_Internal_Rela *rela)
07198 {
07199 switch ((int) ELF32_R_TYPE (rela->r_info))
07200 {
07201 case R_SH_RELATIVE:
07202 return reloc_class_relative;
07203 case R_SH_JMP_SLOT:
07204 return reloc_class_plt;
07205 case R_SH_COPY:
07206 return reloc_class_copy;
07207 default:
07208 return reloc_class_normal;
07209 }
07210 }
07211
07212 #if !defined SH_TARGET_ALREADY_DEFINED
07213
07214
07215 static bfd_boolean
07216 elf32_shlin_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
07217 {
07218 int offset;
07219 unsigned int size;
07220
07221 switch (note->descsz)
07222 {
07223 default:
07224 return FALSE;
07225
07226 case 168:
07227
07228 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
07229
07230
07231 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
07232
07233
07234 offset = 72;
07235 size = 92;
07236
07237 break;
07238 }
07239
07240
07241 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
07242 size, note->descpos + offset);
07243 }
07244
07245 static bfd_boolean
07246 elf32_shlin_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
07247 {
07248 switch (note->descsz)
07249 {
07250 default:
07251 return FALSE;
07252
07253 case 124:
07254 elf_tdata (abfd)->core_program
07255 = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
07256 elf_tdata (abfd)->core_command
07257 = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
07258 }
07259
07260
07261
07262
07263
07264 {
07265 char *command = elf_tdata (abfd)->core_command;
07266 int n = strlen (command);
07267
07268 if (0 < n && command[n - 1] == ' ')
07269 command[n - 1] = '\0';
07270 }
07271
07272 return TRUE;
07273 }
07274 #endif
07275
07276
07277
07278
07279
07280 static bfd_vma
07281 sh_elf_plt_sym_val (bfd_vma i, const asection *plt,
07282 const arelent *rel ATTRIBUTE_UNUSED)
07283 {
07284 return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
07285 }
07286
07287 #if !defined SH_TARGET_ALREADY_DEFINED
07288 #define TARGET_BIG_SYM bfd_elf32_sh_vec
07289 #define TARGET_BIG_NAME "elf32-sh"
07290 #define TARGET_LITTLE_SYM bfd_elf32_shl_vec
07291 #define TARGET_LITTLE_NAME "elf32-shl"
07292 #endif
07293
07294 #define ELF_ARCH bfd_arch_sh
07295 #define ELF_MACHINE_CODE EM_SH
07296 #ifdef __QNXTARGET__
07297 #define ELF_MAXPAGESIZE 0x1000
07298 #else
07299 #define ELF_MAXPAGESIZE 0x80
07300 #endif
07301
07302 #define elf_symbol_leading_char '_'
07303
07304 #define bfd_elf32_bfd_reloc_type_lookup sh_elf_reloc_type_lookup
07305 #define elf_info_to_howto sh_elf_info_to_howto
07306 #define bfd_elf32_bfd_relax_section sh_elf_relax_section
07307 #define elf_backend_relocate_section sh_elf_relocate_section
07308 #define bfd_elf32_bfd_get_relocated_section_contents \
07309 sh_elf_get_relocated_section_contents
07310 #define bfd_elf32_mkobject sh_elf_mkobject
07311 #define elf_backend_object_p sh_elf_object_p
07312 #define bfd_elf32_bfd_set_private_bfd_flags \
07313 sh_elf_set_private_flags
07314 #define bfd_elf32_bfd_copy_private_bfd_data \
07315 sh_elf_copy_private_data
07316 #define bfd_elf32_bfd_merge_private_bfd_data \
07317 sh_elf_merge_private_data
07318
07319 #define elf_backend_gc_mark_hook sh_elf_gc_mark_hook
07320 #define elf_backend_gc_sweep_hook sh_elf_gc_sweep_hook
07321 #define elf_backend_check_relocs sh_elf_check_relocs
07322 #define elf_backend_copy_indirect_symbol \
07323 sh_elf_copy_indirect_symbol
07324 #define elf_backend_create_dynamic_sections \
07325 sh_elf_create_dynamic_sections
07326 #define bfd_elf32_bfd_link_hash_table_create \
07327 sh_elf_link_hash_table_create
07328 #define elf_backend_adjust_dynamic_symbol \
07329 sh_elf_adjust_dynamic_symbol
07330 #define elf_backend_size_dynamic_sections \
07331 sh_elf_size_dynamic_sections
07332 #define elf_backend_finish_dynamic_symbol \
07333 sh_elf_finish_dynamic_symbol
07334 #define elf_backend_finish_dynamic_sections \
07335 sh_elf_finish_dynamic_sections
07336 #define elf_backend_reloc_type_class sh_elf_reloc_type_class
07337 #define elf_backend_plt_sym_val sh_elf_plt_sym_val
07338
07339 #define elf_backend_can_gc_sections 1
07340 #define elf_backend_can_refcount 1
07341 #define elf_backend_want_got_plt 1
07342 #define elf_backend_plt_readonly 1
07343 #define elf_backend_want_plt_sym 0
07344 #define elf_backend_got_header_size 12
07345
07346 #if !defined INCLUDE_SHMEDIA && !defined SH_TARGET_ALREADY_DEFINED
07347
07348 #include "elf32-target.h"
07349
07350
07351 #undef TARGET_BIG_SYM
07352 #define TARGET_BIG_SYM bfd_elf32_shnbsd_vec
07353 #undef TARGET_BIG_NAME
07354 #define TARGET_BIG_NAME "elf32-sh-nbsd"
07355 #undef TARGET_LITTLE_SYM
07356 #define TARGET_LITTLE_SYM bfd_elf32_shlnbsd_vec
07357 #undef TARGET_LITTLE_NAME
07358 #define TARGET_LITTLE_NAME "elf32-shl-nbsd"
07359 #undef ELF_MAXPAGESIZE
07360 #define ELF_MAXPAGESIZE 0x10000
07361 #undef elf_symbol_leading_char
07362 #define elf_symbol_leading_char 0
07363 #undef elf32_bed
07364 #define elf32_bed elf32_sh_nbsd_bed
07365
07366 #include "elf32-target.h"
07367
07368
07369
07370 #undef TARGET_BIG_SYM
07371 #define TARGET_BIG_SYM bfd_elf32_shblin_vec
07372 #undef TARGET_BIG_NAME
07373 #define TARGET_BIG_NAME "elf32-shbig-linux"
07374 #undef TARGET_LITTLE_SYM
07375 #define TARGET_LITTLE_SYM bfd_elf32_shlin_vec
07376 #undef TARGET_LITTLE_NAME
07377 #define TARGET_LITTLE_NAME "elf32-sh-linux"
07378
07379 #undef elf_backend_grok_prstatus
07380 #define elf_backend_grok_prstatus elf32_shlin_grok_prstatus
07381 #undef elf_backend_grok_psinfo
07382 #define elf_backend_grok_psinfo elf32_shlin_grok_psinfo
07383 #undef elf32_bed
07384 #define elf32_bed elf32_sh_lin_bed
07385
07386 #include "elf32-target.h"
07387
07388 #endif