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
00027
00028
00029
00030
00031
00032 #include "bfd.h"
00033 #include "sysdep.h"
00034 #include "bfdlink.h"
00035 #include "libbfd.h"
00036 #include "elf-bfd.h"
00037 #include "elf/ppc64.h"
00038 #include "elf64-ppc.h"
00039
00040 static bfd_reloc_status_type ppc64_elf_ha_reloc
00041 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00042 static bfd_reloc_status_type ppc64_elf_branch_reloc
00043 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00044 static bfd_reloc_status_type ppc64_elf_brtaken_reloc
00045 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00046 static bfd_reloc_status_type ppc64_elf_sectoff_reloc
00047 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00048 static bfd_reloc_status_type ppc64_elf_sectoff_ha_reloc
00049 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00050 static bfd_reloc_status_type ppc64_elf_toc_reloc
00051 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00052 static bfd_reloc_status_type ppc64_elf_toc_ha_reloc
00053 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00054 static bfd_reloc_status_type ppc64_elf_toc64_reloc
00055 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00056 static bfd_reloc_status_type ppc64_elf_unhandled_reloc
00057 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
00058 static bfd_vma opd_entry_value
00059 (asection *, bfd_vma, asection **, bfd_vma *);
00060
00061 #define TARGET_LITTLE_SYM bfd_elf64_powerpcle_vec
00062 #define TARGET_LITTLE_NAME "elf64-powerpcle"
00063 #define TARGET_BIG_SYM bfd_elf64_powerpc_vec
00064 #define TARGET_BIG_NAME "elf64-powerpc"
00065 #define ELF_ARCH bfd_arch_powerpc
00066 #define ELF_MACHINE_CODE EM_PPC64
00067 #define ELF_MAXPAGESIZE 0x10000
00068 #define elf_info_to_howto ppc64_elf_info_to_howto
00069
00070 #define elf_backend_want_got_sym 0
00071 #define elf_backend_want_plt_sym 0
00072 #define elf_backend_plt_alignment 3
00073 #define elf_backend_plt_not_loaded 1
00074 #define elf_backend_got_symbol_offset 0
00075 #define elf_backend_got_header_size 8
00076 #define elf_backend_can_gc_sections 1
00077 #define elf_backend_can_refcount 1
00078 #define elf_backend_rela_normal 1
00079
00080 #define bfd_elf64_mkobject ppc64_elf_mkobject
00081 #define bfd_elf64_bfd_reloc_type_lookup ppc64_elf_reloc_type_lookup
00082 #define bfd_elf64_bfd_merge_private_bfd_data ppc64_elf_merge_private_bfd_data
00083 #define bfd_elf64_new_section_hook ppc64_elf_new_section_hook
00084 #define bfd_elf64_bfd_link_hash_table_create ppc64_elf_link_hash_table_create
00085 #define bfd_elf64_bfd_link_hash_table_free ppc64_elf_link_hash_table_free
00086 #define bfd_elf64_get_synthetic_symtab ppc64_elf_get_synthetic_symtab
00087
00088 #define elf_backend_object_p ppc64_elf_object_p
00089 #define elf_backend_grok_prstatus ppc64_elf_grok_prstatus
00090 #define elf_backend_grok_psinfo ppc64_elf_grok_psinfo
00091 #define elf_backend_create_dynamic_sections ppc64_elf_create_dynamic_sections
00092 #define elf_backend_copy_indirect_symbol ppc64_elf_copy_indirect_symbol
00093 #define elf_backend_add_symbol_hook ppc64_elf_add_symbol_hook
00094 #define elf_backend_check_directives ppc64_elf_check_directives
00095 #define elf_backend_archive_symbol_lookup ppc64_elf_archive_symbol_lookup
00096 #define elf_backend_check_relocs ppc64_elf_check_relocs
00097 #define elf_backend_gc_mark_hook ppc64_elf_gc_mark_hook
00098 #define elf_backend_gc_sweep_hook ppc64_elf_gc_sweep_hook
00099 #define elf_backend_adjust_dynamic_symbol ppc64_elf_adjust_dynamic_symbol
00100 #define elf_backend_hide_symbol ppc64_elf_hide_symbol
00101 #define elf_backend_always_size_sections ppc64_elf_func_desc_adjust
00102 #define elf_backend_size_dynamic_sections ppc64_elf_size_dynamic_sections
00103 #define elf_backend_relocate_section ppc64_elf_relocate_section
00104 #define elf_backend_finish_dynamic_symbol ppc64_elf_finish_dynamic_symbol
00105 #define elf_backend_reloc_type_class ppc64_elf_reloc_type_class
00106 #define elf_backend_finish_dynamic_sections ppc64_elf_finish_dynamic_sections
00107 #define elf_backend_link_output_symbol_hook ppc64_elf_output_symbol_hook
00108 #define elf_backend_special_sections ppc64_elf_special_sections
00109
00110
00111
00112 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
00113
00114
00115 #define PLT_ENTRY_SIZE 24
00116
00117
00118 #define PLT_INITIAL_ENTRY_SIZE PLT_ENTRY_SIZE
00119
00120
00121 #define TOC_BASE_OFF 0x8000
00122
00123
00124 #define TP_OFFSET 0x7000
00125 #define DTP_OFFSET 0x8000
00126
00127
00128
00129
00130 #define PLT_CALL_STUB_SIZE (7*4)
00131 #define ADDIS_R12_R2 0x3d820000
00132 #define STD_R2_40R1 0xf8410028
00133 #define LD_R11_0R12 0xe96c0000
00134 #define LD_R2_0R12 0xe84c0000
00135 #define MTCTR_R11 0x7d6903a6
00136
00137 #define BCTR 0x4e800420
00138
00139
00140 #define ADDIS_R2_R2 0x3c420000
00141 #define ADDI_R2_R2 0x38420000
00142
00143 #define LD_R2_40R1 0xe8410028
00144
00145
00146
00147 #define GLINK_CALL_STUB_SIZE (16*4)
00148 #define MFCTR_R12 0x7d8902a6
00149 #define SLDI_R11_R0_3 0x780b1f24
00150 #define ADDIC_R2_R0_32K 0x34408000
00151 #define SUB_R12_R12_R11 0x7d8b6050
00152 #define SRADI_R2_R2_63 0x7c42fe76
00153 #define SLDI_R11_R0_2 0x780b1764
00154 #define AND_R2_R2_R11 0x7c425838
00155
00156 #define ADD_R12_R12_R2 0x7d8c1214
00157 #define ADDIS_R12_R12 0x3d8c0000
00158
00159 #define ADDI_R12_R12 0x398c0000
00160
00161
00162
00163
00164
00165
00166 #define NOP 0x60000000
00167
00168
00169 #define CROR_151515 0x4def7b82
00170 #define CROR_313131 0x4ffffb82
00171
00172
00173 #define LI_R0_0 0x38000000
00174 #define B_DOT 0x48000000
00175
00176
00177
00178 #define LIS_R0_0 0x3c000000
00179 #define ORI_R0_R0_0 0x60000000
00180
00181
00182 #define STD_R0_0R1 0xf8010000
00183 #define STD_R0_0R12 0xf80c0000
00184 #define LD_R0_0R1 0xe8010000
00185 #define LD_R0_0R12 0xe80c0000
00186 #define STFD_FR0_0R1 0xd8010000
00187 #define LFD_FR0_0R1 0xc8010000
00188 #define LI_R12_0 0x39800000
00189 #define STVX_VR0_R12_R0 0x7c0c01ce
00190 #define LVX_VR0_R12_R0 0x7c0c00ce
00191 #define MTLR_R0 0x7c0803a6
00192 #define BLR 0x4e800020
00193
00194
00195
00196
00197
00198 #ifndef NO_OPD_RELOCS
00199 #define NO_OPD_RELOCS 0
00200 #endif
00201
00202 #define ONES(n) (((bfd_vma) 1 << ((n) - 1) << 1) - 1)
00203
00204
00205 static reloc_howto_type *ppc64_elf_howto_table[(int) R_PPC64_max];
00206
00207 static reloc_howto_type ppc64_elf_howto_raw[] = {
00208
00209 HOWTO (R_PPC64_NONE,
00210 0,
00211 2,
00212 32,
00213 FALSE,
00214 0,
00215 complain_overflow_dont,
00216 bfd_elf_generic_reloc,
00217 "R_PPC64_NONE",
00218 FALSE,
00219 0,
00220 0,
00221 FALSE),
00222
00223
00224 HOWTO (R_PPC64_ADDR32,
00225 0,
00226 2,
00227 32,
00228 FALSE,
00229 0,
00230 complain_overflow_bitfield,
00231 bfd_elf_generic_reloc,
00232 "R_PPC64_ADDR32",
00233 FALSE,
00234 0,
00235 0xffffffff,
00236 FALSE),
00237
00238
00239
00240 HOWTO (R_PPC64_ADDR24,
00241 0,
00242 2,
00243 26,
00244 FALSE,
00245 0,
00246 complain_overflow_bitfield,
00247 bfd_elf_generic_reloc,
00248 "R_PPC64_ADDR24",
00249 FALSE,
00250 0,
00251 0x03fffffc,
00252 FALSE),
00253
00254
00255 HOWTO (R_PPC64_ADDR16,
00256 0,
00257 1,
00258 16,
00259 FALSE,
00260 0,
00261 complain_overflow_bitfield,
00262 bfd_elf_generic_reloc,
00263 "R_PPC64_ADDR16",
00264 FALSE,
00265 0,
00266 0xffff,
00267 FALSE),
00268
00269
00270 HOWTO (R_PPC64_ADDR16_LO,
00271 0,
00272 1,
00273 16,
00274 FALSE,
00275 0,
00276 complain_overflow_dont,
00277 bfd_elf_generic_reloc,
00278 "R_PPC64_ADDR16_LO",
00279 FALSE,
00280 0,
00281 0xffff,
00282 FALSE),
00283
00284
00285 HOWTO (R_PPC64_ADDR16_HI,
00286 16,
00287 1,
00288 16,
00289 FALSE,
00290 0,
00291 complain_overflow_dont,
00292 bfd_elf_generic_reloc,
00293 "R_PPC64_ADDR16_HI",
00294 FALSE,
00295 0,
00296 0xffff,
00297 FALSE),
00298
00299
00300
00301 HOWTO (R_PPC64_ADDR16_HA,
00302 16,
00303 1,
00304 16,
00305 FALSE,
00306 0,
00307 complain_overflow_dont,
00308 ppc64_elf_ha_reloc,
00309 "R_PPC64_ADDR16_HA",
00310 FALSE,
00311 0,
00312 0xffff,
00313 FALSE),
00314
00315
00316
00317 HOWTO (R_PPC64_ADDR14,
00318 0,
00319 2,
00320 16,
00321 FALSE,
00322 0,
00323 complain_overflow_bitfield,
00324 ppc64_elf_branch_reloc,
00325 "R_PPC64_ADDR14",
00326 FALSE,
00327 0,
00328 0x0000fffc,
00329 FALSE),
00330
00331
00332
00333
00334 HOWTO (R_PPC64_ADDR14_BRTAKEN,
00335 0,
00336 2,
00337 16,
00338 FALSE,
00339 0,
00340 complain_overflow_bitfield,
00341 ppc64_elf_brtaken_reloc,
00342 "R_PPC64_ADDR14_BRTAKEN",
00343 FALSE,
00344 0,
00345 0x0000fffc,
00346 FALSE),
00347
00348
00349
00350
00351 HOWTO (R_PPC64_ADDR14_BRNTAKEN,
00352 0,
00353 2,
00354 16,
00355 FALSE,
00356 0,
00357 complain_overflow_bitfield,
00358 ppc64_elf_brtaken_reloc,
00359 "R_PPC64_ADDR14_BRNTAKEN",
00360 FALSE,
00361 0,
00362 0x0000fffc,
00363 FALSE),
00364
00365
00366 HOWTO (R_PPC64_REL24,
00367 0,
00368 2,
00369 26,
00370 TRUE,
00371 0,
00372 complain_overflow_signed,
00373 ppc64_elf_branch_reloc,
00374 "R_PPC64_REL24",
00375 FALSE,
00376 0,
00377 0x03fffffc,
00378 TRUE),
00379
00380
00381 HOWTO (R_PPC64_REL14,
00382 0,
00383 2,
00384 16,
00385 TRUE,
00386 0,
00387 complain_overflow_signed,
00388 ppc64_elf_branch_reloc,
00389 "R_PPC64_REL14",
00390 FALSE,
00391 0,
00392 0x0000fffc,
00393 TRUE),
00394
00395
00396
00397
00398 HOWTO (R_PPC64_REL14_BRTAKEN,
00399 0,
00400 2,
00401 16,
00402 TRUE,
00403 0,
00404 complain_overflow_signed,
00405 ppc64_elf_brtaken_reloc,
00406 "R_PPC64_REL14_BRTAKEN",
00407 FALSE,
00408 0,
00409 0x0000fffc,
00410 TRUE),
00411
00412
00413
00414
00415 HOWTO (R_PPC64_REL14_BRNTAKEN,
00416 0,
00417 2,
00418 16,
00419 TRUE,
00420 0,
00421 complain_overflow_signed,
00422 ppc64_elf_brtaken_reloc,
00423 "R_PPC64_REL14_BRNTAKEN",
00424 FALSE,
00425 0,
00426 0x0000fffc,
00427 TRUE),
00428
00429
00430
00431 HOWTO (R_PPC64_GOT16,
00432 0,
00433 1,
00434 16,
00435 FALSE,
00436 0,
00437 complain_overflow_signed,
00438 ppc64_elf_unhandled_reloc,
00439 "R_PPC64_GOT16",
00440 FALSE,
00441 0,
00442 0xffff,
00443 FALSE),
00444
00445
00446
00447 HOWTO (R_PPC64_GOT16_LO,
00448 0,
00449 1,
00450 16,
00451 FALSE,
00452 0,
00453 complain_overflow_dont,
00454 ppc64_elf_unhandled_reloc,
00455 "R_PPC64_GOT16_LO",
00456 FALSE,
00457 0,
00458 0xffff,
00459 FALSE),
00460
00461
00462
00463 HOWTO (R_PPC64_GOT16_HI,
00464 16,
00465 1,
00466 16,
00467 FALSE,
00468 0,
00469 complain_overflow_dont,
00470 ppc64_elf_unhandled_reloc,
00471 "R_PPC64_GOT16_HI",
00472 FALSE,
00473 0,
00474 0xffff,
00475 FALSE),
00476
00477
00478
00479 HOWTO (R_PPC64_GOT16_HA,
00480 16,
00481 1,
00482 16,
00483 FALSE,
00484 0,
00485 complain_overflow_dont,
00486 ppc64_elf_unhandled_reloc,
00487 "R_PPC64_GOT16_HA",
00488 FALSE,
00489 0,
00490 0xffff,
00491 FALSE),
00492
00493
00494
00495
00496
00497
00498 HOWTO (R_PPC64_COPY,
00499 0,
00500 0,
00501 0,
00502 FALSE,
00503 0,
00504 complain_overflow_dont,
00505 ppc64_elf_unhandled_reloc,
00506 "R_PPC64_COPY",
00507 FALSE,
00508 0,
00509 0,
00510 FALSE),
00511
00512
00513
00514 HOWTO (R_PPC64_GLOB_DAT,
00515 0,
00516 4,
00517 64,
00518 FALSE,
00519 0,
00520 complain_overflow_dont,
00521 ppc64_elf_unhandled_reloc,
00522 "R_PPC64_GLOB_DAT",
00523 FALSE,
00524 0,
00525 ONES (64),
00526 FALSE),
00527
00528
00529
00530 HOWTO (R_PPC64_JMP_SLOT,
00531 0,
00532 0,
00533 0,
00534 FALSE,
00535 0,
00536 complain_overflow_dont,
00537 ppc64_elf_unhandled_reloc,
00538 "R_PPC64_JMP_SLOT",
00539 FALSE,
00540 0,
00541 0,
00542 FALSE),
00543
00544
00545
00546
00547 HOWTO (R_PPC64_RELATIVE,
00548 0,
00549 4,
00550 64,
00551 FALSE,
00552 0,
00553 complain_overflow_dont,
00554 bfd_elf_generic_reloc,
00555 "R_PPC64_RELATIVE",
00556 FALSE,
00557 0,
00558 ONES (64),
00559 FALSE),
00560
00561
00562 HOWTO (R_PPC64_UADDR32,
00563 0,
00564 2,
00565 32,
00566 FALSE,
00567 0,
00568 complain_overflow_bitfield,
00569 bfd_elf_generic_reloc,
00570 "R_PPC64_UADDR32",
00571 FALSE,
00572 0,
00573 0xffffffff,
00574 FALSE),
00575
00576
00577 HOWTO (R_PPC64_UADDR16,
00578 0,
00579 1,
00580 16,
00581 FALSE,
00582 0,
00583 complain_overflow_bitfield,
00584 bfd_elf_generic_reloc,
00585 "R_PPC64_UADDR16",
00586 FALSE,
00587 0,
00588 0xffff,
00589 FALSE),
00590
00591
00592 HOWTO (R_PPC64_REL32,
00593 0,
00594 2,
00595 32,
00596 TRUE,
00597 0,
00598
00599 complain_overflow_signed,
00600 bfd_elf_generic_reloc,
00601 "R_PPC64_REL32",
00602 FALSE,
00603 0,
00604 0xffffffff,
00605 TRUE),
00606
00607
00608 HOWTO (R_PPC64_PLT32,
00609 0,
00610 2,
00611 32,
00612 FALSE,
00613 0,
00614 complain_overflow_bitfield,
00615 ppc64_elf_unhandled_reloc,
00616 "R_PPC64_PLT32",
00617 FALSE,
00618 0,
00619 0xffffffff,
00620 FALSE),
00621
00622
00623
00624 HOWTO (R_PPC64_PLTREL32,
00625 0,
00626 2,
00627 32,
00628 TRUE,
00629 0,
00630 complain_overflow_signed,
00631 bfd_elf_generic_reloc,
00632 "R_PPC64_PLTREL32",
00633 FALSE,
00634 0,
00635 0xffffffff,
00636 TRUE),
00637
00638
00639
00640 HOWTO (R_PPC64_PLT16_LO,
00641 0,
00642 1,
00643 16,
00644 FALSE,
00645 0,
00646 complain_overflow_dont,
00647 ppc64_elf_unhandled_reloc,
00648 "R_PPC64_PLT16_LO",
00649 FALSE,
00650 0,
00651 0xffff,
00652 FALSE),
00653
00654
00655
00656 HOWTO (R_PPC64_PLT16_HI,
00657 16,
00658 1,
00659 16,
00660 FALSE,
00661 0,
00662 complain_overflow_dont,
00663 ppc64_elf_unhandled_reloc,
00664 "R_PPC64_PLT16_HI",
00665 FALSE,
00666 0,
00667 0xffff,
00668 FALSE),
00669
00670
00671
00672 HOWTO (R_PPC64_PLT16_HA,
00673 16,
00674 1,
00675 16,
00676 FALSE,
00677 0,
00678 complain_overflow_dont,
00679 ppc64_elf_unhandled_reloc,
00680 "R_PPC64_PLT16_HA",
00681 FALSE,
00682 0,
00683 0xffff,
00684 FALSE),
00685
00686
00687 HOWTO (R_PPC64_SECTOFF,
00688 0,
00689 1,
00690 16,
00691 FALSE,
00692 0,
00693 complain_overflow_bitfield,
00694 ppc64_elf_sectoff_reloc,
00695 "R_PPC64_SECTOFF",
00696 FALSE,
00697 0,
00698 0xffff,
00699 FALSE),
00700
00701
00702 HOWTO (R_PPC64_SECTOFF_LO,
00703 0,
00704 1,
00705 16,
00706 FALSE,
00707 0,
00708 complain_overflow_dont,
00709 ppc64_elf_sectoff_reloc,
00710 "R_PPC64_SECTOFF_LO",
00711 FALSE,
00712 0,
00713 0xffff,
00714 FALSE),
00715
00716
00717 HOWTO (R_PPC64_SECTOFF_HI,
00718 16,
00719 1,
00720 16,
00721 FALSE,
00722 0,
00723 complain_overflow_dont,
00724 ppc64_elf_sectoff_reloc,
00725 "R_PPC64_SECTOFF_HI",
00726 FALSE,
00727 0,
00728 0xffff,
00729 FALSE),
00730
00731
00732 HOWTO (R_PPC64_SECTOFF_HA,
00733 16,
00734 1,
00735 16,
00736 FALSE,
00737 0,
00738 complain_overflow_dont,
00739 ppc64_elf_sectoff_ha_reloc,
00740 "R_PPC64_SECTOFF_HA",
00741 FALSE,
00742 0,
00743 0xffff,
00744 FALSE),
00745
00746
00747 HOWTO (R_PPC64_REL30,
00748 2,
00749 2,
00750 30,
00751 TRUE,
00752 0,
00753 complain_overflow_dont,
00754 bfd_elf_generic_reloc,
00755 "R_PPC64_REL30",
00756 FALSE,
00757 0,
00758 0xfffffffc,
00759 TRUE),
00760
00761
00762
00763
00764 HOWTO (R_PPC64_ADDR64,
00765 0,
00766 4,
00767 64,
00768 FALSE,
00769 0,
00770 complain_overflow_dont,
00771 bfd_elf_generic_reloc,
00772 "R_PPC64_ADDR64",
00773 FALSE,
00774 0,
00775 ONES (64),
00776 FALSE),
00777
00778
00779 HOWTO (R_PPC64_ADDR16_HIGHER,
00780 32,
00781 1,
00782 16,
00783 FALSE,
00784 0,
00785 complain_overflow_dont,
00786 bfd_elf_generic_reloc,
00787 "R_PPC64_ADDR16_HIGHER",
00788 FALSE,
00789 0,
00790 0xffff,
00791 FALSE),
00792
00793
00794
00795 HOWTO (R_PPC64_ADDR16_HIGHERA,
00796 32,
00797 1,
00798 16,
00799 FALSE,
00800 0,
00801 complain_overflow_dont,
00802 ppc64_elf_ha_reloc,
00803 "R_PPC64_ADDR16_HIGHERA",
00804 FALSE,
00805 0,
00806 0xffff,
00807 FALSE),
00808
00809
00810 HOWTO (R_PPC64_ADDR16_HIGHEST,
00811 48,
00812 1,
00813 16,
00814 FALSE,
00815 0,
00816 complain_overflow_dont,
00817 bfd_elf_generic_reloc,
00818 "R_PPC64_ADDR16_HIGHEST",
00819 FALSE,
00820 0,
00821 0xffff,
00822 FALSE),
00823
00824
00825
00826 HOWTO (R_PPC64_ADDR16_HIGHESTA,
00827 48,
00828 1,
00829 16,
00830 FALSE,
00831 0,
00832 complain_overflow_dont,
00833 ppc64_elf_ha_reloc,
00834 "R_PPC64_ADDR16_HIGHESTA",
00835 FALSE,
00836 0,
00837 0xffff,
00838 FALSE),
00839
00840
00841 HOWTO (R_PPC64_UADDR64,
00842 0,
00843 4,
00844 64,
00845 FALSE,
00846 0,
00847 complain_overflow_dont,
00848 bfd_elf_generic_reloc,
00849 "R_PPC64_UADDR64",
00850 FALSE,
00851 0,
00852 ONES (64),
00853 FALSE),
00854
00855
00856 HOWTO (R_PPC64_REL64,
00857 0,
00858 4,
00859 64,
00860 TRUE,
00861 0,
00862 complain_overflow_dont,
00863 bfd_elf_generic_reloc,
00864 "R_PPC64_REL64",
00865 FALSE,
00866 0,
00867 ONES (64),
00868 TRUE),
00869
00870
00871 HOWTO (R_PPC64_PLT64,
00872 0,
00873 4,
00874 64,
00875 FALSE,
00876 0,
00877 complain_overflow_dont,
00878 ppc64_elf_unhandled_reloc,
00879 "R_PPC64_PLT64",
00880 FALSE,
00881 0,
00882 ONES (64),
00883 FALSE),
00884
00885
00886
00887
00888 HOWTO (R_PPC64_PLTREL64,
00889 0,
00890 4,
00891 64,
00892 TRUE,
00893 0,
00894 complain_overflow_dont,
00895 ppc64_elf_unhandled_reloc,
00896 "R_PPC64_PLTREL64",
00897 FALSE,
00898 0,
00899 ONES (64),
00900 TRUE),
00901
00902
00903
00904
00905 HOWTO (R_PPC64_TOC16,
00906 0,
00907 1,
00908 16,
00909 FALSE,
00910 0,
00911 complain_overflow_signed,
00912 ppc64_elf_toc_reloc,
00913 "R_PPC64_TOC16",
00914 FALSE,
00915 0,
00916 0xffff,
00917 FALSE),
00918
00919
00920
00921
00922 HOWTO (R_PPC64_TOC16_LO,
00923 0,
00924 1,
00925 16,
00926 FALSE,
00927 0,
00928 complain_overflow_dont,
00929 ppc64_elf_toc_reloc,
00930 "R_PPC64_TOC16_LO",
00931 FALSE,
00932 0,
00933 0xffff,
00934 FALSE),
00935
00936
00937
00938
00939 HOWTO (R_PPC64_TOC16_HI,
00940 16,
00941 1,
00942 16,
00943 FALSE,
00944 0,
00945 complain_overflow_dont,
00946 ppc64_elf_toc_reloc,
00947 "R_PPC64_TOC16_HI",
00948 FALSE,
00949 0,
00950 0xffff,
00951 FALSE),
00952
00953
00954
00955
00956
00957
00958 HOWTO (R_PPC64_TOC16_HA,
00959 16,
00960 1,
00961 16,
00962 FALSE,
00963 0,
00964 complain_overflow_dont,
00965 ppc64_elf_toc_ha_reloc,
00966 "R_PPC64_TOC16_HA",
00967 FALSE,
00968 0,
00969 0xffff,
00970 FALSE),
00971
00972
00973
00974
00975 HOWTO (R_PPC64_TOC,
00976 0,
00977 4,
00978 64,
00979 FALSE,
00980 0,
00981 complain_overflow_bitfield,
00982 ppc64_elf_toc64_reloc,
00983 "R_PPC64_TOC",
00984 FALSE,
00985 0,
00986 ONES (64),
00987 FALSE),
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998 HOWTO (R_PPC64_PLTGOT16,
00999 0,
01000 1,
01001 16,
01002 FALSE,
01003 0,
01004 complain_overflow_signed,
01005 ppc64_elf_unhandled_reloc,
01006 "R_PPC64_PLTGOT16",
01007 FALSE,
01008 0,
01009 0xffff,
01010 FALSE),
01011
01012
01013
01014 HOWTO (R_PPC64_PLTGOT16_LO,
01015 0,
01016 1,
01017 16,
01018 FALSE,
01019 0,
01020 complain_overflow_dont,
01021 ppc64_elf_unhandled_reloc,
01022 "R_PPC64_PLTGOT16_LO",
01023 FALSE,
01024 0,
01025 0xffff,
01026 FALSE),
01027
01028
01029
01030 HOWTO (R_PPC64_PLTGOT16_HI,
01031 16,
01032 1,
01033 16,
01034 FALSE,
01035 0,
01036 complain_overflow_dont,
01037 ppc64_elf_unhandled_reloc,
01038 "R_PPC64_PLTGOT16_HI",
01039 FALSE,
01040 0,
01041 0xffff,
01042 FALSE),
01043
01044
01045
01046
01047
01048 HOWTO (R_PPC64_PLTGOT16_HA,
01049 16,
01050 1,
01051 16,
01052 FALSE,
01053 0,
01054 complain_overflow_dont,
01055 ppc64_elf_unhandled_reloc,
01056 "R_PPC64_PLTGOT16_HA",
01057 FALSE,
01058 0,
01059 0xffff,
01060 FALSE),
01061
01062
01063 HOWTO (R_PPC64_ADDR16_DS,
01064 0,
01065 1,
01066 16,
01067 FALSE,
01068 0,
01069 complain_overflow_bitfield,
01070 bfd_elf_generic_reloc,
01071 "R_PPC64_ADDR16_DS",
01072 FALSE,
01073 0,
01074 0xfffc,
01075 FALSE),
01076
01077
01078 HOWTO (R_PPC64_ADDR16_LO_DS,
01079 0,
01080 1,
01081 16,
01082 FALSE,
01083 0,
01084 complain_overflow_dont,
01085 bfd_elf_generic_reloc,
01086 "R_PPC64_ADDR16_LO_DS",
01087 FALSE,
01088 0,
01089 0xfffc,
01090 FALSE),
01091
01092
01093 HOWTO (R_PPC64_GOT16_DS,
01094 0,
01095 1,
01096 16,
01097 FALSE,
01098 0,
01099 complain_overflow_signed,
01100 ppc64_elf_unhandled_reloc,
01101 "R_PPC64_GOT16_DS",
01102 FALSE,
01103 0,
01104 0xfffc,
01105 FALSE),
01106
01107
01108 HOWTO (R_PPC64_GOT16_LO_DS,
01109 0,
01110 1,
01111 16,
01112 FALSE,
01113 0,
01114 complain_overflow_dont,
01115 ppc64_elf_unhandled_reloc,
01116 "R_PPC64_GOT16_LO_DS",
01117 FALSE,
01118 0,
01119 0xfffc,
01120 FALSE),
01121
01122
01123 HOWTO (R_PPC64_PLT16_LO_DS,
01124 0,
01125 1,
01126 16,
01127 FALSE,
01128 0,
01129 complain_overflow_dont,
01130 ppc64_elf_unhandled_reloc,
01131 "R_PPC64_PLT16_LO_DS",
01132 FALSE,
01133 0,
01134 0xfffc,
01135 FALSE),
01136
01137
01138 HOWTO (R_PPC64_SECTOFF_DS,
01139 0,
01140 1,
01141 16,
01142 FALSE,
01143 0,
01144 complain_overflow_bitfield,
01145 ppc64_elf_sectoff_reloc,
01146 "R_PPC64_SECTOFF_DS",
01147 FALSE,
01148 0,
01149 0xfffc,
01150 FALSE),
01151
01152
01153 HOWTO (R_PPC64_SECTOFF_LO_DS,
01154 0,
01155 1,
01156 16,
01157 FALSE,
01158 0,
01159 complain_overflow_dont,
01160 ppc64_elf_sectoff_reloc,
01161 "R_PPC64_SECTOFF_LO_DS",
01162 FALSE,
01163 0,
01164 0xfffc,
01165 FALSE),
01166
01167
01168 HOWTO (R_PPC64_TOC16_DS,
01169 0,
01170 1,
01171 16,
01172 FALSE,
01173 0,
01174 complain_overflow_signed,
01175 ppc64_elf_toc_reloc,
01176 "R_PPC64_TOC16_DS",
01177 FALSE,
01178 0,
01179 0xfffc,
01180 FALSE),
01181
01182
01183 HOWTO (R_PPC64_TOC16_LO_DS,
01184 0,
01185 1,
01186 16,
01187 FALSE,
01188 0,
01189 complain_overflow_dont,
01190 ppc64_elf_toc_reloc,
01191 "R_PPC64_TOC16_LO_DS",
01192 FALSE,
01193 0,
01194 0xfffc,
01195 FALSE),
01196
01197
01198
01199 HOWTO (R_PPC64_PLTGOT16_DS,
01200 0,
01201 1,
01202 16,
01203 FALSE,
01204 0,
01205 complain_overflow_signed,
01206 ppc64_elf_unhandled_reloc,
01207 "R_PPC64_PLTGOT16_DS",
01208 FALSE,
01209 0,
01210 0xfffc,
01211 FALSE),
01212
01213
01214
01215 HOWTO (R_PPC64_PLTGOT16_LO_DS,
01216 0,
01217 1,
01218 16,
01219 FALSE,
01220 0,
01221 complain_overflow_dont,
01222 ppc64_elf_unhandled_reloc,
01223 "R_PPC64_PLTGOT16_LO_DS",
01224 FALSE,
01225 0,
01226 0xfffc,
01227 FALSE),
01228
01229
01230 HOWTO (R_PPC64_TLS,
01231 0,
01232 2,
01233 32,
01234 FALSE,
01235 0,
01236 complain_overflow_dont,
01237 bfd_elf_generic_reloc,
01238 "R_PPC64_TLS",
01239 FALSE,
01240 0,
01241 0,
01242 FALSE),
01243
01244
01245
01246 HOWTO (R_PPC64_DTPMOD64,
01247 0,
01248 4,
01249 64,
01250 FALSE,
01251 0,
01252 complain_overflow_dont,
01253 ppc64_elf_unhandled_reloc,
01254 "R_PPC64_DTPMOD64",
01255 FALSE,
01256 0,
01257 ONES (64),
01258 FALSE),
01259
01260
01261
01262
01263 HOWTO (R_PPC64_DTPREL64,
01264 0,
01265 4,
01266 64,
01267 FALSE,
01268 0,
01269 complain_overflow_dont,
01270 ppc64_elf_unhandled_reloc,
01271 "R_PPC64_DTPREL64",
01272 FALSE,
01273 0,
01274 ONES (64),
01275 FALSE),
01276
01277
01278 HOWTO (R_PPC64_DTPREL16,
01279 0,
01280 1,
01281 16,
01282 FALSE,
01283 0,
01284 complain_overflow_signed,
01285 ppc64_elf_unhandled_reloc,
01286 "R_PPC64_DTPREL16",
01287 FALSE,
01288 0,
01289 0xffff,
01290 FALSE),
01291
01292
01293 HOWTO (R_PPC64_DTPREL16_LO,
01294 0,
01295 1,
01296 16,
01297 FALSE,
01298 0,
01299 complain_overflow_dont,
01300 ppc64_elf_unhandled_reloc,
01301 "R_PPC64_DTPREL16_LO",
01302 FALSE,
01303 0,
01304 0xffff,
01305 FALSE),
01306
01307
01308 HOWTO (R_PPC64_DTPREL16_HI,
01309 16,
01310 1,
01311 16,
01312 FALSE,
01313 0,
01314 complain_overflow_dont,
01315 ppc64_elf_unhandled_reloc,
01316 "R_PPC64_DTPREL16_HI",
01317 FALSE,
01318 0,
01319 0xffff,
01320 FALSE),
01321
01322
01323 HOWTO (R_PPC64_DTPREL16_HA,
01324 16,
01325 1,
01326 16,
01327 FALSE,
01328 0,
01329 complain_overflow_dont,
01330 ppc64_elf_unhandled_reloc,
01331 "R_PPC64_DTPREL16_HA",
01332 FALSE,
01333 0,
01334 0xffff,
01335 FALSE),
01336
01337
01338 HOWTO (R_PPC64_DTPREL16_HIGHER,
01339 32,
01340 1,
01341 16,
01342 FALSE,
01343 0,
01344 complain_overflow_dont,
01345 ppc64_elf_unhandled_reloc,
01346 "R_PPC64_DTPREL16_HIGHER",
01347 FALSE,
01348 0,
01349 0xffff,
01350 FALSE),
01351
01352
01353 HOWTO (R_PPC64_DTPREL16_HIGHERA,
01354 32,
01355 1,
01356 16,
01357 FALSE,
01358 0,
01359 complain_overflow_dont,
01360 ppc64_elf_unhandled_reloc,
01361 "R_PPC64_DTPREL16_HIGHERA",
01362 FALSE,
01363 0,
01364 0xffff,
01365 FALSE),
01366
01367
01368 HOWTO (R_PPC64_DTPREL16_HIGHEST,
01369 48,
01370 1,
01371 16,
01372 FALSE,
01373 0,
01374 complain_overflow_dont,
01375 ppc64_elf_unhandled_reloc,
01376 "R_PPC64_DTPREL16_HIGHEST",
01377 FALSE,
01378 0,
01379 0xffff,
01380 FALSE),
01381
01382
01383 HOWTO (R_PPC64_DTPREL16_HIGHESTA,
01384 48,
01385 1,
01386 16,
01387 FALSE,
01388 0,
01389 complain_overflow_dont,
01390 ppc64_elf_unhandled_reloc,
01391 "R_PPC64_DTPREL16_HIGHESTA",
01392 FALSE,
01393 0,
01394 0xffff,
01395 FALSE),
01396
01397
01398 HOWTO (R_PPC64_DTPREL16_DS,
01399 0,
01400 1,
01401 16,
01402 FALSE,
01403 0,
01404 complain_overflow_signed,
01405 ppc64_elf_unhandled_reloc,
01406 "R_PPC64_DTPREL16_DS",
01407 FALSE,
01408 0,
01409 0xfffc,
01410 FALSE),
01411
01412
01413 HOWTO (R_PPC64_DTPREL16_LO_DS,
01414 0,
01415 1,
01416 16,
01417 FALSE,
01418 0,
01419 complain_overflow_dont,
01420 ppc64_elf_unhandled_reloc,
01421 "R_PPC64_DTPREL16_LO_DS",
01422 FALSE,
01423 0,
01424 0xfffc,
01425 FALSE),
01426
01427
01428
01429 HOWTO (R_PPC64_TPREL64,
01430 0,
01431 4,
01432 64,
01433 FALSE,
01434 0,
01435 complain_overflow_dont,
01436 ppc64_elf_unhandled_reloc,
01437 "R_PPC64_TPREL64",
01438 FALSE,
01439 0,
01440 ONES (64),
01441 FALSE),
01442
01443
01444 HOWTO (R_PPC64_TPREL16,
01445 0,
01446 1,
01447 16,
01448 FALSE,
01449 0,
01450 complain_overflow_signed,
01451 ppc64_elf_unhandled_reloc,
01452 "R_PPC64_TPREL16",
01453 FALSE,
01454 0,
01455 0xffff,
01456 FALSE),
01457
01458
01459 HOWTO (R_PPC64_TPREL16_LO,
01460 0,
01461 1,
01462 16,
01463 FALSE,
01464 0,
01465 complain_overflow_dont,
01466 ppc64_elf_unhandled_reloc,
01467 "R_PPC64_TPREL16_LO",
01468 FALSE,
01469 0,
01470 0xffff,
01471 FALSE),
01472
01473
01474 HOWTO (R_PPC64_TPREL16_HI,
01475 16,
01476 1,
01477 16,
01478 FALSE,
01479 0,
01480 complain_overflow_dont,
01481 ppc64_elf_unhandled_reloc,
01482 "R_PPC64_TPREL16_HI",
01483 FALSE,
01484 0,
01485 0xffff,
01486 FALSE),
01487
01488
01489 HOWTO (R_PPC64_TPREL16_HA,
01490 16,
01491 1,
01492 16,
01493 FALSE,
01494 0,
01495 complain_overflow_dont,
01496 ppc64_elf_unhandled_reloc,
01497 "R_PPC64_TPREL16_HA",
01498 FALSE,
01499 0,
01500 0xffff,
01501 FALSE),
01502
01503
01504 HOWTO (R_PPC64_TPREL16_HIGHER,
01505 32,
01506 1,
01507 16,
01508 FALSE,
01509 0,
01510 complain_overflow_dont,
01511 ppc64_elf_unhandled_reloc,
01512 "R_PPC64_TPREL16_HIGHER",
01513 FALSE,
01514 0,
01515 0xffff,
01516 FALSE),
01517
01518
01519 HOWTO (R_PPC64_TPREL16_HIGHERA,
01520 32,
01521 1,
01522 16,
01523 FALSE,
01524 0,
01525 complain_overflow_dont,
01526 ppc64_elf_unhandled_reloc,
01527 "R_PPC64_TPREL16_HIGHERA",
01528 FALSE,
01529 0,
01530 0xffff,
01531 FALSE),
01532
01533
01534 HOWTO (R_PPC64_TPREL16_HIGHEST,
01535 48,
01536 1,
01537 16,
01538 FALSE,
01539 0,
01540 complain_overflow_dont,
01541 ppc64_elf_unhandled_reloc,
01542 "R_PPC64_TPREL16_HIGHEST",
01543 FALSE,
01544 0,
01545 0xffff,
01546 FALSE),
01547
01548
01549 HOWTO (R_PPC64_TPREL16_HIGHESTA,
01550 48,
01551 1,
01552 16,
01553 FALSE,
01554 0,
01555 complain_overflow_dont,
01556 ppc64_elf_unhandled_reloc,
01557 "R_PPC64_TPREL16_HIGHESTA",
01558 FALSE,
01559 0,
01560 0xffff,
01561 FALSE),
01562
01563
01564 HOWTO (R_PPC64_TPREL16_DS,
01565 0,
01566 1,
01567 16,
01568 FALSE,
01569 0,
01570 complain_overflow_signed,
01571 ppc64_elf_unhandled_reloc,
01572 "R_PPC64_TPREL16_DS",
01573 FALSE,
01574 0,
01575 0xfffc,
01576 FALSE),
01577
01578
01579 HOWTO (R_PPC64_TPREL16_LO_DS,
01580 0,
01581 1,
01582 16,
01583 FALSE,
01584 0,
01585 complain_overflow_dont,
01586 ppc64_elf_unhandled_reloc,
01587 "R_PPC64_TPREL16_LO_DS",
01588 FALSE,
01589 0,
01590 0xfffc,
01591 FALSE),
01592
01593
01594
01595
01596 HOWTO (R_PPC64_GOT_TLSGD16,
01597 0,
01598 1,
01599 16,
01600 FALSE,
01601 0,
01602 complain_overflow_signed,
01603 ppc64_elf_unhandled_reloc,
01604 "R_PPC64_GOT_TLSGD16",
01605 FALSE,
01606 0,
01607 0xffff,
01608 FALSE),
01609
01610
01611 HOWTO (R_PPC64_GOT_TLSGD16_LO,
01612 0,
01613 1,
01614 16,
01615 FALSE,
01616 0,
01617 complain_overflow_dont,
01618 ppc64_elf_unhandled_reloc,
01619 "R_PPC64_GOT_TLSGD16_LO",
01620 FALSE,
01621 0,
01622 0xffff,
01623 FALSE),
01624
01625
01626 HOWTO (R_PPC64_GOT_TLSGD16_HI,
01627 16,
01628 1,
01629 16,
01630 FALSE,
01631 0,
01632 complain_overflow_dont,
01633 ppc64_elf_unhandled_reloc,
01634 "R_PPC64_GOT_TLSGD16_HI",
01635 FALSE,
01636 0,
01637 0xffff,
01638 FALSE),
01639
01640
01641 HOWTO (R_PPC64_GOT_TLSGD16_HA,
01642 16,
01643 1,
01644 16,
01645 FALSE,
01646 0,
01647 complain_overflow_dont,
01648 ppc64_elf_unhandled_reloc,
01649 "R_PPC64_GOT_TLSGD16_HA",
01650 FALSE,
01651 0,
01652 0xffff,
01653 FALSE),
01654
01655
01656
01657
01658 HOWTO (R_PPC64_GOT_TLSLD16,
01659 0,
01660 1,
01661 16,
01662 FALSE,
01663 0,
01664 complain_overflow_signed,
01665 ppc64_elf_unhandled_reloc,
01666 "R_PPC64_GOT_TLSLD16",
01667 FALSE,
01668 0,
01669 0xffff,
01670 FALSE),
01671
01672
01673 HOWTO (R_PPC64_GOT_TLSLD16_LO,
01674 0,
01675 1,
01676 16,
01677 FALSE,
01678 0,
01679 complain_overflow_dont,
01680 ppc64_elf_unhandled_reloc,
01681 "R_PPC64_GOT_TLSLD16_LO",
01682 FALSE,
01683 0,
01684 0xffff,
01685 FALSE),
01686
01687
01688 HOWTO (R_PPC64_GOT_TLSLD16_HI,
01689 16,
01690 1,
01691 16,
01692 FALSE,
01693 0,
01694 complain_overflow_dont,
01695 ppc64_elf_unhandled_reloc,
01696 "R_PPC64_GOT_TLSLD16_HI",
01697 FALSE,
01698 0,
01699 0xffff,
01700 FALSE),
01701
01702
01703 HOWTO (R_PPC64_GOT_TLSLD16_HA,
01704 16,
01705 1,
01706 16,
01707 FALSE,
01708 0,
01709 complain_overflow_dont,
01710 ppc64_elf_unhandled_reloc,
01711 "R_PPC64_GOT_TLSLD16_HA",
01712 FALSE,
01713 0,
01714 0xffff,
01715 FALSE),
01716
01717
01718
01719 HOWTO (R_PPC64_GOT_DTPREL16_DS,
01720 0,
01721 1,
01722 16,
01723 FALSE,
01724 0,
01725 complain_overflow_signed,
01726 ppc64_elf_unhandled_reloc,
01727 "R_PPC64_GOT_DTPREL16_DS",
01728 FALSE,
01729 0,
01730 0xfffc,
01731 FALSE),
01732
01733
01734 HOWTO (R_PPC64_GOT_DTPREL16_LO_DS,
01735 0,
01736 1,
01737 16,
01738 FALSE,
01739 0,
01740 complain_overflow_dont,
01741 ppc64_elf_unhandled_reloc,
01742 "R_PPC64_GOT_DTPREL16_LO_DS",
01743 FALSE,
01744 0,
01745 0xfffc,
01746 FALSE),
01747
01748
01749 HOWTO (R_PPC64_GOT_DTPREL16_HI,
01750 16,
01751 1,
01752 16,
01753 FALSE,
01754 0,
01755 complain_overflow_dont,
01756 ppc64_elf_unhandled_reloc,
01757 "R_PPC64_GOT_DTPREL16_HI",
01758 FALSE,
01759 0,
01760 0xffff,
01761 FALSE),
01762
01763
01764 HOWTO (R_PPC64_GOT_DTPREL16_HA,
01765 16,
01766 1,
01767 16,
01768 FALSE,
01769 0,
01770 complain_overflow_dont,
01771 ppc64_elf_unhandled_reloc,
01772 "R_PPC64_GOT_DTPREL16_HA",
01773 FALSE,
01774 0,
01775 0xffff,
01776 FALSE),
01777
01778
01779
01780 HOWTO (R_PPC64_GOT_TPREL16_DS,
01781 0,
01782 1,
01783 16,
01784 FALSE,
01785 0,
01786 complain_overflow_signed,
01787 ppc64_elf_unhandled_reloc,
01788 "R_PPC64_GOT_TPREL16_DS",
01789 FALSE,
01790 0,
01791 0xfffc,
01792 FALSE),
01793
01794
01795 HOWTO (R_PPC64_GOT_TPREL16_LO_DS,
01796 0,
01797 1,
01798 16,
01799 FALSE,
01800 0,
01801 complain_overflow_dont,
01802 ppc64_elf_unhandled_reloc,
01803 "R_PPC64_GOT_TPREL16_LO_DS",
01804 FALSE,
01805 0,
01806 0xfffc,
01807 FALSE),
01808
01809
01810 HOWTO (R_PPC64_GOT_TPREL16_HI,
01811 16,
01812 1,
01813 16,
01814 FALSE,
01815 0,
01816 complain_overflow_dont,
01817 ppc64_elf_unhandled_reloc,
01818 "R_PPC64_GOT_TPREL16_HI",
01819 FALSE,
01820 0,
01821 0xffff,
01822 FALSE),
01823
01824
01825 HOWTO (R_PPC64_GOT_TPREL16_HA,
01826 16,
01827 1,
01828 16,
01829 FALSE,
01830 0,
01831 complain_overflow_dont,
01832 ppc64_elf_unhandled_reloc,
01833 "R_PPC64_GOT_TPREL16_HA",
01834 FALSE,
01835 0,
01836 0xffff,
01837 FALSE),
01838
01839
01840 HOWTO (R_PPC64_GNU_VTINHERIT,
01841 0,
01842 0,
01843 0,
01844 FALSE,
01845 0,
01846 complain_overflow_dont,
01847 NULL,
01848 "R_PPC64_GNU_VTINHERIT",
01849 FALSE,
01850 0,
01851 0,
01852 FALSE),
01853
01854
01855 HOWTO (R_PPC64_GNU_VTENTRY,
01856 0,
01857 0,
01858 0,
01859 FALSE,
01860 0,
01861 complain_overflow_dont,
01862 NULL,
01863 "R_PPC64_GNU_VTENTRY",
01864 FALSE,
01865 0,
01866 0,
01867 FALSE),
01868 };
01869
01870
01871
01872
01873
01874 static void
01875 ppc_howto_init (void)
01876 {
01877 unsigned int i, type;
01878
01879 for (i = 0;
01880 i < sizeof (ppc64_elf_howto_raw) / sizeof (ppc64_elf_howto_raw[0]);
01881 i++)
01882 {
01883 type = ppc64_elf_howto_raw[i].type;
01884 BFD_ASSERT (type < (sizeof (ppc64_elf_howto_table)
01885 / sizeof (ppc64_elf_howto_table[0])));
01886 ppc64_elf_howto_table[type] = &ppc64_elf_howto_raw[i];
01887 }
01888 }
01889
01890 static reloc_howto_type *
01891 ppc64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
01892 bfd_reloc_code_real_type code)
01893 {
01894 enum elf_ppc64_reloc_type r = R_PPC64_NONE;
01895
01896 if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
01897
01898 ppc_howto_init ();
01899
01900 switch (code)
01901 {
01902 default:
01903 return NULL;
01904
01905 case BFD_RELOC_NONE: r = R_PPC64_NONE;
01906 break;
01907 case BFD_RELOC_32: r = R_PPC64_ADDR32;
01908 break;
01909 case BFD_RELOC_PPC_BA26: r = R_PPC64_ADDR24;
01910 break;
01911 case BFD_RELOC_16: r = R_PPC64_ADDR16;
01912 break;
01913 case BFD_RELOC_LO16: r = R_PPC64_ADDR16_LO;
01914 break;
01915 case BFD_RELOC_HI16: r = R_PPC64_ADDR16_HI;
01916 break;
01917 case BFD_RELOC_HI16_S: r = R_PPC64_ADDR16_HA;
01918 break;
01919 case BFD_RELOC_PPC_BA16: r = R_PPC64_ADDR14;
01920 break;
01921 case BFD_RELOC_PPC_BA16_BRTAKEN: r = R_PPC64_ADDR14_BRTAKEN;
01922 break;
01923 case BFD_RELOC_PPC_BA16_BRNTAKEN: r = R_PPC64_ADDR14_BRNTAKEN;
01924 break;
01925 case BFD_RELOC_PPC_B26: r = R_PPC64_REL24;
01926 break;
01927 case BFD_RELOC_PPC_B16: r = R_PPC64_REL14;
01928 break;
01929 case BFD_RELOC_PPC_B16_BRTAKEN: r = R_PPC64_REL14_BRTAKEN;
01930 break;
01931 case BFD_RELOC_PPC_B16_BRNTAKEN: r = R_PPC64_REL14_BRNTAKEN;
01932 break;
01933 case BFD_RELOC_16_GOTOFF: r = R_PPC64_GOT16;
01934 break;
01935 case BFD_RELOC_LO16_GOTOFF: r = R_PPC64_GOT16_LO;
01936 break;
01937 case BFD_RELOC_HI16_GOTOFF: r = R_PPC64_GOT16_HI;
01938 break;
01939 case BFD_RELOC_HI16_S_GOTOFF: r = R_PPC64_GOT16_HA;
01940 break;
01941 case BFD_RELOC_PPC_COPY: r = R_PPC64_COPY;
01942 break;
01943 case BFD_RELOC_PPC_GLOB_DAT: r = R_PPC64_GLOB_DAT;
01944 break;
01945 case BFD_RELOC_32_PCREL: r = R_PPC64_REL32;
01946 break;
01947 case BFD_RELOC_32_PLTOFF: r = R_PPC64_PLT32;
01948 break;
01949 case BFD_RELOC_32_PLT_PCREL: r = R_PPC64_PLTREL32;
01950 break;
01951 case BFD_RELOC_LO16_PLTOFF: r = R_PPC64_PLT16_LO;
01952 break;
01953 case BFD_RELOC_HI16_PLTOFF: r = R_PPC64_PLT16_HI;
01954 break;
01955 case BFD_RELOC_HI16_S_PLTOFF: r = R_PPC64_PLT16_HA;
01956 break;
01957 case BFD_RELOC_16_BASEREL: r = R_PPC64_SECTOFF;
01958 break;
01959 case BFD_RELOC_LO16_BASEREL: r = R_PPC64_SECTOFF_LO;
01960 break;
01961 case BFD_RELOC_HI16_BASEREL: r = R_PPC64_SECTOFF_HI;
01962 break;
01963 case BFD_RELOC_HI16_S_BASEREL: r = R_PPC64_SECTOFF_HA;
01964 break;
01965 case BFD_RELOC_CTOR: r = R_PPC64_ADDR64;
01966 break;
01967 case BFD_RELOC_64: r = R_PPC64_ADDR64;
01968 break;
01969 case BFD_RELOC_PPC64_HIGHER: r = R_PPC64_ADDR16_HIGHER;
01970 break;
01971 case BFD_RELOC_PPC64_HIGHER_S: r = R_PPC64_ADDR16_HIGHERA;
01972 break;
01973 case BFD_RELOC_PPC64_HIGHEST: r = R_PPC64_ADDR16_HIGHEST;
01974 break;
01975 case BFD_RELOC_PPC64_HIGHEST_S: r = R_PPC64_ADDR16_HIGHESTA;
01976 break;
01977 case BFD_RELOC_64_PCREL: r = R_PPC64_REL64;
01978 break;
01979 case BFD_RELOC_64_PLTOFF: r = R_PPC64_PLT64;
01980 break;
01981 case BFD_RELOC_64_PLT_PCREL: r = R_PPC64_PLTREL64;
01982 break;
01983 case BFD_RELOC_PPC_TOC16: r = R_PPC64_TOC16;
01984 break;
01985 case BFD_RELOC_PPC64_TOC16_LO: r = R_PPC64_TOC16_LO;
01986 break;
01987 case BFD_RELOC_PPC64_TOC16_HI: r = R_PPC64_TOC16_HI;
01988 break;
01989 case BFD_RELOC_PPC64_TOC16_HA: r = R_PPC64_TOC16_HA;
01990 break;
01991 case BFD_RELOC_PPC64_TOC: r = R_PPC64_TOC;
01992 break;
01993 case BFD_RELOC_PPC64_PLTGOT16: r = R_PPC64_PLTGOT16;
01994 break;
01995 case BFD_RELOC_PPC64_PLTGOT16_LO: r = R_PPC64_PLTGOT16_LO;
01996 break;
01997 case BFD_RELOC_PPC64_PLTGOT16_HI: r = R_PPC64_PLTGOT16_HI;
01998 break;
01999 case BFD_RELOC_PPC64_PLTGOT16_HA: r = R_PPC64_PLTGOT16_HA;
02000 break;
02001 case BFD_RELOC_PPC64_ADDR16_DS: r = R_PPC64_ADDR16_DS;
02002 break;
02003 case BFD_RELOC_PPC64_ADDR16_LO_DS: r = R_PPC64_ADDR16_LO_DS;
02004 break;
02005 case BFD_RELOC_PPC64_GOT16_DS: r = R_PPC64_GOT16_DS;
02006 break;
02007 case BFD_RELOC_PPC64_GOT16_LO_DS: r = R_PPC64_GOT16_LO_DS;
02008 break;
02009 case BFD_RELOC_PPC64_PLT16_LO_DS: r = R_PPC64_PLT16_LO_DS;
02010 break;
02011 case BFD_RELOC_PPC64_SECTOFF_DS: r = R_PPC64_SECTOFF_DS;
02012 break;
02013 case BFD_RELOC_PPC64_SECTOFF_LO_DS: r = R_PPC64_SECTOFF_LO_DS;
02014 break;
02015 case BFD_RELOC_PPC64_TOC16_DS: r = R_PPC64_TOC16_DS;
02016 break;
02017 case BFD_RELOC_PPC64_TOC16_LO_DS: r = R_PPC64_TOC16_LO_DS;
02018 break;
02019 case BFD_RELOC_PPC64_PLTGOT16_DS: r = R_PPC64_PLTGOT16_DS;
02020 break;
02021 case BFD_RELOC_PPC64_PLTGOT16_LO_DS: r = R_PPC64_PLTGOT16_LO_DS;
02022 break;
02023 case BFD_RELOC_PPC_TLS: r = R_PPC64_TLS;
02024 break;
02025 case BFD_RELOC_PPC_DTPMOD: r = R_PPC64_DTPMOD64;
02026 break;
02027 case BFD_RELOC_PPC_TPREL16: r = R_PPC64_TPREL16;
02028 break;
02029 case BFD_RELOC_PPC_TPREL16_LO: r = R_PPC64_TPREL16_LO;
02030 break;
02031 case BFD_RELOC_PPC_TPREL16_HI: r = R_PPC64_TPREL16_HI;
02032 break;
02033 case BFD_RELOC_PPC_TPREL16_HA: r = R_PPC64_TPREL16_HA;
02034 break;
02035 case BFD_RELOC_PPC_TPREL: r = R_PPC64_TPREL64;
02036 break;
02037 case BFD_RELOC_PPC_DTPREL16: r = R_PPC64_DTPREL16;
02038 break;
02039 case BFD_RELOC_PPC_DTPREL16_LO: r = R_PPC64_DTPREL16_LO;
02040 break;
02041 case BFD_RELOC_PPC_DTPREL16_HI: r = R_PPC64_DTPREL16_HI;
02042 break;
02043 case BFD_RELOC_PPC_DTPREL16_HA: r = R_PPC64_DTPREL16_HA;
02044 break;
02045 case BFD_RELOC_PPC_DTPREL: r = R_PPC64_DTPREL64;
02046 break;
02047 case BFD_RELOC_PPC_GOT_TLSGD16: r = R_PPC64_GOT_TLSGD16;
02048 break;
02049 case BFD_RELOC_PPC_GOT_TLSGD16_LO: r = R_PPC64_GOT_TLSGD16_LO;
02050 break;
02051 case BFD_RELOC_PPC_GOT_TLSGD16_HI: r = R_PPC64_GOT_TLSGD16_HI;
02052 break;
02053 case BFD_RELOC_PPC_GOT_TLSGD16_HA: r = R_PPC64_GOT_TLSGD16_HA;
02054 break;
02055 case BFD_RELOC_PPC_GOT_TLSLD16: r = R_PPC64_GOT_TLSLD16;
02056 break;
02057 case BFD_RELOC_PPC_GOT_TLSLD16_LO: r = R_PPC64_GOT_TLSLD16_LO;
02058 break;
02059 case BFD_RELOC_PPC_GOT_TLSLD16_HI: r = R_PPC64_GOT_TLSLD16_HI;
02060 break;
02061 case BFD_RELOC_PPC_GOT_TLSLD16_HA: r = R_PPC64_GOT_TLSLD16_HA;
02062 break;
02063 case BFD_RELOC_PPC_GOT_TPREL16: r = R_PPC64_GOT_TPREL16_DS;
02064 break;
02065 case BFD_RELOC_PPC_GOT_TPREL16_LO: r = R_PPC64_GOT_TPREL16_LO_DS;
02066 break;
02067 case BFD_RELOC_PPC_GOT_TPREL16_HI: r = R_PPC64_GOT_TPREL16_HI;
02068 break;
02069 case BFD_RELOC_PPC_GOT_TPREL16_HA: r = R_PPC64_GOT_TPREL16_HA;
02070 break;
02071 case BFD_RELOC_PPC_GOT_DTPREL16: r = R_PPC64_GOT_DTPREL16_DS;
02072 break;
02073 case BFD_RELOC_PPC_GOT_DTPREL16_LO: r = R_PPC64_GOT_DTPREL16_LO_DS;
02074 break;
02075 case BFD_RELOC_PPC_GOT_DTPREL16_HI: r = R_PPC64_GOT_DTPREL16_HI;
02076 break;
02077 case BFD_RELOC_PPC_GOT_DTPREL16_HA: r = R_PPC64_GOT_DTPREL16_HA;
02078 break;
02079 case BFD_RELOC_PPC64_TPREL16_DS: r = R_PPC64_TPREL16_DS;
02080 break;
02081 case BFD_RELOC_PPC64_TPREL16_LO_DS: r = R_PPC64_TPREL16_LO_DS;
02082 break;
02083 case BFD_RELOC_PPC64_TPREL16_HIGHER: r = R_PPC64_TPREL16_HIGHER;
02084 break;
02085 case BFD_RELOC_PPC64_TPREL16_HIGHERA: r = R_PPC64_TPREL16_HIGHERA;
02086 break;
02087 case BFD_RELOC_PPC64_TPREL16_HIGHEST: r = R_PPC64_TPREL16_HIGHEST;
02088 break;
02089 case BFD_RELOC_PPC64_TPREL16_HIGHESTA: r = R_PPC64_TPREL16_HIGHESTA;
02090 break;
02091 case BFD_RELOC_PPC64_DTPREL16_DS: r = R_PPC64_DTPREL16_DS;
02092 break;
02093 case BFD_RELOC_PPC64_DTPREL16_LO_DS: r = R_PPC64_DTPREL16_LO_DS;
02094 break;
02095 case BFD_RELOC_PPC64_DTPREL16_HIGHER: r = R_PPC64_DTPREL16_HIGHER;
02096 break;
02097 case BFD_RELOC_PPC64_DTPREL16_HIGHERA: r = R_PPC64_DTPREL16_HIGHERA;
02098 break;
02099 case BFD_RELOC_PPC64_DTPREL16_HIGHEST: r = R_PPC64_DTPREL16_HIGHEST;
02100 break;
02101 case BFD_RELOC_PPC64_DTPREL16_HIGHESTA: r = R_PPC64_DTPREL16_HIGHESTA;
02102 break;
02103 case BFD_RELOC_VTABLE_INHERIT: r = R_PPC64_GNU_VTINHERIT;
02104 break;
02105 case BFD_RELOC_VTABLE_ENTRY: r = R_PPC64_GNU_VTENTRY;
02106 break;
02107 }
02108
02109 return ppc64_elf_howto_table[r];
02110 };
02111
02112
02113
02114 static void
02115 ppc64_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
02116 Elf_Internal_Rela *dst)
02117 {
02118 unsigned int type;
02119
02120
02121 if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
02122 ppc_howto_init ();
02123
02124 type = ELF64_R_TYPE (dst->r_info);
02125 BFD_ASSERT (type < (sizeof (ppc64_elf_howto_table)
02126 / sizeof (ppc64_elf_howto_table[0])));
02127 cache_ptr->howto = ppc64_elf_howto_table[type];
02128 }
02129
02130
02131
02132 static bfd_reloc_status_type
02133 ppc64_elf_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
02134 void *data, asection *input_section,
02135 bfd *output_bfd, char **error_message)
02136 {
02137
02138
02139
02140 if (output_bfd != NULL)
02141 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
02142 input_section, output_bfd, error_message);
02143
02144
02145
02146
02147 reloc_entry->addend += 0x8000;
02148 return bfd_reloc_continue;
02149 }
02150
02151 static bfd_reloc_status_type
02152 ppc64_elf_branch_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
02153 void *data, asection *input_section,
02154 bfd *output_bfd, char **error_message)
02155 {
02156 if (output_bfd != NULL)
02157 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
02158 input_section, output_bfd, error_message);
02159
02160 if (strcmp (symbol->section->name, ".opd") == 0
02161 && (symbol->section->owner->flags & DYNAMIC) == 0)
02162 {
02163 bfd_vma dest = opd_entry_value (symbol->section,
02164 symbol->value + reloc_entry->addend,
02165 NULL, NULL);
02166 if (dest != (bfd_vma) -1)
02167 reloc_entry->addend = dest - (symbol->value
02168 + symbol->section->output_section->vma
02169 + symbol->section->output_offset);
02170 }
02171 return bfd_reloc_continue;
02172 }
02173
02174 static bfd_reloc_status_type
02175 ppc64_elf_brtaken_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
02176 void *data, asection *input_section,
02177 bfd *output_bfd, char **error_message)
02178 {
02179 long insn;
02180 enum elf_ppc64_reloc_type r_type;
02181 bfd_size_type octets;
02182
02183 bfd_boolean is_power4 = FALSE;
02184
02185
02186
02187
02188 if (output_bfd != NULL)
02189 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
02190 input_section, output_bfd, error_message);
02191
02192 octets = reloc_entry->address * bfd_octets_per_byte (abfd);
02193 insn = bfd_get_32 (abfd, (bfd_byte *) data + octets);
02194 insn &= ~(0x01 << 21);
02195 r_type = reloc_entry->howto->type;
02196 if (r_type == R_PPC64_ADDR14_BRTAKEN
02197 || r_type == R_PPC64_REL14_BRTAKEN)
02198 insn |= 0x01 << 21;
02199
02200 if (is_power4)
02201 {
02202
02203
02204
02205 if ((insn & (0x14 << 21)) == (0x04 << 21))
02206 insn |= 0x02 << 21;
02207 else if ((insn & (0x14 << 21)) == (0x10 << 21))
02208 insn |= 0x08 << 21;
02209 else
02210 goto out;
02211 }
02212 else
02213 {
02214 bfd_vma target = 0;
02215 bfd_vma from;
02216
02217 if (!bfd_is_com_section (symbol->section))
02218 target = symbol->value;
02219 target += symbol->section->output_section->vma;
02220 target += symbol->section->output_offset;
02221 target += reloc_entry->addend;
02222
02223 from = (reloc_entry->address
02224 + input_section->output_offset
02225 + input_section->output_section->vma);
02226
02227
02228 if ((bfd_signed_vma) (target - from) < 0)
02229 insn ^= 0x01 << 21;
02230 }
02231 bfd_put_32 (abfd, insn, (bfd_byte *) data + octets);
02232 out:
02233 return ppc64_elf_branch_reloc (abfd, reloc_entry, symbol, data,
02234 input_section, output_bfd, error_message);
02235 }
02236
02237 static bfd_reloc_status_type
02238 ppc64_elf_sectoff_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
02239 void *data, asection *input_section,
02240 bfd *output_bfd, char **error_message)
02241 {
02242
02243
02244
02245 if (output_bfd != NULL)
02246 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
02247 input_section, output_bfd, error_message);
02248
02249
02250 reloc_entry->addend -= symbol->section->output_section->vma;
02251 return bfd_reloc_continue;
02252 }
02253
02254 static bfd_reloc_status_type
02255 ppc64_elf_sectoff_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
02256 void *data, asection *input_section,
02257 bfd *output_bfd, char **error_message)
02258 {
02259
02260
02261
02262 if (output_bfd != NULL)
02263 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
02264 input_section, output_bfd, error_message);
02265
02266
02267 reloc_entry->addend -= symbol->section->output_section->vma;
02268
02269
02270 reloc_entry->addend += 0x8000;
02271 return bfd_reloc_continue;
02272 }
02273
02274 static bfd_reloc_status_type
02275 ppc64_elf_toc_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
02276 void *data, asection *input_section,
02277 bfd *output_bfd, char **error_message)
02278 {
02279 bfd_vma TOCstart;
02280
02281
02282
02283
02284 if (output_bfd != NULL)
02285 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
02286 input_section, output_bfd, error_message);
02287
02288 TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
02289 if (TOCstart == 0)
02290 TOCstart = ppc64_elf_toc (input_section->output_section->owner);
02291
02292
02293 reloc_entry->addend -= TOCstart + TOC_BASE_OFF;
02294 return bfd_reloc_continue;
02295 }
02296
02297 static bfd_reloc_status_type
02298 ppc64_elf_toc_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
02299 void *data, asection *input_section,
02300 bfd *output_bfd, char **error_message)
02301 {
02302 bfd_vma TOCstart;
02303
02304
02305
02306
02307 if (output_bfd != NULL)
02308 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
02309 input_section, output_bfd, error_message);
02310
02311 TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
02312 if (TOCstart == 0)
02313 TOCstart = ppc64_elf_toc (input_section->output_section->owner);
02314
02315
02316 reloc_entry->addend -= TOCstart + TOC_BASE_OFF;
02317
02318
02319 reloc_entry->addend += 0x8000;
02320 return bfd_reloc_continue;
02321 }
02322
02323 static bfd_reloc_status_type
02324 ppc64_elf_toc64_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
02325 void *data, asection *input_section,
02326 bfd *output_bfd, char **error_message)
02327 {
02328 bfd_vma TOCstart;
02329 bfd_size_type octets;
02330
02331
02332
02333
02334 if (output_bfd != NULL)
02335 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
02336 input_section, output_bfd, error_message);
02337
02338 TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
02339 if (TOCstart == 0)
02340 TOCstart = ppc64_elf_toc (input_section->output_section->owner);
02341
02342 octets = reloc_entry->address * bfd_octets_per_byte (abfd);
02343 bfd_put_64 (abfd, TOCstart + TOC_BASE_OFF, (bfd_byte *) data + octets);
02344 return bfd_reloc_ok;
02345 }
02346
02347 static bfd_reloc_status_type
02348 ppc64_elf_unhandled_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
02349 void *data, asection *input_section,
02350 bfd *output_bfd, char **error_message)
02351 {
02352
02353
02354
02355 if (output_bfd != NULL)
02356 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
02357 input_section, output_bfd, error_message);
02358
02359 if (error_message != NULL)
02360 {
02361 static char buf[60];
02362 sprintf (buf, "generic linker can't handle %s",
02363 reloc_entry->howto->name);
02364 *error_message = buf;
02365 }
02366 return bfd_reloc_dangerous;
02367 }
02368
02369 struct ppc64_elf_obj_tdata
02370 {
02371 struct elf_obj_tdata elf;
02372
02373
02374 asection *got;
02375 asection *relgot;
02376
02377 union {
02378
02379
02380 asection *deleted_section;
02381
02382
02383 bfd_boolean has_dotsym;
02384 } u;
02385
02386
02387
02388 union {
02389 bfd_signed_vma refcount;
02390 bfd_vma offset;
02391 } tlsld_got;
02392
02393
02394 Elf_Internal_Rela *opd_relocs;
02395 };
02396
02397 #define ppc64_elf_tdata(bfd) \
02398 ((struct ppc64_elf_obj_tdata *) (bfd)->tdata.any)
02399
02400 #define ppc64_tlsld_got(bfd) \
02401 (&ppc64_elf_tdata (bfd)->tlsld_got)
02402
02403
02404
02405 static bfd_boolean
02406 ppc64_elf_mkobject (bfd *abfd)
02407 {
02408 bfd_size_type amt = sizeof (struct ppc64_elf_obj_tdata);
02409 abfd->tdata.any = bfd_zalloc (abfd, amt);
02410 if (abfd->tdata.any == NULL)
02411 return FALSE;
02412 return TRUE;
02413 }
02414
02415
02416
02417 static bfd_boolean
02418 is_ppc64_elf_target (const struct bfd_target *targ)
02419 {
02420 extern const bfd_target bfd_elf64_powerpc_vec;
02421 extern const bfd_target bfd_elf64_powerpcle_vec;
02422
02423 return targ == &bfd_elf64_powerpc_vec || targ == &bfd_elf64_powerpcle_vec;
02424 }
02425
02426
02427
02428
02429 static bfd_boolean
02430 ppc64_elf_object_p (bfd *abfd)
02431 {
02432 if (abfd->arch_info->the_default && abfd->arch_info->bits_per_word == 32)
02433 {
02434 Elf_Internal_Ehdr *i_ehdr = elf_elfheader (abfd);
02435
02436 if (i_ehdr->e_ident[EI_CLASS] == ELFCLASS64)
02437 {
02438
02439 abfd->arch_info = abfd->arch_info->next;
02440 BFD_ASSERT (abfd->arch_info->bits_per_word == 64);
02441 }
02442 }
02443 return TRUE;
02444 }
02445
02446
02447
02448 static bfd_boolean
02449 ppc64_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
02450 {
02451 size_t offset, size;
02452
02453 if (note->descsz != 504)
02454 return FALSE;
02455
02456
02457 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
02458
02459
02460 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 32);
02461
02462
02463 offset = 112;
02464 size = 384;
02465
02466
02467 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
02468 size, note->descpos + offset);
02469 }
02470
02471 static bfd_boolean
02472 ppc64_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
02473 {
02474 if (note->descsz != 136)
02475 return FALSE;
02476
02477 elf_tdata (abfd)->core_program
02478 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
02479 elf_tdata (abfd)->core_command
02480 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
02481
02482 return TRUE;
02483 }
02484
02485
02486
02487
02488 static bfd_boolean
02489 ppc64_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
02490 {
02491
02492 if (ibfd->xvec->byteorder != obfd->xvec->byteorder
02493 && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
02494 && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
02495 {
02496 const char *msg;
02497
02498 if (bfd_big_endian (ibfd))
02499 msg = _("%B: compiled for a big endian system "
02500 "and target is little endian");
02501 else
02502 msg = _("%B: compiled for a little endian system "
02503 "and target is big endian");
02504
02505 (*_bfd_error_handler) (msg, ibfd);
02506
02507 bfd_set_error (bfd_error_wrong_format);
02508 return FALSE;
02509 }
02510
02511 return TRUE;
02512 }
02513
02514
02515
02516 static struct bfd_elf_special_section const ppc64_elf_special_sections[]=
02517 {
02518 { ".sdata", 6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
02519 { ".sbss", 5, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
02520 { ".plt", 4, 0, SHT_NOBITS, 0 },
02521 { ".toc", 4, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
02522 { ".toc1", 5, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
02523 { ".tocbss", 7, 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
02524 { NULL, 0, 0, 0, 0 }
02525 };
02526
02527 struct _ppc64_elf_section_data
02528 {
02529 struct bfd_elf_section_data elf;
02530
02531
02532 union
02533 {
02534
02535 asection **func_sec;
02536
02537 long *adjust;
02538 } opd;
02539
02540
02541
02542 unsigned *t_symndx;
02543 };
02544
02545 #define ppc64_elf_section_data(sec) \
02546 ((struct _ppc64_elf_section_data *) elf_section_data (sec))
02547
02548 static bfd_boolean
02549 ppc64_elf_new_section_hook (bfd *abfd, asection *sec)
02550 {
02551 struct _ppc64_elf_section_data *sdata;
02552 bfd_size_type amt = sizeof (*sdata);
02553
02554 sdata = bfd_zalloc (abfd, amt);
02555 if (sdata == NULL)
02556 return FALSE;
02557 sec->used_by_bfd = sdata;
02558
02559 return _bfd_elf_new_section_hook (abfd, sec);
02560 }
02561
02562 static void *
02563 get_opd_info (asection * sec)
02564 {
02565 if (sec != NULL
02566 && ppc64_elf_section_data (sec) != NULL
02567 && ppc64_elf_section_data (sec)->opd.adjust != NULL)
02568 return ppc64_elf_section_data (sec)->opd.adjust;
02569 return NULL;
02570 }
02571
02572
02573 static asection *synthetic_opd;
02574 static bfd_boolean synthetic_relocatable;
02575
02576
02577
02578 static int
02579 compare_symbols (const void *ap, const void *bp)
02580 {
02581 const asymbol *a = * (const asymbol **) ap;
02582 const asymbol *b = * (const asymbol **) bp;
02583
02584
02585 if ((a->flags & BSF_SECTION_SYM) && !(b->flags & BSF_SECTION_SYM))
02586 return -1;
02587 if (!(a->flags & BSF_SECTION_SYM) && (b->flags & BSF_SECTION_SYM))
02588 return 1;
02589
02590
02591 if (a->section == synthetic_opd && b->section != synthetic_opd)
02592 return -1;
02593 if (a->section != synthetic_opd && b->section == synthetic_opd)
02594 return 1;
02595
02596
02597 if ((a->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
02598 == (SEC_CODE | SEC_ALLOC)
02599 && (b->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
02600 != (SEC_CODE | SEC_ALLOC))
02601 return -1;
02602
02603 if ((a->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
02604 != (SEC_CODE | SEC_ALLOC)
02605 && (b->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
02606 == (SEC_CODE | SEC_ALLOC))
02607 return 1;
02608
02609 if (synthetic_relocatable)
02610 {
02611 if (a->section->id < b->section->id)
02612 return -1;
02613
02614 if (a->section->id > b->section->id)
02615 return 1;
02616 }
02617
02618 if (a->value + a->section->vma < b->value + b->section->vma)
02619 return -1;
02620
02621 if (a->value + a->section->vma > b->value + b->section->vma)
02622 return 1;
02623
02624 return 0;
02625 }
02626
02627
02628
02629 static asymbol *
02630 sym_exists_at (asymbol **syms, long lo, long hi, int id, bfd_vma value)
02631 {
02632 long mid;
02633
02634 if (id == -1)
02635 {
02636 while (lo < hi)
02637 {
02638 mid = (lo + hi) >> 1;
02639 if (syms[mid]->value + syms[mid]->section->vma < value)
02640 lo = mid + 1;
02641 else if (syms[mid]->value + syms[mid]->section->vma > value)
02642 hi = mid;
02643 else
02644 return syms[mid];
02645 }
02646 }
02647 else
02648 {
02649 while (lo < hi)
02650 {
02651 mid = (lo + hi) >> 1;
02652 if (syms[mid]->section->id < id)
02653 lo = mid + 1;
02654 else if (syms[mid]->section->id > id)
02655 hi = mid;
02656 else if (syms[mid]->value < value)
02657 lo = mid + 1;
02658 else if (syms[mid]->value > value)
02659 hi = mid;
02660 else
02661 return syms[mid];
02662 }
02663 }
02664 return NULL;
02665 }
02666
02667
02668
02669
02670 static long
02671 ppc64_elf_get_synthetic_symtab (bfd *abfd,
02672 long static_count, asymbol **static_syms,
02673 long dyn_count, asymbol **dyn_syms,
02674 asymbol **ret)
02675 {
02676 asymbol *s;
02677 long i;
02678 long count;
02679 char *names;
02680 long symcount, codesecsym, codesecsymend, secsymend, opdsymend;
02681 asection *opd;
02682 bfd_boolean relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0;
02683 asymbol **syms;
02684
02685 *ret = NULL;
02686
02687 opd = bfd_get_section_by_name (abfd, ".opd");
02688 if (opd == NULL)
02689 return 0;
02690
02691 symcount = static_count;
02692 if (!relocatable)
02693 symcount += dyn_count;
02694 if (symcount == 0)
02695 return 0;
02696
02697 syms = bfd_malloc ((symcount + 1) * sizeof (*syms));
02698 if (syms == NULL)
02699 return -1;
02700
02701 if (!relocatable && static_count != 0 && dyn_count != 0)
02702 {
02703
02704 memcpy (syms, static_syms, static_count * sizeof (*syms));
02705 memcpy (syms + static_count, dyn_syms, (dyn_count + 1) * sizeof (*syms));
02706 }
02707 else if (!relocatable && static_count == 0)
02708 memcpy (syms, dyn_syms, (symcount + 1) * sizeof (*syms));
02709 else
02710 memcpy (syms, static_syms, (symcount + 1) * sizeof (*syms));
02711
02712 synthetic_opd = opd;
02713 synthetic_relocatable = relocatable;
02714 qsort (syms, symcount, sizeof (*syms), compare_symbols);
02715
02716 if (!relocatable && symcount > 1)
02717 {
02718 long j;
02719
02720
02721
02722 for (i = 1, j = 1; i < symcount; ++i)
02723 if (syms[i - 1]->value + syms[i - 1]->section->vma
02724 != syms[i]->value + syms[i]->section->vma)
02725 syms[j++] = syms[i];
02726 symcount = j;
02727 }
02728
02729 i = 0;
02730 if (syms[i]->section == opd)
02731 ++i;
02732 codesecsym = i;
02733
02734 for (; i < symcount; ++i)
02735 if (((syms[i]->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
02736 != (SEC_CODE | SEC_ALLOC))
02737 || (syms[i]->flags & BSF_SECTION_SYM) == 0)
02738 break;
02739 codesecsymend = i;
02740
02741 for (; i < symcount; ++i)
02742 if ((syms[i]->flags & BSF_SECTION_SYM) == 0)
02743 break;
02744 secsymend = i;
02745
02746 for (; i < symcount; ++i)
02747 if (syms[i]->section != opd)
02748 break;
02749 opdsymend = i;
02750
02751 for (; i < symcount; ++i)
02752 if ((syms[i]->section->flags & (SEC_CODE | SEC_ALLOC | SEC_THREAD_LOCAL))
02753 != (SEC_CODE | SEC_ALLOC))
02754 break;
02755 symcount = i;
02756
02757 count = 0;
02758 if (opdsymend == secsymend)
02759 goto done;
02760
02761 if (relocatable)
02762 {
02763 bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
02764 arelent *r;
02765 size_t size;
02766 long relcount;
02767
02768 slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
02769 relcount = (opd->flags & SEC_RELOC) ? opd->reloc_count : 0;
02770 if (relcount == 0)
02771 goto done;
02772
02773 if (!(*slurp_relocs) (abfd, opd, static_syms, FALSE))
02774 {
02775 count = -1;
02776 goto done;
02777 }
02778
02779 size = 0;
02780 for (i = secsymend, r = opd->relocation; i < opdsymend; ++i)
02781 {
02782 asymbol *sym;
02783
02784 while (r < opd->relocation + relcount
02785 && r->address < syms[i]->value + opd->vma)
02786 ++r;
02787
02788 if (r == opd->relocation + relcount)
02789 break;
02790
02791 if (r->address != syms[i]->value + opd->vma)
02792 continue;
02793
02794 if (r->howto->type != R_PPC64_ADDR64)
02795 continue;
02796
02797 sym = *r->sym_ptr_ptr;
02798 if (!sym_exists_at (syms, opdsymend, symcount,
02799 sym->section->id, sym->value + r->addend))
02800 {
02801 ++count;
02802 size += sizeof (asymbol);
02803 size += strlen (syms[i]->name) + 2;
02804 }
02805 }
02806
02807 s = *ret = bfd_malloc (size);
02808 if (s == NULL)
02809 {
02810 count = -1;
02811 goto done;
02812 }
02813
02814 names = (char *) (s + count);
02815
02816 for (i = secsymend, r = opd->relocation; i < opdsymend; ++i)
02817 {
02818 asymbol *sym;
02819
02820 while (r < opd->relocation + relcount
02821 && r->address < syms[i]->value + opd->vma)
02822 ++r;
02823
02824 if (r == opd->relocation + relcount)
02825 break;
02826
02827 if (r->address != syms[i]->value + opd->vma)
02828 continue;
02829
02830 if (r->howto->type != R_PPC64_ADDR64)
02831 continue;
02832
02833 sym = *r->sym_ptr_ptr;
02834 if (!sym_exists_at (syms, opdsymend, symcount,
02835 sym->section->id, sym->value + r->addend))
02836 {
02837 size_t len;
02838
02839 *s = *syms[i];
02840 s->section = sym->section;
02841 s->value = sym->value + r->addend;
02842 s->name = names;
02843 *names++ = '.';
02844 len = strlen (syms[i]->name);
02845 memcpy (names, syms[i]->name, len + 1);
02846 names += len + 1;
02847 s++;
02848 }
02849 }
02850 }
02851 else
02852 {
02853 bfd_byte *contents;
02854 size_t size;
02855
02856 if (!bfd_malloc_and_get_section (abfd, opd, &contents))
02857 {
02858 if (contents)
02859 {
02860 free_contents_and_exit:
02861 free (contents);
02862 }
02863 count = -1;
02864 goto done;
02865 }
02866
02867 size = 0;
02868 for (i = secsymend; i < opdsymend; ++i)
02869 {
02870 bfd_vma ent;
02871
02872 ent = bfd_get_64 (abfd, contents + syms[i]->value);
02873 if (!sym_exists_at (syms, opdsymend, symcount, -1, ent))
02874 {
02875 ++count;
02876 size += sizeof (asymbol);
02877 size += strlen (syms[i]->name) + 2;
02878 }
02879 }
02880
02881 s = *ret = bfd_malloc (size);
02882 if (s == NULL)
02883 goto free_contents_and_exit;
02884
02885 names = (char *) (s + count);
02886
02887 for (i = secsymend; i < opdsymend; ++i)
02888 {
02889 bfd_vma ent;
02890
02891 ent = bfd_get_64 (abfd, contents + syms[i]->value);
02892 if (!sym_exists_at (syms, opdsymend, symcount, -1, ent))
02893 {
02894 long lo, hi;
02895 size_t len;
02896 asection *sec = abfd->sections;
02897
02898 *s = *syms[i];
02899 lo = codesecsym;
02900 hi = codesecsymend;
02901 while (lo < hi)
02902 {
02903 long mid = (lo + hi) >> 1;
02904 if (syms[mid]->section->vma < ent)
02905 lo = mid + 1;
02906 else if (syms[mid]->section->vma > ent)
02907 hi = mid;
02908 else
02909 {
02910 sec = syms[mid]->section;
02911 break;
02912 }
02913 }
02914
02915 if (lo >= hi && lo > codesecsym)
02916 sec = syms[lo - 1]->section;
02917
02918 for (; sec != NULL; sec = sec->next)
02919 {
02920 if (sec->vma > ent)
02921 break;
02922 if ((sec->flags & SEC_ALLOC) == 0
02923 || (sec->flags & SEC_LOAD) == 0)
02924 break;
02925 if ((sec->flags & SEC_CODE) != 0)
02926 s->section = sec;
02927 }
02928 s->value = ent - s->section->vma;
02929 s->name = names;
02930 *names++ = '.';
02931 len = strlen (syms[i]->name);
02932 memcpy (names, syms[i]->name, len + 1);
02933 names += len + 1;
02934 s++;
02935 }
02936 }
02937 free (contents);
02938 }
02939
02940 done:
02941 free (syms);
02942 return count;
02943 }
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023 struct ppc_dyn_relocs
03024 {
03025 struct ppc_dyn_relocs *next;
03026
03027
03028 asection *sec;
03029
03030
03031 bfd_size_type count;
03032
03033
03034 bfd_size_type pc_count;
03035 };
03036
03037
03038
03039 struct got_entry
03040 {
03041 struct got_entry *next;
03042
03043
03044 bfd_vma addend;
03045
03046
03047
03048
03049
03050
03051
03052 bfd *owner;
03053
03054
03055
03056 char tls_type;
03057
03058
03059 union
03060 {
03061 bfd_signed_vma refcount;
03062 bfd_vma offset;
03063 } got;
03064 };
03065
03066
03067 struct plt_entry
03068 {
03069 struct plt_entry *next;
03070
03071 bfd_vma addend;
03072
03073 union
03074 {
03075 bfd_signed_vma refcount;
03076 bfd_vma offset;
03077 } plt;
03078 };
03079
03080
03081
03082
03083
03084 #define MUST_BE_DYN_RELOC(RTYPE) \
03085 ((RTYPE) != R_PPC64_REL32 \
03086 && (RTYPE) != R_PPC64_REL64 \
03087 && (RTYPE) != R_PPC64_REL30)
03088
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101
03102
03103
03104 #define ELIMINATE_COPY_RELOCS 1
03105
03106
03107
03108 #define STUB_SUFFIX ".stub"
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155 enum ppc_stub_type {
03156 ppc_stub_none,
03157 ppc_stub_long_branch,
03158 ppc_stub_long_branch_r2off,
03159 ppc_stub_plt_branch,
03160 ppc_stub_plt_branch_r2off,
03161 ppc_stub_plt_call
03162 };
03163
03164 struct ppc_stub_hash_entry {
03165
03166
03167 struct bfd_hash_entry root;
03168
03169 enum ppc_stub_type stub_type;
03170
03171
03172 asection *stub_sec;
03173
03174
03175 bfd_vma stub_offset;
03176
03177
03178
03179 bfd_vma target_value;
03180 asection *target_section;
03181
03182
03183 struct ppc_link_hash_entry *h;
03184
03185
03186 bfd_vma addend;
03187
03188
03189
03190 asection *id_sec;
03191 };
03192
03193 struct ppc_branch_hash_entry {
03194
03195
03196 struct bfd_hash_entry root;
03197
03198
03199 unsigned int offset;
03200
03201
03202 unsigned int iter;
03203 };
03204
03205 struct ppc_link_hash_entry
03206 {
03207 struct elf_link_hash_entry elf;
03208
03209
03210
03211 struct ppc_stub_hash_entry *stub_cache;
03212
03213
03214 struct ppc_dyn_relocs *dyn_relocs;
03215
03216
03217 struct ppc_link_hash_entry *oh;
03218
03219
03220 unsigned int is_func:1;
03221 unsigned int is_func_descriptor:1;
03222 unsigned int fake:1;
03223
03224
03225
03226
03227 unsigned int adjust_done:1;
03228
03229
03230 unsigned int was_undefined:1;
03231
03232
03233
03234
03235
03236
03237
03238
03239
03240 #define TLS_GD 1
03241 #define TLS_LD 2
03242 #define TLS_TPREL 4
03243 #define TLS_DTPREL 8
03244 #define TLS_TLS 16
03245 #define TLS_EXPLICIT 32
03246 #define TLS_TPRELGD 64
03247 char tls_mask;
03248 };
03249
03250
03251
03252 struct ppc_link_hash_table
03253 {
03254 struct elf_link_hash_table elf;
03255
03256
03257 struct bfd_hash_table stub_hash_table;
03258
03259
03260 struct bfd_hash_table branch_hash_table;
03261
03262
03263 bfd *stub_bfd;
03264
03265
03266 asection * (*add_stub_section) (const char *, asection *);
03267 void (*layout_sections_again) (void);
03268
03269
03270
03271 struct map_stub {
03272
03273 asection *link_sec;
03274
03275 asection *stub_sec;
03276
03277 bfd_vma toc_off;
03278 } *stub_group;
03279
03280
03281 bfd_vma toc_curr;
03282
03283
03284 int top_id;
03285
03286
03287 int top_index;
03288
03289
03290 asection **input_list;
03291
03292
03293 asection *got;
03294 asection *plt;
03295 asection *relplt;
03296 asection *dynbss;
03297 asection *relbss;
03298 asection *glink;
03299 asection *sfpr;
03300 asection *brlt;
03301 asection *relbrlt;
03302
03303
03304 struct ppc_link_hash_entry *tls_get_addr;
03305 struct ppc_link_hash_entry *tls_get_addr_fd;
03306
03307
03308 unsigned long stub_count[ppc_stub_plt_call];
03309
03310
03311 unsigned long stub_globals;
03312
03313
03314 unsigned int emit_stub_syms:1;
03315
03316
03317 unsigned int no_multi_toc:1;
03318 unsigned int multi_toc_needed:1;
03319
03320
03321 unsigned int stub_error:1;
03322
03323
03324
03325 unsigned int has_14bit_branch:1;
03326
03327
03328 unsigned int twiddled_syms:1;
03329
03330
03331 unsigned int stub_iteration;
03332
03333
03334 struct sym_sec_cache sym_sec;
03335 };
03336
03337
03338
03339 #define has_toc_reloc has_gp_reloc
03340 #define makes_toc_func_call need_finalize_relax
03341 #define call_check_in_progress reloc_done
03342
03343
03344
03345 #define ppc_hash_table(p) \
03346 ((struct ppc_link_hash_table *) ((p)->hash))
03347
03348 #define ppc_stub_hash_lookup(table, string, create, copy) \
03349 ((struct ppc_stub_hash_entry *) \
03350 bfd_hash_lookup ((table), (string), (create), (copy)))
03351
03352 #define ppc_branch_hash_lookup(table, string, create, copy) \
03353 ((struct ppc_branch_hash_entry *) \
03354 bfd_hash_lookup ((table), (string), (create), (copy)))
03355
03356
03357
03358 static struct bfd_hash_entry *
03359 stub_hash_newfunc (struct bfd_hash_entry *entry,
03360 struct bfd_hash_table *table,
03361 const char *string)
03362 {
03363
03364
03365 if (entry == NULL)
03366 {
03367 entry = bfd_hash_allocate (table, sizeof (struct ppc_stub_hash_entry));
03368 if (entry == NULL)
03369 return entry;
03370 }
03371
03372
03373 entry = bfd_hash_newfunc (entry, table, string);
03374 if (entry != NULL)
03375 {
03376 struct ppc_stub_hash_entry *eh;
03377
03378
03379 eh = (struct ppc_stub_hash_entry *) entry;
03380 eh->stub_type = ppc_stub_none;
03381 eh->stub_sec = NULL;
03382 eh->stub_offset = 0;
03383 eh->target_value = 0;
03384 eh->target_section = NULL;
03385 eh->h = NULL;
03386 eh->id_sec = NULL;
03387 }
03388
03389 return entry;
03390 }
03391
03392
03393
03394 static struct bfd_hash_entry *
03395 branch_hash_newfunc (struct bfd_hash_entry *entry,
03396 struct bfd_hash_table *table,
03397 const char *string)
03398 {
03399
03400
03401 if (entry == NULL)
03402 {
03403 entry = bfd_hash_allocate (table, sizeof (struct ppc_branch_hash_entry));
03404 if (entry == NULL)
03405 return entry;
03406 }
03407
03408
03409 entry = bfd_hash_newfunc (entry, table, string);
03410 if (entry != NULL)
03411 {
03412 struct ppc_branch_hash_entry *eh;
03413
03414
03415 eh = (struct ppc_branch_hash_entry *) entry;
03416 eh->offset = 0;
03417 eh->iter = 0;
03418 }
03419
03420 return entry;
03421 }
03422
03423
03424
03425 static struct bfd_hash_entry *
03426 link_hash_newfunc (struct bfd_hash_entry *entry,
03427 struct bfd_hash_table *table,
03428 const char *string)
03429 {
03430
03431
03432 if (entry == NULL)
03433 {
03434 entry = bfd_hash_allocate (table, sizeof (struct ppc_link_hash_entry));
03435 if (entry == NULL)
03436 return entry;
03437 }
03438
03439
03440 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
03441 if (entry != NULL)
03442 {
03443 struct ppc_link_hash_entry *eh = (struct ppc_link_hash_entry *) entry;
03444
03445 memset (&eh->stub_cache, 0,
03446 (sizeof (struct ppc_link_hash_entry)
03447 - offsetof (struct ppc_link_hash_entry, stub_cache)));
03448 }
03449
03450 return entry;
03451 }
03452
03453
03454
03455 static struct bfd_link_hash_table *
03456 ppc64_elf_link_hash_table_create (bfd *abfd)
03457 {
03458 struct ppc_link_hash_table *htab;
03459 bfd_size_type amt = sizeof (struct ppc_link_hash_table);
03460
03461 htab = bfd_zmalloc (amt);
03462 if (htab == NULL)
03463 return NULL;
03464
03465 if (! _bfd_elf_link_hash_table_init (&htab->elf, abfd, link_hash_newfunc))
03466 {
03467 free (htab);
03468 return NULL;
03469 }
03470
03471
03472 if (!bfd_hash_table_init (&htab->stub_hash_table, stub_hash_newfunc))
03473 return NULL;
03474
03475
03476 if (!bfd_hash_table_init (&htab->branch_hash_table, branch_hash_newfunc))
03477 return NULL;
03478
03479
03480
03481
03482
03483 htab->elf.init_refcount.refcount = 0;
03484 htab->elf.init_refcount.glist = NULL;
03485 htab->elf.init_offset.offset = 0;
03486 htab->elf.init_offset.glist = NULL;
03487
03488 return &htab->elf.root;
03489 }
03490
03491
03492
03493 static void
03494 ppc64_elf_link_hash_table_free (struct bfd_link_hash_table *hash)
03495 {
03496 struct ppc_link_hash_table *ret = (struct ppc_link_hash_table *) hash;
03497
03498 bfd_hash_table_free (&ret->stub_hash_table);
03499 bfd_hash_table_free (&ret->branch_hash_table);
03500 _bfd_generic_link_hash_table_free (hash);
03501 }
03502
03503
03504
03505 void
03506 ppc64_elf_init_stub_bfd (bfd *abfd, struct bfd_link_info *info)
03507 {
03508 struct ppc_link_hash_table *htab;
03509
03510 elf_elfheader (abfd)->e_ident[EI_CLASS] = ELFCLASS64;
03511
03512
03513
03514
03515 htab = ppc_hash_table (info);
03516 htab->stub_bfd = abfd;
03517 htab->elf.dynobj = abfd;
03518 }
03519
03520
03521
03522 static char *
03523 ppc_stub_name (const asection *input_section,
03524 const asection *sym_sec,
03525 const struct ppc_link_hash_entry *h,
03526 const Elf_Internal_Rela *rel)
03527 {
03528 char *stub_name;
03529 bfd_size_type len;
03530
03531
03532
03533
03534 BFD_ASSERT (((int) rel->r_addend & 0xffffffff) == rel->r_addend);
03535
03536 if (h)
03537 {
03538 len = 8 + 1 + strlen (h->elf.root.root.string) + 1 + 8 + 1;
03539 stub_name = bfd_malloc (len);
03540 if (stub_name == NULL)
03541 return stub_name;
03542
03543 sprintf (stub_name, "%08x.%s+%x",
03544 input_section->id & 0xffffffff,
03545 h->elf.root.root.string,
03546 (int) rel->r_addend & 0xffffffff);
03547 }
03548 else
03549 {
03550 len = 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1;
03551 stub_name = bfd_malloc (len);
03552 if (stub_name == NULL)
03553 return stub_name;
03554
03555 sprintf (stub_name, "%08x.%x:%x+%x",
03556 input_section->id & 0xffffffff,
03557 sym_sec->id & 0xffffffff,
03558 (int) ELF64_R_SYM (rel->r_info) & 0xffffffff,
03559 (int) rel->r_addend & 0xffffffff);
03560 }
03561 if (stub_name[len - 2] == '+' && stub_name[len - 1] == '0')
03562 stub_name[len - 2] = 0;
03563 return stub_name;
03564 }
03565
03566
03567
03568
03569 static struct ppc_stub_hash_entry *
03570 ppc_get_stub_entry (const asection *input_section,
03571 const asection *sym_sec,
03572 struct ppc_link_hash_entry *h,
03573 const Elf_Internal_Rela *rel,
03574 struct ppc_link_hash_table *htab)
03575 {
03576 struct ppc_stub_hash_entry *stub_entry;
03577 const asection *id_sec;
03578
03579
03580
03581
03582
03583
03584 id_sec = htab->stub_group[input_section->id].link_sec;
03585
03586 if (h != NULL && h->stub_cache != NULL
03587 && h->stub_cache->h == h
03588 && h->stub_cache->id_sec == id_sec)
03589 {
03590 stub_entry = h->stub_cache;
03591 }
03592 else
03593 {
03594 char *stub_name;
03595
03596 stub_name = ppc_stub_name (id_sec, sym_sec, h, rel);
03597 if (stub_name == NULL)
03598 return NULL;
03599
03600 stub_entry = ppc_stub_hash_lookup (&htab->stub_hash_table,
03601 stub_name, FALSE, FALSE);
03602 if (h != NULL)
03603 h->stub_cache = stub_entry;
03604
03605 free (stub_name);
03606 }
03607
03608 return stub_entry;
03609 }
03610
03611
03612
03613
03614 static struct ppc_stub_hash_entry *
03615 ppc_add_stub (const char *stub_name,
03616 asection *section,
03617 struct ppc_link_hash_table *htab)
03618 {
03619 asection *link_sec;
03620 asection *stub_sec;
03621 struct ppc_stub_hash_entry *stub_entry;
03622
03623 link_sec = htab->stub_group[section->id].link_sec;
03624 stub_sec = htab->stub_group[section->id].stub_sec;
03625 if (stub_sec == NULL)
03626 {
03627 stub_sec = htab->stub_group[link_sec->id].stub_sec;
03628 if (stub_sec == NULL)
03629 {
03630 size_t namelen;
03631 bfd_size_type len;
03632 char *s_name;
03633
03634 namelen = strlen (link_sec->name);
03635 len = namelen + sizeof (STUB_SUFFIX);
03636 s_name = bfd_alloc (htab->stub_bfd, len);
03637 if (s_name == NULL)
03638 return NULL;
03639
03640 memcpy (s_name, link_sec->name, namelen);
03641 memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
03642 stub_sec = (*htab->add_stub_section) (s_name, link_sec);
03643 if (stub_sec == NULL)
03644 return NULL;
03645 htab->stub_group[link_sec->id].stub_sec = stub_sec;
03646 }
03647 htab->stub_group[section->id].stub_sec = stub_sec;
03648 }
03649
03650
03651 stub_entry = ppc_stub_hash_lookup (&htab->stub_hash_table, stub_name,
03652 TRUE, FALSE);
03653 if (stub_entry == NULL)
03654 {
03655 (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
03656 section->owner, stub_name);
03657 return NULL;
03658 }
03659
03660 stub_entry->stub_sec = stub_sec;
03661 stub_entry->stub_offset = 0;
03662 stub_entry->id_sec = link_sec;
03663 return stub_entry;
03664 }
03665
03666
03667
03668 static bfd_boolean
03669 create_linkage_sections (bfd *dynobj, struct bfd_link_info *info)
03670 {
03671 struct ppc_link_hash_table *htab;
03672 flagword flags;
03673
03674 htab = ppc_hash_table (info);
03675
03676
03677 flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY
03678 | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
03679 htab->sfpr = bfd_make_section_anyway (dynobj, ".sfpr");
03680 if (htab->sfpr == NULL
03681 || ! bfd_set_section_flags (dynobj, htab->sfpr, flags)
03682 || ! bfd_set_section_alignment (dynobj, htab->sfpr, 2))
03683 return FALSE;
03684
03685
03686 htab->glink = bfd_make_section_anyway (dynobj, ".glink");
03687 if (htab->glink == NULL
03688 || ! bfd_set_section_flags (dynobj, htab->glink, flags)
03689 || ! bfd_set_section_alignment (dynobj, htab->glink, 2))
03690 return FALSE;
03691
03692
03693 flags = (SEC_ALLOC | SEC_LOAD
03694 | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
03695 htab->brlt = bfd_make_section_anyway (dynobj, ".branch_lt");
03696 if (htab->brlt == NULL
03697 || ! bfd_set_section_flags (dynobj, htab->brlt, flags)
03698 || ! bfd_set_section_alignment (dynobj, htab->brlt, 3))
03699 return FALSE;
03700
03701 if (info->shared || info->emitrelocations)
03702 {
03703 flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
03704 | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
03705 htab->relbrlt = bfd_make_section_anyway (dynobj, ".rela.branch_lt");
03706 if (!htab->relbrlt
03707 || ! bfd_set_section_flags (dynobj, htab->relbrlt, flags)
03708 || ! bfd_set_section_alignment (dynobj, htab->relbrlt, 3))
03709 return FALSE;
03710 }
03711 return TRUE;
03712 }
03713
03714
03715
03716
03717 static bfd_boolean
03718 create_got_section (bfd *abfd, struct bfd_link_info *info)
03719 {
03720 asection *got, *relgot;
03721 flagword flags;
03722 struct ppc_link_hash_table *htab = ppc_hash_table (info);
03723
03724 if (!htab->got)
03725 {
03726 if (! _bfd_elf_create_got_section (htab->elf.dynobj, info))
03727 return FALSE;
03728
03729 htab->got = bfd_get_section_by_name (htab->elf.dynobj, ".got");
03730 if (!htab->got)
03731 abort ();
03732 }
03733
03734 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
03735 | SEC_LINKER_CREATED);
03736
03737 got = bfd_make_section (abfd, ".got");
03738 if (!got
03739 || !bfd_set_section_flags (abfd, got, flags)
03740 || !bfd_set_section_alignment (abfd, got, 3))
03741 return FALSE;
03742
03743 relgot = bfd_make_section (abfd, ".rela.got");
03744 if (!relgot
03745 || ! bfd_set_section_flags (abfd, relgot, flags | SEC_READONLY)
03746 || ! bfd_set_section_alignment (abfd, relgot, 3))
03747 return FALSE;
03748
03749 ppc64_elf_tdata (abfd)->got = got;
03750 ppc64_elf_tdata (abfd)->relgot = relgot;
03751 return TRUE;
03752 }
03753
03754
03755
03756 static bfd_boolean
03757 ppc64_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
03758 {
03759 struct ppc_link_hash_table *htab;
03760
03761 if (!_bfd_elf_create_dynamic_sections (dynobj, info))
03762 return FALSE;
03763
03764 htab = ppc_hash_table (info);
03765 if (!htab->got)
03766 htab->got = bfd_get_section_by_name (dynobj, ".got");
03767 htab->plt = bfd_get_section_by_name (dynobj, ".plt");
03768 htab->relplt = bfd_get_section_by_name (dynobj, ".rela.plt");
03769 htab->dynbss = bfd_get_section_by_name (dynobj, ".dynbss");
03770 if (!info->shared)
03771 htab->relbss = bfd_get_section_by_name (dynobj, ".rela.bss");
03772
03773 if (!htab->got || !htab->plt || !htab->relplt || !htab->dynbss
03774 || (!info->shared && !htab->relbss))
03775 abort ();
03776
03777 return TRUE;
03778 }
03779
03780
03781
03782 static void
03783 move_plt_plist (struct ppc_link_hash_entry *from,
03784 struct ppc_link_hash_entry *to)
03785 {
03786 if (from->elf.plt.plist != NULL)
03787 {
03788 if (to->elf.plt.plist != NULL)
03789 {
03790 struct plt_entry **entp;
03791 struct plt_entry *ent;
03792
03793 for (entp = &from->elf.plt.plist; (ent = *entp) != NULL; )
03794 {
03795 struct plt_entry *dent;
03796
03797 for (dent = to->elf.plt.plist; dent != NULL; dent = dent->next)
03798 if (dent->addend == ent->addend)
03799 {
03800 dent->plt.refcount += ent->plt.refcount;
03801 *entp = ent->next;
03802 break;
03803 }
03804 if (dent == NULL)
03805 entp = &ent->next;
03806 }
03807 *entp = to->elf.plt.plist;
03808 }
03809
03810 to->elf.plt.plist = from->elf.plt.plist;
03811 from->elf.plt.plist = NULL;
03812 }
03813 }
03814
03815
03816
03817 static void
03818 ppc64_elf_copy_indirect_symbol
03819 (const struct elf_backend_data *bed ATTRIBUTE_UNUSED,
03820 struct elf_link_hash_entry *dir,
03821 struct elf_link_hash_entry *ind)
03822 {
03823 struct ppc_link_hash_entry *edir, *eind;
03824
03825 edir = (struct ppc_link_hash_entry *) dir;
03826 eind = (struct ppc_link_hash_entry *) ind;
03827
03828
03829 if (eind->dyn_relocs != NULL)
03830 {
03831 if (edir->dyn_relocs != NULL)
03832 {
03833 struct ppc_dyn_relocs **pp;
03834 struct ppc_dyn_relocs *p;
03835
03836 if (eind->elf.root.type == bfd_link_hash_indirect)
03837 abort ();
03838
03839
03840
03841 for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
03842 {
03843 struct ppc_dyn_relocs *q;
03844
03845 for (q = edir->dyn_relocs; q != NULL; q = q->next)
03846 if (q->sec == p->sec)
03847 {
03848 q->pc_count += p->pc_count;
03849 q->count += p->count;
03850 *pp = p->next;
03851 break;
03852 }
03853 if (q == NULL)
03854 pp = &p->next;
03855 }
03856 *pp = edir->dyn_relocs;
03857 }
03858
03859 edir->dyn_relocs = eind->dyn_relocs;
03860 eind->dyn_relocs = NULL;
03861 }
03862
03863 edir->is_func |= eind->is_func;
03864 edir->is_func_descriptor |= eind->is_func_descriptor;
03865 edir->tls_mask |= eind->tls_mask;
03866
03867
03868
03869
03870 if (!(ELIMINATE_COPY_RELOCS
03871 && eind->elf.root.type != bfd_link_hash_indirect
03872 && edir->elf.dynamic_adjusted))
03873 edir->elf.non_got_ref |= eind->elf.non_got_ref;
03874
03875 edir->elf.ref_dynamic |= eind->elf.ref_dynamic;
03876 edir->elf.ref_regular |= eind->elf.ref_regular;
03877 edir->elf.ref_regular_nonweak |= eind->elf.ref_regular_nonweak;
03878 edir->elf.needs_plt |= eind->elf.needs_plt;
03879
03880
03881 if (eind->elf.root.type != bfd_link_hash_indirect)
03882 return;
03883
03884
03885
03886 if (eind->elf.got.glist != NULL)
03887 {
03888 if (edir->elf.got.glist != NULL)
03889 {
03890 struct got_entry **entp;
03891 struct got_entry *ent;
03892
03893 for (entp = &eind->elf.got.glist; (ent = *entp) != NULL; )
03894 {
03895 struct got_entry *dent;
03896
03897 for (dent = edir->elf.got.glist; dent != NULL; dent = dent->next)
03898 if (dent->addend == ent->addend
03899 && dent->owner == ent->owner
03900 && dent->tls_type == ent->tls_type)
03901 {
03902 dent->got.refcount += ent->got.refcount;
03903 *entp = ent->next;
03904 break;
03905 }
03906 if (dent == NULL)
03907 entp = &ent->next;
03908 }
03909 *entp = edir->elf.got.glist;
03910 }
03911
03912 edir->elf.got.glist = eind->elf.got.glist;
03913 eind->elf.got.glist = NULL;
03914 }
03915
03916
03917 move_plt_plist (eind, edir);
03918
03919 if (edir->elf.dynindx == -1)
03920 {
03921 edir->elf.dynindx = eind->elf.dynindx;
03922 edir->elf.dynstr_index = eind->elf.dynstr_index;
03923 eind->elf.dynindx = -1;
03924 eind->elf.dynstr_index = 0;
03925 }
03926 else
03927 BFD_ASSERT (eind->elf.dynindx == -1);
03928 }
03929
03930
03931
03932
03933 static struct ppc_link_hash_entry *
03934 get_fdh (struct ppc_link_hash_entry *fh, struct ppc_link_hash_table *htab)
03935 {
03936 struct ppc_link_hash_entry *fdh = fh->oh;
03937
03938 if (fdh == NULL)
03939 {
03940 const char *fd_name = fh->elf.root.root.string + 1;
03941
03942 fdh = (struct ppc_link_hash_entry *)
03943 elf_link_hash_lookup (&htab->elf, fd_name, FALSE, FALSE, FALSE);
03944 if (fdh != NULL)
03945 {
03946 fdh->is_func_descriptor = 1;
03947 fdh->oh = fh;
03948 fh->is_func = 1;
03949 fh->oh = fdh;
03950 }
03951 }
03952
03953 return fdh;
03954 }
03955
03956
03957
03958 static struct ppc_link_hash_entry *
03959 make_fdh (struct bfd_link_info *info,
03960 struct ppc_link_hash_entry *fh)
03961 {
03962 bfd *abfd;
03963 asymbol *newsym;
03964 struct bfd_link_hash_entry *bh;
03965 struct ppc_link_hash_entry *fdh;
03966
03967 abfd = fh->elf.root.u.undef.abfd;
03968 newsym = bfd_make_empty_symbol (abfd);
03969 newsym->name = fh->elf.root.root.string + 1;
03970 newsym->section = bfd_und_section_ptr;
03971 newsym->value = 0;
03972 newsym->flags = BSF_WEAK;
03973
03974 bh = NULL;
03975 if (!_bfd_generic_link_add_one_symbol (info, abfd, newsym->name,
03976 newsym->flags, newsym->section,
03977 newsym->value, NULL, FALSE, FALSE,
03978 &bh))
03979 return NULL;
03980
03981 fdh = (struct ppc_link_hash_entry *) bh;
03982 fdh->elf.non_elf = 0;
03983 fdh->fake = 1;
03984 fdh->is_func_descriptor = 1;
03985 fdh->oh = fh;
03986 fh->is_func = 1;
03987 fh->oh = fdh;
03988 return fdh;
03989 }
03990
03991
03992
03993
03994
03995
03996
03997
03998
03999
04000
04001
04002
04003
04004
04005
04006
04007
04008
04009 static bfd_boolean
04010 ppc64_elf_add_symbol_hook (bfd *ibfd,
04011 struct bfd_link_info *info ATTRIBUTE_UNUSED,
04012 Elf_Internal_Sym *isym,
04013 const char **name,
04014 flagword *flags ATTRIBUTE_UNUSED,
04015 asection **sec,
04016 bfd_vma *value ATTRIBUTE_UNUSED)
04017 {
04018 if (*sec != NULL
04019 && strcmp (bfd_get_section_name (ibfd, *sec), ".opd") == 0)
04020 isym->st_info = ELF_ST_INFO (ELF_ST_BIND (isym->st_info), STT_FUNC);
04021
04022 if ((*name)[0] == '.'
04023 && ELF_ST_BIND (isym->st_info) == STB_GLOBAL
04024 && ELF_ST_TYPE (isym->st_info) < STT_SECTION
04025 && is_ppc64_elf_target (ibfd->xvec))
04026 ppc64_elf_tdata (ibfd)->u.has_dotsym = 1;
04027
04028 return TRUE;
04029 }
04030
04031
04032
04033
04034
04035
04036 static struct elf_link_hash_entry *
04037 ppc64_elf_archive_symbol_lookup (bfd *abfd,
04038 struct bfd_link_info *info,
04039 const char *name)
04040 {
04041 struct elf_link_hash_entry *h;
04042 char *dot_name;
04043 size_t len;
04044
04045 h = _bfd_elf_archive_symbol_lookup (abfd, info, name);
04046 if (h != NULL
04047
04048
04049 && !(h->root.type == bfd_link_hash_undefweak
04050 && ((struct ppc_link_hash_entry *) h)->fake))
04051 return h;
04052
04053 if (name[0] == '.')
04054 return h;
04055
04056 len = strlen (name);
04057 dot_name = bfd_alloc (abfd, len + 2);
04058 if (dot_name == NULL)
04059 return (struct elf_link_hash_entry *) 0 - 1;
04060 dot_name[0] = '.';
04061 memcpy (dot_name + 1, name, len + 1);
04062 h = _bfd_elf_archive_symbol_lookup (abfd, info, dot_name);
04063 bfd_release (abfd, dot_name);
04064 return h;
04065 }
04066
04067
04068
04069
04070
04071
04072
04073
04074
04075
04076 struct add_symbol_adjust_data
04077 {
04078 struct bfd_link_info *info;
04079 bfd_boolean ok;
04080 };
04081
04082 static bfd_boolean
04083 add_symbol_adjust (struct elf_link_hash_entry *h, void *inf)
04084 {
04085 struct add_symbol_adjust_data *data;
04086 struct ppc_link_hash_table *htab;
04087 struct ppc_link_hash_entry *eh;
04088 struct ppc_link_hash_entry *fdh;
04089
04090 if (h->root.type == bfd_link_hash_indirect)
04091 return TRUE;
04092
04093 if (h->root.type == bfd_link_hash_warning)
04094 h = (struct elf_link_hash_entry *) h->root.u.i.link;
04095
04096 if (h->root.root.string[0] != '.')
04097 return TRUE;
04098
04099 data = inf;
04100 htab = ppc_hash_table (data->info);
04101 eh = (struct ppc_link_hash_entry *) h;
04102 fdh = get_fdh (eh, htab);
04103 if (fdh == NULL
04104 && !data->info->relocatable
04105 && (eh->elf.root.type == bfd_link_hash_undefined
04106 || eh->elf.root.type == bfd_link_hash_undefweak)
04107 && eh->elf.ref_regular)
04108 {
04109
04110
04111
04112 fdh = make_fdh (data->info, eh);
04113 if (fdh == NULL)
04114 data->ok = FALSE;
04115 else
04116 fdh->elf.ref_regular = 1;
04117 }
04118 else if (fdh != NULL)
04119 {
04120 unsigned entry_vis = ELF_ST_VISIBILITY (eh->elf.other) - 1;
04121 unsigned descr_vis = ELF_ST_VISIBILITY (fdh->elf.other) - 1;
04122 if (entry_vis < descr_vis)
04123 fdh->elf.other += entry_vis - descr_vis;
04124 else if (entry_vis > descr_vis)
04125 eh->elf.other += descr_vis - entry_vis;
04126
04127 if ((fdh->elf.root.type == bfd_link_hash_defined
04128 || fdh->elf.root.type == bfd_link_hash_defweak)
04129 && eh->elf.root.type == bfd_link_hash_undefined)
04130 {
04131 eh->elf.root.type = bfd_link_hash_undefweak;
04132 eh->was_undefined = 1;
04133 htab->twiddled_syms = 1;
04134 }
04135 }
04136
04137 return TRUE;
04138 }
04139
04140 static bfd_boolean
04141 ppc64_elf_check_directives (bfd *abfd, struct bfd_link_info *info)
04142 {
04143 struct ppc_link_hash_table *htab;
04144 struct add_symbol_adjust_data data;
04145
04146 if (!is_ppc64_elf_target (abfd->xvec))
04147 return TRUE;
04148
04149 if (!ppc64_elf_tdata (abfd)->u.has_dotsym)
04150 return TRUE;
04151 ppc64_elf_tdata (abfd)->u.deleted_section = NULL;
04152
04153 htab = ppc_hash_table (info);
04154 if (!is_ppc64_elf_target (htab->elf.root.creator))
04155 return TRUE;
04156
04157 data.info = info;
04158 data.ok = TRUE;
04159 elf_link_hash_traverse (&htab->elf, add_symbol_adjust, &data);
04160
04161
04162
04163 if (htab->twiddled_syms)
04164 {
04165 bfd_link_repair_undef_list (&htab->elf.root);
04166 htab->twiddled_syms = 0;
04167 }
04168 return data.ok;
04169 }
04170
04171 static bfd_boolean
04172 update_local_sym_info (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
04173 unsigned long r_symndx, bfd_vma r_addend, int tls_type)
04174 {
04175 struct got_entry **local_got_ents = elf_local_got_ents (abfd);
04176 char *local_got_tls_masks;
04177
04178 if (local_got_ents == NULL)
04179 {
04180 bfd_size_type size = symtab_hdr->sh_info;
04181
04182 size *= sizeof (*local_got_ents) + sizeof (*local_got_tls_masks);
04183 local_got_ents = bfd_zalloc (abfd, size);
04184 if (local_got_ents == NULL)
04185 return FALSE;
04186 elf_local_got_ents (abfd) = local_got_ents;
04187 }
04188
04189 if ((tls_type & TLS_EXPLICIT) == 0)
04190 {
04191 struct got_entry *ent;
04192
04193 for (ent = local_got_ents[r_symndx]; ent != NULL; ent = ent->next)
04194 if (ent->addend == r_addend
04195 && ent->owner == abfd
04196 && ent->tls_type == tls_type)
04197 break;
04198 if (ent == NULL)
04199 {
04200 bfd_size_type amt = sizeof (*ent);
04201 ent = bfd_alloc (abfd, amt);
04202 if (ent == NULL)
04203 return FALSE;
04204 ent->next = local_got_ents[r_symndx];
04205 ent->addend = r_addend;
04206 ent->owner = abfd;
04207 ent->tls_type = tls_type;
04208 ent->got.refcount = 0;
04209 local_got_ents[r_symndx] = ent;
04210 }
04211 ent->got.refcount += 1;
04212 }
04213
04214 local_got_tls_masks = (char *) (local_got_ents + symtab_hdr->sh_info);
04215 local_got_tls_masks[r_symndx] |= tls_type;
04216 return TRUE;
04217 }
04218
04219 static bfd_boolean
04220 update_plt_info (bfd *abfd, struct ppc_link_hash_entry *eh, bfd_vma addend)
04221 {
04222 struct plt_entry *ent;
04223
04224 for (ent = eh->elf.plt.plist; ent != NULL; ent = ent->next)
04225 if (ent->addend == addend)
04226 break;
04227 if (ent == NULL)
04228 {
04229 bfd_size_type amt = sizeof (*ent);
04230 ent = bfd_alloc (abfd, amt);
04231 if (ent == NULL)
04232 return FALSE;
04233 ent->next = eh->elf.plt.plist;
04234 ent->addend = addend;
04235 ent->plt.refcount = 0;
04236 eh->elf.plt.plist = ent;
04237 }
04238 ent->plt.refcount += 1;
04239 eh->elf.needs_plt = 1;
04240 if (eh->elf.root.root.string[0] == '.'
04241 && eh->elf.root.root.string[1] != '\0')
04242 eh->is_func = 1;
04243 return TRUE;
04244 }
04245
04246
04247
04248
04249
04250 static bfd_boolean
04251 ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
04252 asection *sec, const Elf_Internal_Rela *relocs)
04253 {
04254 struct ppc_link_hash_table *htab;
04255 Elf_Internal_Shdr *symtab_hdr;
04256 struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
04257 const Elf_Internal_Rela *rel;
04258 const Elf_Internal_Rela *rel_end;
04259 asection *sreloc;
04260 asection **opd_sym_map;
04261
04262 if (info->relocatable)
04263 return TRUE;
04264
04265
04266
04267
04268
04269
04270
04271 if ((sec->flags & SEC_ALLOC) == 0)
04272 return TRUE;
04273
04274 htab = ppc_hash_table (info);
04275 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
04276
04277 sym_hashes = elf_sym_hashes (abfd);
04278 sym_hashes_end = (sym_hashes
04279 + symtab_hdr->sh_size / sizeof (Elf64_External_Sym)
04280 - symtab_hdr->sh_info);
04281
04282 sreloc = NULL;
04283 opd_sym_map = NULL;
04284 if (strcmp (bfd_get_section_name (abfd, sec), ".opd") == 0)
04285 {
04286
04287
04288
04289
04290
04291
04292
04293
04294
04295 union opd_info {
04296 asection *func_section;
04297 long entry_adjust;
04298 };
04299 bfd_size_type amt;
04300
04301 amt = sec->size * sizeof (union opd_info) / 8;
04302 opd_sym_map = bfd_zalloc (abfd, amt);
04303 if (opd_sym_map == NULL)
04304 return FALSE;
04305 ppc64_elf_section_data (sec)->opd.func_sec = opd_sym_map;
04306 }
04307
04308 if (htab->sfpr == NULL
04309 && !create_linkage_sections (htab->elf.dynobj, info))
04310 return FALSE;
04311
04312 rel_end = relocs + sec->reloc_count;
04313 for (rel = relocs; rel < rel_end; rel++)
04314 {
04315 unsigned long r_symndx;
04316 struct elf_link_hash_entry *h;
04317 enum elf_ppc64_reloc_type r_type;
04318 int tls_type = 0;
04319
04320 r_symndx = ELF64_R_SYM (rel->r_info);
04321 if (r_symndx < symtab_hdr->sh_info)
04322 h = NULL;
04323 else
04324 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
04325
04326 r_type = ELF64_R_TYPE (rel->r_info);
04327 switch (r_type)
04328 {
04329 case R_PPC64_GOT_TLSLD16:
04330 case R_PPC64_GOT_TLSLD16_LO:
04331 case R_PPC64_GOT_TLSLD16_HI:
04332 case R_PPC64_GOT_TLSLD16_HA:
04333 ppc64_tlsld_got (abfd)->refcount += 1;
04334 tls_type = TLS_TLS | TLS_LD;
04335 goto dogottls;
04336
04337 case R_PPC64_GOT_TLSGD16:
04338 case R_PPC64_GOT_TLSGD16_LO:
04339 case R_PPC64_GOT_TLSGD16_HI:
04340 case R_PPC64_GOT_TLSGD16_HA:
04341 tls_type = TLS_TLS | TLS_GD;
04342 goto dogottls;
04343
04344 case R_PPC64_GOT_TPREL16_DS:
04345 case R_PPC64_GOT_TPREL16_LO_DS:
04346 case R_PPC64_GOT_TPREL16_HI:
04347 case R_PPC64_GOT_TPREL16_HA:
04348 if (info->shared)
04349 info->flags |= DF_STATIC_TLS;
04350 tls_type = TLS_TLS | TLS_TPREL;
04351 goto dogottls;
04352
04353 case R_PPC64_GOT_DTPREL16_DS:
04354 case R_PPC64_GOT_DTPREL16_LO_DS:
04355 case R_PPC64_GOT_DTPREL16_HI:
04356 case R_PPC64_GOT_DTPREL16_HA:
04357 tls_type = TLS_TLS | TLS_DTPREL;
04358 dogottls:
04359 sec->has_tls_reloc = 1;
04360
04361
04362 case R_PPC64_GOT16:
04363 case R_PPC64_GOT16_DS:
04364 case R_PPC64_GOT16_HA:
04365 case R_PPC64_GOT16_HI:
04366 case R_PPC64_GOT16_LO:
04367 case R_PPC64_GOT16_LO_DS:
04368
04369 sec->has_toc_reloc = 1;
04370 if (ppc64_elf_tdata (abfd)->got == NULL
04371 && !create_got_section (abfd, info))
04372 return FALSE;
04373
04374 if (h != NULL)
04375 {
04376 struct ppc_link_hash_entry *eh;
04377 struct got_entry *ent;
04378
04379 eh = (struct ppc_link_hash_entry *) h;
04380 for (ent = eh->elf.got.glist; ent != NULL; ent = ent->next)
04381 if (ent->addend == rel->r_addend
04382 && ent->owner == abfd
04383 && ent->tls_type == tls_type)
04384 break;
04385 if (ent == NULL)
04386 {
04387 bfd_size_type amt = sizeof (*ent);
04388 ent = bfd_alloc (abfd, amt);
04389 if (ent == NULL)
04390 return FALSE;
04391 ent->next = eh->elf.got.glist;
04392 ent->addend = rel->r_addend;
04393 ent->owner = abfd;
04394 ent->tls_type = tls_type;
04395 ent->got.refcount = 0;
04396 eh->elf.got.glist = ent;
04397 }
04398 ent->got.refcount += 1;
04399 eh->tls_mask |= tls_type;
04400 }
04401 else
04402
04403 if (!update_local_sym_info (abfd, symtab_hdr, r_symndx,
04404 rel->r_addend, tls_type))
04405 return FALSE;
04406 break;
04407
04408 case R_PPC64_PLT16_HA:
04409 case R_PPC64_PLT16_HI:
04410 case R_PPC64_PLT16_LO:
04411 case R_PPC64_PLT32:
04412 case R_PPC64_PLT64:
04413
04414
04415
04416
04417
04418 if (h == NULL)
04419 {
04420
04421
04422 bfd_set_error (bfd_error_bad_value);
04423 return FALSE;
04424 }
04425 else
04426 if (!update_plt_info (abfd, (struct ppc_link_hash_entry *) h,
04427 rel->r_addend))
04428 return FALSE;
04429 break;
04430
04431
04432
04433
04434 case R_PPC64_SECTOFF:
04435 case R_PPC64_SECTOFF_LO:
04436 case R_PPC64_SECTOFF_HI:
04437 case R_PPC64_SECTOFF_HA:
04438 case R_PPC64_SECTOFF_DS:
04439 case R_PPC64_SECTOFF_LO_DS:
04440 case R_PPC64_DTPREL16:
04441 case R_PPC64_DTPREL16_LO:
04442 case R_PPC64_DTPREL16_HI:
04443 case R_PPC64_DTPREL16_HA:
04444 case R_PPC64_DTPREL16_DS:
04445 case R_PPC64_DTPREL16_LO_DS:
04446 case R_PPC64_DTPREL16_HIGHER:
04447 case R_PPC64_DTPREL16_HIGHERA:
04448 case R_PPC64_DTPREL16_HIGHEST:
04449 case R_PPC64_DTPREL16_HIGHESTA:
04450 break;
04451
04452
04453 case R_PPC64_TOC16:
04454 case R_PPC64_TOC16_LO:
04455 case R_PPC64_TOC16_HI:
04456 case R_PPC64_TOC16_HA:
04457 case R_PPC64_TOC16_DS:
04458 case R_PPC64_TOC16_LO_DS:
04459 sec->has_toc_reloc = 1;
04460 break;
04461
04462
04463
04464 case R_PPC64_GNU_VTINHERIT:
04465 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
04466 return FALSE;
04467 break;
04468
04469
04470
04471 case R_PPC64_GNU_VTENTRY:
04472 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
04473 return FALSE;
04474 break;
04475
04476 case R_PPC64_REL14:
04477 case R_PPC64_REL14_BRTAKEN:
04478 case R_PPC64_REL14_BRNTAKEN:
04479 htab->has_14bit_branch = 1;
04480
04481
04482 case R_PPC64_REL24:
04483 if (h != NULL)
04484 {
04485
04486
04487 if (!update_plt_info (abfd, (struct ppc_link_hash_entry *) h,
04488 rel->r_addend))
04489 return FALSE;
04490 if (h == &htab->tls_get_addr->elf
04491 || h == &htab->tls_get_addr_fd->elf)
04492 sec->has_tls_reloc = 1;
04493 else if (htab->tls_get_addr == NULL
04494 && !strncmp (h->root.root.string, ".__tls_get_addr", 15)
04495 && (h->root.root.string[15] == 0
04496 || h->root.root.string[15] == '@'))
04497 {
04498 htab->tls_get_addr = (struct ppc_link_hash_entry *) h;
04499 sec->has_tls_reloc = 1;
04500 }
04501 else if (htab->tls_get_addr_fd == NULL
04502 && !strncmp (h->root.root.string, "__tls_get_addr", 14)
04503 && (h->root.root.string[14] == 0
04504 || h->root.root.string[14] == '@'))
04505 {
04506 htab->tls_get_addr_fd = (struct ppc_link_hash_entry *) h;
04507 sec->has_tls_reloc = 1;
04508 }
04509 }
04510 break;
04511
04512 case R_PPC64_TPREL64:
04513 tls_type = TLS_EXPLICIT | TLS_TLS | TLS_TPREL;
04514 if (info->shared)
04515 info->flags |= DF_STATIC_TLS;
04516 goto dotlstoc;
04517
04518 case R_PPC64_DTPMOD64:
04519 if (rel + 1 < rel_end
04520 && rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_DTPREL64)
04521 && rel[1].r_offset == rel->r_offset + 8)
04522 tls_type = TLS_EXPLICIT | TLS_TLS | TLS_GD;
04523 else
04524 tls_type = TLS_EXPLICIT | TLS_TLS | TLS_LD;
04525 goto dotlstoc;
04526
04527 case R_PPC64_DTPREL64:
04528 tls_type = TLS_EXPLICIT | TLS_TLS | TLS_DTPREL;
04529 if (rel != relocs
04530 && rel[-1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_DTPMOD64)
04531 && rel[-1].r_offset == rel->r_offset - 8)
04532
04533
04534 goto dodyn;
04535
04536 dotlstoc:
04537 sec->has_tls_reloc = 1;
04538 if (h != NULL)
04539 {
04540 struct ppc_link_hash_entry *eh;
04541 eh = (struct ppc_link_hash_entry *) h;
04542 eh->tls_mask |= tls_type;
04543 }
04544 else
04545 if (!update_local_sym_info (abfd, symtab_hdr, r_symndx,
04546 rel->r_addend, tls_type))
04547 return FALSE;
04548
04549 if (ppc64_elf_section_data (sec)->t_symndx == NULL)
04550 {
04551
04552 bfd_size_type amt = sec->size * sizeof (unsigned) / 8 + 1;
04553 ppc64_elf_section_data (sec)->t_symndx = bfd_zalloc (abfd, amt);
04554 if (ppc64_elf_section_data (sec)->t_symndx == NULL)
04555 return FALSE;
04556 }
04557 BFD_ASSERT (rel->r_offset % 8 == 0);
04558 ppc64_elf_section_data (sec)->t_symndx[rel->r_offset / 8] = r_symndx;
04559
04560
04561
04562 if (tls_type == (TLS_EXPLICIT | TLS_TLS | TLS_GD))
04563 ppc64_elf_section_data (sec)->t_symndx[rel->r_offset / 8 + 1] = -1;
04564 else if (tls_type == (TLS_EXPLICIT | TLS_TLS | TLS_LD))
04565 ppc64_elf_section_data (sec)->t_symndx[rel->r_offset / 8 + 1] = -2;
04566 goto dodyn;
04567
04568 case R_PPC64_TPREL16:
04569 case R_PPC64_TPREL16_LO:
04570 case R_PPC64_TPREL16_HI:
04571 case R_PPC64_TPREL16_HA:
04572 case R_PPC64_TPREL16_DS:
04573 case R_PPC64_TPREL16_LO_DS:
04574 case R_PPC64_TPREL16_HIGHER:
04575 case R_PPC64_TPREL16_HIGHERA:
04576 case R_PPC64_TPREL16_HIGHEST:
04577 case R_PPC64_TPREL16_HIGHESTA:
04578 if (info->shared)
04579 {
04580 info->flags |= DF_STATIC_TLS;
04581 goto dodyn;
04582 }
04583 break;
04584
04585 case R_PPC64_ADDR64:
04586 if (opd_sym_map != NULL
04587 && rel + 1 < rel_end
04588 && ELF64_R_TYPE ((rel + 1)->r_info) == R_PPC64_TOC)
04589 {
04590 if (h != NULL)
04591 {
04592 if (h->root.root.string[0] == '.'
04593 && h->root.root.string[1] != 0
04594 && get_fdh ((struct ppc_link_hash_entry *) h, htab))
04595 ;
04596 else
04597 ((struct ppc_link_hash_entry *) h)->is_func = 1;
04598 }
04599 else
04600 {
04601 asection *s;
04602
04603 s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, sec,
04604 r_symndx);
04605 if (s == NULL)
04606 return FALSE;
04607 else if (s != sec)
04608 opd_sym_map[rel->r_offset / 8] = s;
04609 }
04610 }
04611
04612
04613 case R_PPC64_REL30:
04614 case R_PPC64_REL32:
04615 case R_PPC64_REL64:
04616 case R_PPC64_ADDR14:
04617 case R_PPC64_ADDR14_BRNTAKEN:
04618 case R_PPC64_ADDR14_BRTAKEN:
04619 case R_PPC64_ADDR16:
04620 case R_PPC64_ADDR16_DS:
04621 case R_PPC64_ADDR16_HA:
04622 case R_PPC64_ADDR16_HI:
04623 case R_PPC64_ADDR16_HIGHER:
04624 case R_PPC64_ADDR16_HIGHERA:
04625 case R_PPC64_ADDR16_HIGHEST:
04626 case R_PPC64_ADDR16_HIGHESTA:
04627 case R_PPC64_ADDR16_LO:
04628 case R_PPC64_ADDR16_LO_DS:
04629 case R_PPC64_ADDR24:
04630 case R_PPC64_ADDR32:
04631 case R_PPC64_UADDR16:
04632 case R_PPC64_UADDR32:
04633 case R_PPC64_UADDR64:
04634 case R_PPC64_TOC:
04635 if (h != NULL && !info->shared)
04636
04637 h->non_got_ref = 1;
04638
04639
04640 if (NO_OPD_RELOCS && opd_sym_map != NULL)
04641 break;
04642
04643
04644
04645
04646
04647
04648
04649
04650
04651
04652
04653
04654
04655
04656
04657
04658
04659
04660
04661
04662
04663
04664 dodyn:
04665 if ((info->shared
04666 && (MUST_BE_DYN_RELOC (r_type)
04667 || (h != NULL
04668 && (! info->symbolic
04669 || h->root.type == bfd_link_hash_defweak
04670 || !h->def_regular))))
04671 || (ELIMINATE_COPY_RELOCS
04672 && !info->shared
04673 && h != NULL
04674 && (h->root.type == bfd_link_hash_defweak
04675 || !h->def_regular)))
04676 {
04677 struct ppc_dyn_relocs *p;
04678 struct ppc_dyn_relocs **head;
04679
04680
04681
04682
04683 if (sreloc == NULL)
04684 {
04685 const char *name;
04686 bfd *dynobj;
04687
04688 name = (bfd_elf_string_from_elf_section
04689 (abfd,
04690 elf_elfheader (abfd)->e_shstrndx,
04691 elf_section_data (sec)->rel_hdr.sh_name));
04692 if (name == NULL)
04693 return FALSE;
04694
04695 if (strncmp (name, ".rela", 5) != 0
04696 || strcmp (bfd_get_section_name (abfd, sec),
04697 name + 5) != 0)
04698 {
04699 (*_bfd_error_handler)
04700 (_("%B: bad relocation section name `%s\'"),
04701 abfd, name);
04702 bfd_set_error (bfd_error_bad_value);
04703 }
04704
04705 dynobj = htab->elf.dynobj;
04706 sreloc = bfd_get_section_by_name (dynobj, name);
04707 if (sreloc == NULL)
04708 {
04709 flagword flags;
04710
04711 sreloc = bfd_make_section (dynobj, name);
04712 flags = (SEC_HAS_CONTENTS | SEC_READONLY
04713 | SEC_IN_MEMORY | SEC_LINKER_CREATED
04714 | SEC_ALLOC | SEC_LOAD);
04715 if (sreloc == NULL
04716 || ! bfd_set_section_flags (dynobj, sreloc, flags)
04717 || ! bfd_set_section_alignment (dynobj, sreloc, 3))
04718 return FALSE;
04719 }
04720 elf_section_data (sec)->sreloc = sreloc;
04721 }
04722
04723
04724
04725 if (h != NULL)
04726 {
04727 head = &((struct ppc_link_hash_entry *) h)->dyn_relocs;
04728 }
04729 else
04730 {
04731
04732
04733
04734
04735 asection *s;
04736 s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
04737 sec, r_symndx);
04738 if (s == NULL)
04739 return FALSE;
04740
04741 head = ((struct ppc_dyn_relocs **)
04742 &elf_section_data (s)->local_dynrel);
04743 }
04744
04745 p = *head;
04746 if (p == NULL || p->sec != sec)
04747 {
04748 p = bfd_alloc (htab->elf.dynobj, sizeof *p);
04749 if (p == NULL)
04750 return FALSE;
04751 p->next = *head;
04752 *head = p;
04753 p->sec = sec;
04754 p->count = 0;
04755 p->pc_count = 0;
04756 }
04757
04758 p->count += 1;
04759 if (!MUST_BE_DYN_RELOC (r_type))
04760 p->pc_count += 1;
04761 }
04762 break;
04763
04764 default:
04765 break;
04766 }
04767 }
04768
04769 return TRUE;
04770 }
04771
04772
04773
04774
04775 static bfd_vma
04776 opd_entry_value (asection *opd_sec,
04777 bfd_vma offset,
04778 asection **code_sec,
04779 bfd_vma *code_off)
04780 {
04781 bfd *opd_bfd = opd_sec->owner;
04782 Elf_Internal_Rela *relocs;
04783 Elf_Internal_Rela *lo, *hi, *look;
04784 bfd_vma val;
04785
04786
04787 if (opd_sec->reloc_count == 0)
04788 {
04789 bfd_vma val;
04790
04791 if (!bfd_get_section_contents (opd_bfd, opd_sec, &val, offset, 8))
04792 return (bfd_vma) -1;
04793
04794 if (code_sec != NULL)
04795 {
04796 asection *sec, *likely = NULL;
04797 for (sec = opd_bfd->sections; sec != NULL; sec = sec->next)
04798 if (sec->vma <= val
04799 && (sec->flags & SEC_LOAD) != 0
04800 && (sec->flags & SEC_ALLOC) != 0)
04801 likely = sec;
04802 if (likely != NULL)
04803 {
04804 *code_sec = likely;
04805 if (code_off != NULL)
04806 *code_off = val - likely->vma;
04807 }
04808 }
04809 return val;
04810 }
04811
04812 relocs = ppc64_elf_tdata (opd_bfd)->opd_relocs;
04813 if (relocs == NULL)
04814 relocs = _bfd_elf_link_read_relocs (opd_bfd, opd_sec, NULL, NULL, TRUE);
04815
04816
04817 lo = relocs;
04818 BFD_ASSERT (lo != NULL);
04819 hi = lo + opd_sec->reloc_count - 1;
04820 val = (bfd_vma) -1;
04821 while (lo < hi)
04822 {
04823 look = lo + (hi - lo) / 2;
04824 if (look->r_offset < offset)
04825 lo = look + 1;
04826 else if (look->r_offset > offset)
04827 hi = look;
04828 else
04829 {
04830 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (opd_bfd)->symtab_hdr;
04831 if (ELF64_R_TYPE (look->r_info) == R_PPC64_ADDR64
04832 && ELF64_R_TYPE ((look + 1)->r_info) == R_PPC64_TOC)
04833 {
04834 unsigned long symndx = ELF64_R_SYM (look->r_info);
04835 asection *sec;
04836
04837 if (symndx < symtab_hdr->sh_info)
04838 {
04839 Elf_Internal_Sym *sym;
04840
04841 sym = (Elf_Internal_Sym *) symtab_hdr->contents;
04842 if (sym == NULL)
04843 {
04844 sym = bfd_elf_get_elf_syms (opd_bfd, symtab_hdr,
04845 symtab_hdr->sh_info,
04846 0, NULL, NULL, NULL);
04847 if (sym == NULL)
04848 break;
04849 symtab_hdr->contents = (bfd_byte *) sym;
04850 }
04851
04852 sym += symndx;
04853 val = sym->st_value;
04854 sec = NULL;
04855 if ((sym->st_shndx != SHN_UNDEF
04856 && sym->st_shndx < SHN_LORESERVE)
04857 || sym->st_shndx > SHN_HIRESERVE)
04858 sec = bfd_section_from_elf_index (opd_bfd, sym->st_shndx);
04859 BFD_ASSERT ((sec->flags & SEC_MERGE) == 0);
04860 }
04861 else
04862 {
04863 struct elf_link_hash_entry **sym_hashes;
04864 struct elf_link_hash_entry *rh;
04865
04866 sym_hashes = elf_sym_hashes (opd_bfd);
04867 rh = sym_hashes[symndx - symtab_hdr->sh_info];
04868 while (rh->root.type == bfd_link_hash_indirect
04869 || rh->root.type == bfd_link_hash_warning)
04870 rh = ((struct elf_link_hash_entry *) rh->root.u.i.link);
04871 BFD_ASSERT (rh->root.type == bfd_link_hash_defined
04872 || rh->root.type == bfd_link_hash_defweak);
04873 val = rh->root.u.def.value;
04874 sec = rh->root.u.def.section;
04875 }
04876 val += look->r_addend;
04877 if (code_off != NULL)
04878 *code_off = val;
04879 if (code_sec != NULL)
04880 *code_sec = sec;
04881 if (sec != NULL && sec->output_section != NULL)
04882 val += sec->output_section->vma + sec->output_offset;
04883 }
04884 break;
04885 }
04886 }
04887
04888 return val;
04889 }
04890
04891
04892
04893
04894 static asection *
04895 ppc64_elf_gc_mark_hook (asection *sec,
04896 struct bfd_link_info *info,
04897 Elf_Internal_Rela *rel,
04898 struct elf_link_hash_entry *h,
04899 Elf_Internal_Sym *sym)
04900 {
04901 asection *rsec;
04902
04903
04904 if (info->gc_sym_list != NULL)
04905 {
04906 struct ppc_link_hash_table *htab = ppc_hash_table (info);
04907 struct bfd_sym_chain *sym = info->gc_sym_list;
04908
04909 info->gc_sym_list = NULL;
04910 do
04911 {
04912 struct ppc_link_hash_entry *eh;
04913
04914 eh = (struct ppc_link_hash_entry *)
04915 elf_link_hash_lookup (&htab->elf, sym->name, FALSE, FALSE, FALSE);
04916 if (eh == NULL)
04917 continue;
04918 if (eh->elf.root.type != bfd_link_hash_defined
04919 && eh->elf.root.type != bfd_link_hash_defweak)
04920 continue;
04921
04922 if (eh->is_func_descriptor
04923 && (eh->oh->elf.root.type == bfd_link_hash_defined
04924 || eh->oh->elf.root.type == bfd_link_hash_defweak))
04925 rsec = eh->oh->elf.root.u.def.section;
04926 else if (get_opd_info (eh->elf.root.u.def.section) != NULL
04927 && opd_entry_value (eh->elf.root.u.def.section,
04928 eh->elf.root.u.def.value,
04929 &rsec, NULL) != (bfd_vma) -1)
04930 ;
04931 else
04932 continue;
04933
04934 if (!rsec->gc_mark)
04935 _bfd_elf_gc_mark (info, rsec, ppc64_elf_gc_mark_hook);
04936
04937 rsec = eh->elf.root.u.def.section;
04938 if (!rsec->gc_mark)
04939 _bfd_elf_gc_mark (info, rsec, ppc64_elf_gc_mark_hook);
04940
04941 sym = sym->next;
04942 }
04943 while (sym != NULL);
04944 }
04945
04946
04947
04948 rsec = NULL;
04949 if (get_opd_info (sec) != NULL)
04950 return rsec;
04951
04952 if (h != NULL)
04953 {
04954 enum elf_ppc64_reloc_type r_type;
04955 struct ppc_link_hash_entry *eh;
04956
04957 r_type = ELF64_R_TYPE (rel->r_info);
04958 switch (r_type)
04959 {
04960 case R_PPC64_GNU_VTINHERIT:
04961 case R_PPC64_GNU_VTENTRY:
04962 break;
04963
04964 default:
04965 switch (h->root.type)
04966 {
04967 case bfd_link_hash_defined:
04968 case bfd_link_hash_defweak:
04969 eh = (struct ppc_link_hash_entry *) h;
04970 if (eh->oh != NULL
04971 && eh->oh->is_func_descriptor
04972 && (eh->oh->elf.root.type == bfd_link_hash_defined
04973 || eh->oh->elf.root.type == bfd_link_hash_defweak))
04974 eh = eh->oh;
04975
04976
04977
04978 if (eh->is_func_descriptor
04979 && (eh->oh->elf.root.type == bfd_link_hash_defined
04980 || eh->oh->elf.root.type == bfd_link_hash_defweak))
04981 {
04982
04983 if (!eh->elf.root.u.def.section->gc_mark)
04984 _bfd_elf_gc_mark (info, eh->elf.root.u.def.section,
04985 ppc64_elf_gc_mark_hook);
04986
04987 rsec = eh->oh->elf.root.u.def.section;
04988 }
04989 else if (get_opd_info (eh->elf.root.u.def.section) != NULL
04990 && opd_entry_value (eh->elf.root.u.def.section,
04991 eh->elf.root.u.def.value,
04992 &rsec, NULL) != (bfd_vma) -1)
04993 {
04994 if (!eh->elf.root.u.def.section->gc_mark)
04995 _bfd_elf_gc_mark (info, eh->elf.root.u.def.section,
04996 ppc64_elf_gc_mark_hook);
04997 }
04998 else
04999 rsec = h->root.u.def.section;
05000 break;
05001
05002 case bfd_link_hash_common:
05003 rsec = h->root.u.c.p->section;
05004 break;
05005
05006 default:
05007 break;
05008 }
05009 }
05010 }
05011 else
05012 {
05013 asection **opd_sym_section;
05014
05015 rsec = bfd_section_from_elf_index (sec->owner, sym->st_shndx);
05016 opd_sym_section = get_opd_info (rsec);
05017 if (opd_sym_section != NULL)
05018 {
05019 if (!rsec->gc_mark)
05020 _bfd_elf_gc_mark (info, rsec, ppc64_elf_gc_mark_hook);
05021
05022 rsec = opd_sym_section[(sym->st_value + rel->r_addend) / 8];
05023 }
05024 }
05025
05026 return rsec;
05027 }
05028
05029
05030
05031
05032 static bfd_boolean
05033 ppc64_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
05034 asection *sec, const Elf_Internal_Rela *relocs)
05035 {
05036 struct ppc_link_hash_table *htab;
05037 Elf_Internal_Shdr *symtab_hdr;
05038 struct elf_link_hash_entry **sym_hashes;
05039 struct got_entry **local_got_ents;
05040 const Elf_Internal_Rela *rel, *relend;
05041
05042 if ((sec->flags & SEC_ALLOC) == 0)
05043 return TRUE;
05044
05045 elf_section_data (sec)->local_dynrel = NULL;
05046
05047 htab = ppc_hash_table (info);
05048 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
05049 sym_hashes = elf_sym_hashes (abfd);
05050 local_got_ents = elf_local_got_ents (abfd);
05051
05052 relend = relocs + sec->reloc_count;
05053 for (rel = relocs; rel < relend; rel++)
05054 {
05055 unsigned long r_symndx;
05056 enum elf_ppc64_reloc_type r_type;
05057 struct elf_link_hash_entry *h = NULL;
05058 char tls_type = 0;
05059
05060 r_symndx = ELF64_R_SYM (rel->r_info);
05061 r_type = ELF64_R_TYPE (rel->r_info);
05062 if (r_symndx >= symtab_hdr->sh_info)
05063 {
05064 struct ppc_link_hash_entry *eh;
05065 struct ppc_dyn_relocs **pp;
05066 struct ppc_dyn_relocs *p;
05067
05068 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
05069 while (h->root.type == bfd_link_hash_indirect
05070 || h->root.type == bfd_link_hash_warning)
05071 h = (struct elf_link_hash_entry *) h->root.u.i.link;
05072 eh = (struct ppc_link_hash_entry *) h;
05073
05074 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
05075 if (p->sec == sec)
05076 {
05077
05078 *pp = p->next;
05079 break;
05080 }
05081 }
05082
05083 switch (r_type)
05084 {
05085 case R_PPC64_GOT_TLSLD16:
05086 case R_PPC64_GOT_TLSLD16_LO:
05087 case R_PPC64_GOT_TLSLD16_HI:
05088 case R_PPC64_GOT_TLSLD16_HA:
05089 ppc64_tlsld_got (abfd)->refcount -= 1;
05090 tls_type = TLS_TLS | TLS_LD;
05091 goto dogot;
05092
05093 case R_PPC64_GOT_TLSGD16:
05094 case R_PPC64_GOT_TLSGD16_LO:
05095 case R_PPC64_GOT_TLSGD16_HI:
05096 case R_PPC64_GOT_TLSGD16_HA:
05097 tls_type = TLS_TLS | TLS_GD;
05098 goto dogot;
05099
05100 case R_PPC64_GOT_TPREL16_DS:
05101 case R_PPC64_GOT_TPREL16_LO_DS:
05102 case R_PPC64_GOT_TPREL16_HI:
05103 case R_PPC64_GOT_TPREL16_HA:
05104 tls_type = TLS_TLS | TLS_TPREL;
05105 goto dogot;
05106
05107 case R_PPC64_GOT_DTPREL16_DS:
05108 case R_PPC64_GOT_DTPREL16_LO_DS:
05109 case R_PPC64_GOT_DTPREL16_HI:
05110 case R_PPC64_GOT_DTPREL16_HA:
05111 tls_type = TLS_TLS | TLS_DTPREL;
05112 goto dogot;
05113
05114 case R_PPC64_GOT16:
05115 case R_PPC64_GOT16_DS:
05116 case R_PPC64_GOT16_HA:
05117 case R_PPC64_GOT16_HI:
05118 case R_PPC64_GOT16_LO:
05119 case R_PPC64_GOT16_LO_DS:
05120 dogot:
05121 {
05122 struct got_entry *ent;
05123
05124 if (h != NULL)
05125 ent = h->got.glist;
05126 else
05127 ent = local_got_ents[r_symndx];
05128
05129 for (; ent != NULL; ent = ent->next)
05130 if (ent->addend == rel->r_addend
05131 && ent->owner == abfd
05132 && ent->tls_type == tls_type)
05133 break;
05134 if (ent == NULL)
05135 abort ();
05136 if (ent->got.refcount > 0)
05137 ent->got.refcount -= 1;
05138 }
05139 break;
05140
05141 case R_PPC64_PLT16_HA:
05142 case R_PPC64_PLT16_HI:
05143 case R_PPC64_PLT16_LO:
05144 case R_PPC64_PLT32:
05145 case R_PPC64_PLT64:
05146 case R_PPC64_REL14:
05147 case R_PPC64_REL14_BRNTAKEN:
05148 case R_PPC64_REL14_BRTAKEN:
05149 case R_PPC64_REL24:
05150 if (h != NULL)
05151 {
05152 struct plt_entry *ent;
05153
05154 for (ent = h->plt.plist; ent != NULL; ent = ent->next)
05155 if (ent->addend == rel->r_addend)
05156 break;
05157 if (ent == NULL)
05158 abort ();
05159 if (ent->plt.refcount > 0)
05160 ent->plt.refcount -= 1;
05161 }
05162 break;
05163
05164 default:
05165 break;
05166 }
05167 }
05168 return TRUE;
05169 }
05170
05171
05172 #define SFPR_MAX (218*4)
05173
05174 struct sfpr_def_parms
05175 {
05176 const char name[12];
05177 unsigned char lo, hi;
05178 bfd_byte * (*write_ent) (bfd *, bfd_byte *, int);
05179 bfd_byte * (*write_tail) (bfd *, bfd_byte *, int);
05180 };
05181
05182
05183
05184 static unsigned int
05185 sfpr_define (struct bfd_link_info *info, const struct sfpr_def_parms *parm)
05186 {
05187 struct ppc_link_hash_table *htab = ppc_hash_table (info);
05188 unsigned int i;
05189 size_t len = strlen (parm->name);
05190 bfd_boolean writing = FALSE;
05191 char sym[16];
05192
05193 memcpy (sym, parm->name, len);
05194 sym[len + 2] = 0;
05195
05196 for (i = parm->lo; i <= parm->hi; i++)
05197 {
05198 struct elf_link_hash_entry *h;
05199
05200 sym[len + 0] = i / 10 + '0';
05201 sym[len + 1] = i % 10 + '0';
05202 h = elf_link_hash_lookup (&htab->elf, sym, FALSE, FALSE, TRUE);
05203 if (h != NULL
05204 && !h->def_regular)
05205 {
05206 h->root.type = bfd_link_hash_defined;
05207 h->root.u.def.section = htab->sfpr;
05208 h->root.u.def.value = htab->sfpr->size;
05209 h->type = STT_FUNC;
05210 h->def_regular = 1;
05211 _bfd_elf_link_hash_hide_symbol (info, h, TRUE);
05212 writing = TRUE;
05213 if (htab->sfpr->contents == NULL)
05214 {
05215 htab->sfpr->contents = bfd_alloc (htab->elf.dynobj, SFPR_MAX);
05216 if (htab->sfpr->contents == NULL)
05217 return FALSE;
05218 }
05219 }
05220 if (writing)
05221 {
05222 bfd_byte *p = htab->sfpr->contents + htab->sfpr->size;
05223 if (i != parm->hi)
05224 p = (*parm->write_ent) (htab->elf.dynobj, p, i);
05225 else
05226 p = (*parm->write_tail) (htab->elf.dynobj, p, i);
05227 htab->sfpr->size = p - htab->sfpr->contents;
05228 }
05229 }
05230
05231 return TRUE;
05232 }
05233
05234 static bfd_byte *
05235 savegpr0 (bfd *abfd, bfd_byte *p, int r)
05236 {
05237 bfd_put_32 (abfd, STD_R0_0R1 + (r << 21) + (1 << 16) - (32 - r) * 8, p);
05238 return p + 4;
05239 }
05240
05241 static bfd_byte *
05242 savegpr0_tail (bfd *abfd, bfd_byte *p, int r)
05243 {
05244 p = savegpr0 (abfd, p, r);
05245 bfd_put_32 (abfd, STD_R0_0R1 + 16, p);
05246 p = p + 4;
05247 bfd_put_32 (abfd, BLR, p);
05248 return p + 4;
05249 }
05250
05251 static bfd_byte *
05252 restgpr0 (bfd *abfd, bfd_byte *p, int r)
05253 {
05254 bfd_put_32 (abfd, LD_R0_0R1 + (r << 21) + (1 << 16) - (32 - r) * 8, p);
05255 return p + 4;
05256 }
05257
05258 static bfd_byte *
05259 restgpr0_tail (bfd *abfd, bfd_byte *p, int r)
05260 {
05261 bfd_put_32 (abfd, LD_R0_0R1 + 16, p);
05262 p = p + 4;
05263 p = restgpr0 (abfd, p, r);
05264 bfd_put_32 (abfd, MTLR_R0, p);
05265 p = p + 4;
05266 if (r == 29)
05267 {
05268 p = restgpr0 (abfd, p, 30);
05269 p = restgpr0 (abfd, p, 31);
05270 }
05271 bfd_put_32 (abfd, BLR, p);
05272 return p + 4;
05273 }
05274
05275 static bfd_byte *
05276 savegpr1 (bfd *abfd, bfd_byte *p, int r)
05277 {
05278 bfd_put_32 (abfd, STD_R0_0R12 + (r << 21) + (1 << 16) - (32 - r) * 8, p);
05279 return p + 4;
05280 }
05281
05282 static bfd_byte *
05283 savegpr1_tail (bfd *abfd, bfd_byte *p, int r)
05284 {
05285 p = savegpr1 (abfd, p, r);
05286 bfd_put_32 (abfd, BLR, p);
05287 return p + 4;
05288 }
05289
05290 static bfd_byte *
05291 restgpr1 (bfd *abfd, bfd_byte *p, int r)
05292 {
05293 bfd_put_32 (abfd, LD_R0_0R12 + (r << 21) + (1 << 16) - (32 - r) * 8, p);
05294 return p + 4;
05295 }
05296
05297 static bfd_byte *
05298 restgpr1_tail (bfd *abfd, bfd_byte *p, int r)
05299 {
05300 p = restgpr1 (abfd, p, r);
05301 bfd_put_32 (abfd, BLR, p);
05302 return p + 4;
05303 }
05304
05305 static bfd_byte *
05306 savefpr (bfd *abfd, bfd_byte *p, int r)
05307 {
05308 bfd_put_32 (abfd, STFD_FR0_0R1 + (r << 21) + (1 << 16) - (32 - r) * 8, p);
05309 return p + 4;
05310 }
05311
05312 static bfd_byte *
05313 savefpr0_tail (bfd *abfd, bfd_byte *p, int r)
05314 {
05315 p = savefpr (abfd, p, r);
05316 bfd_put_32 (abfd, STD_R0_0R1 + 16, p);
05317 p = p + 4;
05318 bfd_put_32 (abfd, BLR, p);
05319 return p + 4;
05320 }
05321
05322 static bfd_byte *
05323 restfpr (bfd *abfd, bfd_byte *p, int r)
05324 {
05325 bfd_put_32 (abfd, LFD_FR0_0R1 + (r << 21) + (1 << 16) - (32 - r) * 8, p);
05326 return p + 4;
05327 }
05328
05329 static bfd_byte *
05330 restfpr0_tail (bfd *abfd, bfd_byte *p, int r)
05331 {
05332 bfd_put_32 (abfd, LD_R0_0R1 + 16, p);
05333 p = p + 4;
05334 p = restfpr (abfd, p, r);
05335 bfd_put_32 (abfd, MTLR_R0, p);
05336 p = p + 4;
05337 if (r == 29)
05338 {
05339 p = restfpr (abfd, p, 30);
05340 p = restfpr (abfd, p, 31);
05341 }
05342 bfd_put_32 (abfd, BLR, p);
05343 return p + 4;
05344 }
05345
05346 static bfd_byte *
05347 savefpr1_tail (bfd *abfd, bfd_byte *p, int r)
05348 {
05349 p = savefpr (abfd, p, r);
05350 bfd_put_32 (abfd, BLR, p);
05351 return p + 4;
05352 }
05353
05354 static bfd_byte *
05355 restfpr1_tail (bfd *abfd, bfd_byte *p, int r)
05356 {
05357 p = restfpr (abfd, p, r);
05358 bfd_put_32 (abfd, BLR, p);
05359 return p + 4;
05360 }
05361
05362 static bfd_byte *
05363 savevr (bfd *abfd, bfd_byte *p, int r)
05364 {
05365 bfd_put_32 (abfd, LI_R12_0 + (1 << 16) - (32 - r) * 16, p);
05366 p = p + 4;
05367 bfd_put_32 (abfd, STVX_VR0_R12_R0 + (r << 21), p);
05368 return p + 4;
05369 }
05370
05371 static bfd_byte *
05372 savevr_tail (bfd *abfd, bfd_byte *p, int r)
05373 {
05374 p = savevr (abfd, p, r);
05375 bfd_put_32 (abfd, BLR, p);
05376 return p + 4;
05377 }
05378
05379 static bfd_byte *
05380 restvr (bfd *abfd, bfd_byte *p, int r)
05381 {
05382 bfd_put_32 (abfd, LI_R12_0 + (1 << 16) - (32 - r) * 16, p);
05383 p = p + 4;
05384 bfd_put_32 (abfd, LVX_VR0_R12_R0 + (r << 21), p);
05385 return p + 4;
05386 }
05387
05388 static bfd_byte *
05389 restvr_tail (bfd *abfd, bfd_byte *p, int r)
05390 {
05391 p = restvr (abfd, p, r);
05392 bfd_put_32 (abfd, BLR, p);
05393 return p + 4;
05394 }
05395
05396
05397
05398
05399
05400 static bfd_boolean
05401 func_desc_adjust (struct elf_link_hash_entry *h, void *inf)
05402 {
05403 struct bfd_link_info *info;
05404 struct ppc_link_hash_table *htab;
05405 struct plt_entry *ent;
05406 struct ppc_link_hash_entry *fh;
05407 struct ppc_link_hash_entry *fdh;
05408 bfd_boolean force_local;
05409
05410 fh = (struct ppc_link_hash_entry *) h;
05411 if (fh->elf.root.type == bfd_link_hash_indirect)
05412 return TRUE;
05413
05414 if (fh->elf.root.type == bfd_link_hash_warning)
05415 fh = (struct ppc_link_hash_entry *) fh->elf.root.u.i.link;
05416
05417 info = inf;
05418 htab = ppc_hash_table (info);
05419
05420
05421
05422
05423
05424 if (fh->elf.root.type == bfd_link_hash_undefweak
05425 && fh->was_undefined
05426 && (fh->oh->elf.root.type == bfd_link_hash_defined
05427 || fh->oh->elf.root.type == bfd_link_hash_defweak)
05428 && get_opd_info (fh->oh->elf.root.u.def.section) != NULL
05429 && opd_entry_value (fh->oh->elf.root.u.def.section,
05430 fh->oh->elf.root.u.def.value,
05431 &fh->elf.root.u.def.section,
05432 &fh->elf.root.u.def.value) != (bfd_vma) -1)
05433 {
05434 fh->elf.root.type = fh->oh->elf.root.type;
05435 fh->elf.forced_local = 1;
05436 }
05437
05438
05439
05440 if (!fh->is_func)
05441 return TRUE;
05442
05443 for (ent = fh->elf.plt.plist; ent != NULL; ent = ent->next)
05444 if (ent->plt.refcount > 0)
05445 break;
05446 if (ent == NULL
05447 || fh->elf.root.root.string[0] != '.'
05448 || fh->elf.root.root.string[1] == '\0')
05449 return TRUE;
05450
05451
05452
05453
05454 fdh = get_fdh (fh, htab);
05455 if (fdh != NULL)
05456 while (fdh->elf.root.type == bfd_link_hash_indirect
05457 || fdh->elf.root.type == bfd_link_hash_warning)
05458 fdh = (struct ppc_link_hash_entry *) fdh->elf.root.u.i.link;
05459
05460 if (fdh == NULL
05461 && info->shared
05462 && (fh->elf.root.type == bfd_link_hash_undefined
05463 || fh->elf.root.type == bfd_link_hash_undefweak))
05464 {
05465 fdh = make_fdh (info, fh);
05466 if (fdh == NULL)
05467 return FALSE;
05468 }
05469
05470
05471
05472
05473
05474
05475
05476 if (fdh != NULL
05477 && fdh->fake
05478 && fdh->elf.root.type == bfd_link_hash_undefweak)
05479 {
05480 if (fh->elf.root.type == bfd_link_hash_undefined)
05481 {
05482 fdh->elf.root.type = bfd_link_hash_undefined;
05483 bfd_link_add_undef (&htab->elf.root, &fdh->elf.root);
05484 }
05485 else if (fh->elf.root.type == bfd_link_hash_defined
05486 || fh->elf.root.type == bfd_link_hash_defweak)
05487 {
05488 _bfd_elf_link_hash_hide_symbol (info, &fdh->elf, TRUE);
05489 }
05490 }
05491
05492 if (fdh != NULL
05493 && !fdh->elf.forced_local
05494 && (info->shared
05495 || fdh->elf.def_dynamic
05496 || fdh->elf.ref_dynamic
05497 || (fdh->elf.root.type == bfd_link_hash_undefweak
05498 && ELF_ST_VISIBILITY (fdh->elf.other) == STV_DEFAULT)))
05499 {
05500 if (fdh->elf.dynindx == -1)
05501 if (! bfd_elf_link_record_dynamic_symbol (info, &fdh->elf))
05502 return FALSE;
05503 fdh->elf.ref_regular |= fh->elf.ref_regular;
05504 fdh->elf.ref_dynamic |= fh->elf.ref_dynamic;
05505 fdh->elf.ref_regular_nonweak |= fh->elf.ref_regular_nonweak;
05506 fdh->elf.non_got_ref |= fh->elf.non_got_ref;
05507 if (ELF_ST_VISIBILITY (fh->elf.other) == STV_DEFAULT)
05508 {
05509 move_plt_plist (fh, fdh);
05510 fdh->elf.needs_plt = 1;
05511 }
05512 fdh->is_func_descriptor = 1;
05513 fdh->oh = fh;
05514 fh->oh = fdh;
05515 }
05516
05517
05518
05519
05520
05521
05522
05523
05524 force_local = (!fh->elf.def_regular
05525 || fdh == NULL
05526 || !fdh->elf.def_regular
05527 || fdh->elf.forced_local);
05528 _bfd_elf_link_hash_hide_symbol (info, &fh->elf, force_local);
05529
05530 return TRUE;
05531 }
05532
05533
05534
05535
05536
05537
05538 static bfd_boolean
05539 ppc64_elf_func_desc_adjust (bfd *obfd ATTRIBUTE_UNUSED,
05540 struct bfd_link_info *info)
05541 {
05542 struct ppc_link_hash_table *htab;
05543 unsigned int i;
05544 const struct sfpr_def_parms funcs[] =
05545 {
05546 { "_savegpr0_", 14, 31, savegpr0, savegpr0_tail },
05547 { "_restgpr0_", 14, 29, restgpr0, restgpr0_tail },
05548 { "_restgpr0_", 30, 31, restgpr0, restgpr0_tail },
05549 { "_savegpr1_", 14, 31, savegpr1, savegpr1_tail },
05550 { "_restgpr1_", 14, 31, restgpr1, restgpr1_tail },
05551 { "_savefpr_", 14, 31, savefpr, savefpr0_tail },
05552 { "_restfpr_", 14, 29, restfpr, restfpr0_tail },
05553 { "_restfpr_", 30, 31, restfpr, restfpr0_tail },
05554 { "._savef", 14, 31, savefpr, savefpr1_tail },
05555 { "._restf", 14, 31, restfpr, restfpr1_tail },
05556 { "_savevr_", 20, 31, savevr, savevr_tail },
05557 { "_restvr_", 20, 31, restvr, restvr_tail }
05558 };
05559
05560 htab = ppc_hash_table (info);
05561 if (htab->sfpr == NULL)
05562
05563 return TRUE;
05564
05565
05566 htab->sfpr->size = 0;
05567 for (i = 0; i < sizeof (funcs) / sizeof (funcs[0]); i++)
05568 if (!sfpr_define (info, &funcs[i]))
05569 return FALSE;
05570
05571 elf_link_hash_traverse (&htab->elf, func_desc_adjust, info);
05572
05573 if (htab->sfpr->size == 0)
05574 _bfd_strip_section_from_output (info, htab->sfpr);
05575
05576 return TRUE;
05577 }
05578
05579
05580
05581
05582
05583
05584
05585 static bfd_boolean
05586 ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
05587 struct elf_link_hash_entry *h)
05588 {
05589 struct ppc_link_hash_table *htab;
05590 asection *s;
05591 unsigned int power_of_two;
05592
05593 htab = ppc_hash_table (info);
05594
05595
05596 if (h->type == STT_FUNC
05597 || h->needs_plt)
05598 {
05599
05600
05601 struct plt_entry *ent;
05602 for (ent = h->plt.plist; ent != NULL; ent = ent->next)
05603 if (ent->plt.refcount > 0)
05604 break;
05605 if (ent == NULL
05606 || SYMBOL_CALLS_LOCAL (info, h)
05607 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
05608 && h->root.type == bfd_link_hash_undefweak))
05609 {
05610 h->plt.plist = NULL;
05611 h->needs_plt = 0;
05612 }
05613 }
05614 else
05615 h->plt.plist = NULL;
05616
05617
05618
05619
05620 if (h->u.weakdef != NULL)
05621 {
05622 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
05623 || h->u.weakdef->root.type == bfd_link_hash_defweak);
05624 h->root.u.def.section = h->u.weakdef->root.u.def.section;
05625 h->root.u.def.value = h->u.weakdef->root.u.def.value;
05626 if (ELIMINATE_COPY_RELOCS)
05627 h->non_got_ref = h->u.weakdef->non_got_ref;
05628 return TRUE;
05629 }
05630
05631
05632
05633
05634
05635 if (info->shared)
05636 return TRUE;
05637
05638
05639
05640 if (!h->non_got_ref)
05641 return TRUE;
05642
05643 if (ELIMINATE_COPY_RELOCS)
05644 {
05645 struct ppc_link_hash_entry * eh;
05646 struct ppc_dyn_relocs *p;
05647
05648 eh = (struct ppc_link_hash_entry *) h;
05649 for (p = eh->dyn_relocs; p != NULL; p = p->next)
05650 {
05651 s = p->sec->output_section;
05652 if (s != NULL && (s->flags & SEC_READONLY) != 0)
05653 break;
05654 }
05655
05656
05657
05658 if (p == NULL)
05659 {
05660 h->non_got_ref = 0;
05661 return TRUE;
05662 }
05663 }
05664
05665 if (h->plt.plist != NULL)
05666 {
05667
05668
05669
05670
05671
05672 (*_bfd_error_handler)
05673 (_("copy reloc against `%s' requires lazy plt linking; "
05674 "avoid setting LD_BIND_NOW=1 or upgrade gcc"),
05675 h->root.root.string);
05676 }
05677
05678
05679
05680
05681
05682
05683
05684
05685
05686
05687
05688
05689
05690
05691
05692
05693
05694
05695 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
05696 {
05697 htab->relbss->size += sizeof (Elf64_External_Rela);
05698 h->needs_copy = 1;
05699 }
05700
05701
05702
05703 power_of_two = bfd_log2 (h->size);
05704 if (power_of_two > 4)
05705 power_of_two = 4;
05706
05707
05708 s = htab->dynbss;
05709 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
05710 if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
05711 {
05712 if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
05713 return FALSE;
05714 }
05715
05716
05717 h->root.u.def.section = s;
05718 h->root.u.def.value = s->size;
05719
05720
05721 s->size += h->size;
05722
05723 return TRUE;
05724 }
05725
05726
05727
05728 static void
05729 ppc64_elf_hide_symbol (struct bfd_link_info *info,
05730 struct elf_link_hash_entry *h,
05731 bfd_boolean force_local)
05732 {
05733 struct ppc_link_hash_entry *eh;
05734 _bfd_elf_link_hash_hide_symbol (info, h, force_local);
05735
05736 eh = (struct ppc_link_hash_entry *) h;
05737 if (eh->is_func_descriptor)
05738 {
05739 struct ppc_link_hash_entry *fh = eh->oh;
05740
05741 if (fh == NULL)
05742 {
05743 const char *p, *q;
05744 struct ppc_link_hash_table *htab;
05745 char save;
05746
05747
05748
05749
05750
05751
05752
05753
05754
05755
05756 p = eh->elf.root.root.string - 1;
05757 save = *p;
05758 *(char *) p = '.';
05759 htab = ppc_hash_table (info);
05760 fh = (struct ppc_link_hash_entry *)
05761 elf_link_hash_lookup (&htab->elf, p, FALSE, FALSE, FALSE);
05762 *(char *) p = save;
05763
05764
05765
05766
05767
05768 if (fh == NULL)
05769 {
05770 q = eh->elf.root.root.string + strlen (eh->elf.root.root.string);
05771 while (q >= eh->elf.root.root.string && *q == *p)
05772 --q, --p;
05773 if (q < eh->elf.root.root.string && *p == '.')
05774 fh = (struct ppc_link_hash_entry *)
05775 elf_link_hash_lookup (&htab->elf, p, FALSE, FALSE, FALSE);
05776 }
05777 if (fh != NULL)
05778 {
05779 eh->oh = fh;
05780 fh->oh = eh;
05781 }
05782 }
05783 if (fh != NULL)
05784 _bfd_elf_link_hash_hide_symbol (info, &fh->elf, force_local);
05785 }
05786 }
05787
05788 static bfd_boolean
05789 get_sym_h (struct elf_link_hash_entry **hp,
05790 Elf_Internal_Sym **symp,
05791 asection **symsecp,
05792 char **tls_maskp,
05793 Elf_Internal_Sym **locsymsp,
05794 unsigned long r_symndx,
05795 bfd *ibfd)
05796 {
05797 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
05798
05799 if (r_symndx >= symtab_hdr->sh_info)
05800 {
05801 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (ibfd);
05802 struct elf_link_hash_entry *h;
05803
05804 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
05805 while (h->root.type == bfd_link_hash_indirect
05806 || h->root.type == bfd_link_hash_warning)
05807 h = (struct elf_link_hash_entry *) h->root.u.i.link;
05808
05809 if (hp != NULL)
05810 *hp = h;
05811
05812 if (symp != NULL)
05813 *symp = NULL;
05814
05815 if (symsecp != NULL)
05816 {
05817 asection *symsec = NULL;
05818 if (h->root.type == bfd_link_hash_defined
05819 || h->root.type == bfd_link_hash_defweak)
05820 symsec = h->root.u.def.section;
05821 *symsecp = symsec;
05822 }
05823
05824 if (tls_maskp != NULL)
05825 {
05826 struct ppc_link_hash_entry *eh;
05827
05828 eh = (struct ppc_link_hash_entry *) h;
05829 *tls_maskp = &eh->tls_mask;
05830 }
05831 }
05832 else
05833 {
05834 Elf_Internal_Sym *sym;
05835 Elf_Internal_Sym *locsyms = *locsymsp;
05836
05837 if (locsyms == NULL)
05838 {
05839 locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
05840 if (locsyms == NULL)
05841 locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
05842 symtab_hdr->sh_info,
05843 0, NULL, NULL, NULL);
05844 if (locsyms == NULL)
05845 return FALSE;
05846 *locsymsp = locsyms;
05847 }
05848 sym = locsyms + r_symndx;
05849
05850 if (hp != NULL)
05851 *hp = NULL;
05852
05853 if (symp != NULL)
05854 *symp = sym;
05855
05856 if (symsecp != NULL)
05857 {
05858 asection *symsec = NULL;
05859 if ((sym->st_shndx != SHN_UNDEF
05860 && sym->st_shndx < SHN_LORESERVE)
05861 || sym->st_shndx > SHN_HIRESERVE)
05862 symsec = bfd_section_from_elf_index (ibfd, sym->st_shndx);
05863 *symsecp = symsec;
05864 }
05865
05866 if (tls_maskp != NULL)
05867 {
05868 struct got_entry **lgot_ents;
05869 char *tls_mask;
05870
05871 tls_mask = NULL;
05872 lgot_ents = elf_local_got_ents (ibfd);
05873 if (lgot_ents != NULL)
05874 {
05875 char *lgot_masks = (char *) (lgot_ents + symtab_hdr->sh_info);
05876 tls_mask = &lgot_masks[r_symndx];
05877 }
05878 *tls_maskp = tls_mask;
05879 }
05880 }
05881 return TRUE;
05882 }
05883
05884
05885
05886
05887
05888 static int
05889 get_tls_mask (char **tls_maskp, unsigned long *toc_symndx,
05890 Elf_Internal_Sym **locsymsp,
05891 const Elf_Internal_Rela *rel, bfd *ibfd)
05892 {
05893 unsigned long r_symndx;
05894 int next_r;
05895 struct elf_link_hash_entry *h;
05896 Elf_Internal_Sym *sym;
05897 asection *sec;
05898 bfd_vma off;
05899
05900 r_symndx = ELF64_R_SYM (rel->r_info);
05901 if (!get_sym_h (&h, &sym, &sec, tls_maskp, locsymsp, r_symndx, ibfd))
05902 return 0;
05903
05904 if ((*tls_maskp != NULL && **tls_maskp != 0)
05905 || sec == NULL
05906 || ppc64_elf_section_data (sec)->t_symndx == NULL)
05907 return 1;
05908
05909
05910 if (h != NULL)
05911 {
05912 BFD_ASSERT (h->root.type == bfd_link_hash_defined);
05913 off = h->root.u.def.value;
05914 }
05915 else
05916 off = sym->st_value;
05917 off += rel->r_addend;
05918 BFD_ASSERT (off % 8 == 0);
05919 r_symndx = ppc64_elf_section_data (sec)->t_symndx[off / 8];
05920 next_r = ppc64_elf_section_data (sec)->t_symndx[off / 8 + 1];
05921 if (!get_sym_h (&h, &sym, &sec, tls_maskp, locsymsp, r_symndx, ibfd))
05922 return 0;
05923 if (toc_symndx != NULL)
05924 *toc_symndx = r_symndx;
05925 if ((h == NULL
05926 || ((h->root.type == bfd_link_hash_defined
05927 || h->root.type == bfd_link_hash_defweak)
05928 && !h->def_dynamic))
05929 && (next_r == -1 || next_r == -2))
05930 return 1 - next_r;
05931 return 1;
05932 }
05933
05934
05935
05936
05937 static bfd_boolean
05938 adjust_opd_syms (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
05939 {
05940 struct ppc_link_hash_entry *eh;
05941 asection *sym_sec;
05942 long *opd_adjust;
05943
05944 if (h->root.type == bfd_link_hash_indirect)
05945 return TRUE;
05946
05947 if (h->root.type == bfd_link_hash_warning)
05948 h = (struct elf_link_hash_entry *) h->root.u.i.link;
05949
05950 if (h->root.type != bfd_link_hash_defined
05951 && h->root.type != bfd_link_hash_defweak)
05952 return TRUE;
05953
05954 eh = (struct ppc_link_hash_entry *) h;
05955 if (eh->adjust_done)
05956 return TRUE;
05957
05958 sym_sec = eh->elf.root.u.def.section;
05959 opd_adjust = get_opd_info (sym_sec);
05960 if (opd_adjust != NULL)
05961 {
05962 long adjust = opd_adjust[eh->elf.root.u.def.value / 8];
05963 if (adjust == -1)
05964 {
05965
05966 asection *dsec = ppc64_elf_tdata (sym_sec->owner)->u.deleted_section;
05967 if (dsec == NULL)
05968 {
05969 for (dsec = sym_sec->owner->sections; dsec; dsec = dsec->next)
05970 if (elf_discarded_section (dsec))
05971 {
05972 ppc64_elf_tdata (sym_sec->owner)->u.deleted_section = dsec;
05973 break;
05974 }
05975 }
05976 eh->elf.root.u.def.value = 0;
05977 eh->elf.root.u.def.section = dsec;
05978 }
05979 else
05980 eh->elf.root.u.def.value += adjust;
05981 eh->adjust_done = 1;
05982 }
05983 return TRUE;
05984 }
05985
05986
05987
05988
05989
05990 static bfd_boolean
05991 dec_dynrel_count (bfd_vma r_info,
05992 asection *sec,
05993 struct bfd_link_info *info,
05994 Elf_Internal_Sym **local_syms,
05995 struct elf_link_hash_entry *h,
05996 asection *sym_sec)
05997 {
05998 enum elf_ppc64_reloc_type r_type;
05999 struct ppc_dyn_relocs *p;
06000 struct ppc_dyn_relocs **pp;
06001
06002
06003
06004 r_type = ELF64_R_TYPE (r_info);
06005 switch (r_type)
06006 {
06007 default:
06008 return TRUE;
06009
06010 case R_PPC64_TPREL16:
06011 case R_PPC64_TPREL16_LO:
06012 case R_PPC64_TPREL16_HI:
06013 case R_PPC64_TPREL16_HA:
06014 case R_PPC64_TPREL16_DS:
06015 case R_PPC64_TPREL16_LO_DS:
06016 case R_PPC64_TPREL16_HIGHER:
06017 case R_PPC64_TPREL16_HIGHERA:
06018 case R_PPC64_TPREL16_HIGHEST:
06019 case R_PPC64_TPREL16_HIGHESTA:
06020 if (!info->shared)
06021 return TRUE;
06022
06023 case R_PPC64_TPREL64:
06024 case R_PPC64_DTPMOD64:
06025 case R_PPC64_DTPREL64:
06026 case R_PPC64_ADDR64:
06027 case R_PPC64_REL30:
06028 case R_PPC64_REL32:
06029 case R_PPC64_REL64:
06030 case R_PPC64_ADDR14:
06031 case R_PPC64_ADDR14_BRNTAKEN:
06032 case R_PPC64_ADDR14_BRTAKEN:
06033 case R_PPC64_ADDR16:
06034 case R_PPC64_ADDR16_DS:
06035 case R_PPC64_ADDR16_HA:
06036 case R_PPC64_ADDR16_HI:
06037 case R_PPC64_ADDR16_HIGHER:
06038 case R_PPC64_ADDR16_HIGHERA:
06039 case R_PPC64_ADDR16_HIGHEST:
06040 case R_PPC64_ADDR16_HIGHESTA:
06041 case R_PPC64_ADDR16_LO:
06042 case R_PPC64_ADDR16_LO_DS:
06043 case R_PPC64_ADDR24:
06044 case R_PPC64_ADDR32:
06045 case R_PPC64_UADDR16:
06046 case R_PPC64_UADDR32:
06047 case R_PPC64_UADDR64:
06048 case R_PPC64_TOC:
06049 break;
06050 }
06051
06052 if (local_syms != NULL)
06053 {
06054 unsigned long r_symndx;
06055 Elf_Internal_Sym *sym;
06056 bfd *ibfd = sec->owner;
06057
06058 r_symndx = ELF64_R_SYM (r_info);
06059 if (!get_sym_h (&h, &sym, &sym_sec, NULL, local_syms, r_symndx, ibfd))
06060 return FALSE;
06061 }
06062
06063 if ((info->shared
06064 && (MUST_BE_DYN_RELOC (r_type)
06065 || (h != NULL
06066 && (!info->symbolic
06067 || h->root.type == bfd_link_hash_defweak
06068 || !h->def_regular))))
06069 || (ELIMINATE_COPY_RELOCS
06070 && !info->shared
06071 && h != NULL
06072 && (h->root.type == bfd_link_hash_defweak
06073 || !h->def_regular)))
06074 ;
06075 else
06076 return TRUE;
06077
06078 if (h != NULL)
06079 pp = &((struct ppc_link_hash_entry *) h)->dyn_relocs;
06080 else if (sym_sec != NULL)
06081 pp = (struct ppc_dyn_relocs **) &elf_section_data (sym_sec)->local_dynrel;
06082 else
06083 pp = (struct ppc_dyn_relocs **) &elf_section_data (sec)->local_dynrel;
06084
06085 while ((p = *pp) != NULL)
06086 {
06087 if (p->sec == sec)
06088 {
06089 if (!MUST_BE_DYN_RELOC (r_type))
06090 p->pc_count -= 1;
06091 p->count -= 1;
06092 if (p->count == 0)
06093 *pp = p->next;
06094 return TRUE;
06095 }
06096 pp = &p->next;
06097 }
06098
06099 (*_bfd_error_handler) (_("dynreloc miscount for %B, section %A"),
06100 sec->owner, sec);
06101 bfd_set_error (bfd_error_bad_value);
06102 return FALSE;
06103 }
06104
06105
06106
06107
06108
06109
06110
06111 bfd_boolean
06112 ppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info,
06113 bfd_boolean no_opd_opt,
06114 bfd_boolean non_overlapping)
06115 {
06116 bfd *ibfd;
06117 bfd_boolean some_edited = FALSE;
06118 asection *need_pad = NULL;
06119
06120 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
06121 {
06122 asection *sec;
06123 Elf_Internal_Rela *relstart, *rel, *relend;
06124 Elf_Internal_Shdr *symtab_hdr;
06125 Elf_Internal_Sym *local_syms;
06126 struct elf_link_hash_entry **sym_hashes;
06127 bfd_vma offset;
06128 bfd_size_type amt;
06129 long *opd_adjust;
06130 bfd_boolean need_edit, add_aux_fields;
06131 bfd_size_type cnt_16b = 0;
06132
06133 sec = bfd_get_section_by_name (ibfd, ".opd");
06134 if (sec == NULL || sec->size == 0)
06135 continue;
06136
06137 amt = sec->size * sizeof (long) / 8;
06138 opd_adjust = get_opd_info (sec);
06139 if (opd_adjust == NULL)
06140 {
06141
06142
06143 opd_adjust = bfd_alloc (obfd, amt);
06144 if (opd_adjust == NULL)
06145 return FALSE;
06146 ppc64_elf_section_data (sec)->opd.adjust = opd_adjust;
06147 }
06148 memset (opd_adjust, 0, amt);
06149
06150 if (no_opd_opt)
06151 continue;
06152
06153 if (sec->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
06154 continue;
06155
06156 if (sec->output_section == bfd_abs_section_ptr)
06157 continue;
06158
06159
06160 if ((sec->flags & SEC_RELOC) == 0 || sec->reloc_count == 0)
06161 continue;
06162
06163 local_syms = NULL;
06164 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
06165 sym_hashes = elf_sym_hashes (ibfd);
06166
06167
06168 relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
06169 info->keep_memory);
06170 if (relstart == NULL)
06171 return FALSE;
06172
06173
06174
06175 need_edit = FALSE;
06176 need_pad = sec;
06177 offset = 0;
06178 relend = relstart + sec->reloc_count;
06179 for (rel = relstart; rel < relend; )
06180 {
06181 enum elf_ppc64_reloc_type r_type;
06182 unsigned long r_symndx;
06183 asection *sym_sec;
06184 struct elf_link_hash_entry *h;
06185 Elf_Internal_Sym *sym;
06186
06187
06188
06189
06190 if (rel->r_offset != offset
06191 || rel + 1 >= relend
06192 || (rel + 1)->r_offset != offset + 8)
06193 {
06194
06195
06196
06197
06198
06199 broken_opd:
06200 (*_bfd_error_handler)
06201 (_("%B: .opd is not a regular array of opd entries"), ibfd);
06202 need_edit = FALSE;
06203 break;
06204 }
06205
06206 if ((r_type = ELF64_R_TYPE (rel->r_info)) != R_PPC64_ADDR64
06207 || (r_type = ELF64_R_TYPE ((rel + 1)->r_info)) != R_PPC64_TOC)
06208 {
06209 (*_bfd_error_handler)
06210 (_("%B: unexpected reloc type %u in .opd section"),
06211 ibfd, r_type);
06212 need_edit = FALSE;
06213 break;
06214 }
06215
06216 r_symndx = ELF64_R_SYM (rel->r_info);
06217 if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
06218 r_symndx, ibfd))
06219 goto error_ret;
06220
06221 if (sym_sec == NULL || sym_sec->owner == NULL)
06222 {
06223 const char *sym_name;
06224 if (h != NULL)
06225 sym_name = h->root.root.string;
06226 else
06227 sym_name = bfd_elf_sym_name (ibfd, symtab_hdr, sym);
06228
06229 (*_bfd_error_handler)
06230 (_("%B: undefined sym `%s' in .opd section"),
06231 ibfd, sym_name);
06232 need_edit = FALSE;
06233 break;
06234 }
06235
06236
06237
06238
06239
06240
06241
06242
06243 if (sym_sec->owner != ibfd
06244 || sym_sec->output_section == bfd_abs_section_ptr)
06245 need_edit = TRUE;
06246
06247 rel += 2;
06248 if (rel == relend
06249 || (rel + 1 == relend && rel->r_offset == offset + 16))
06250 {
06251 if (sec->size == offset + 24)
06252 {
06253 need_pad = NULL;
06254 break;
06255 }
06256 if (rel == relend && sec->size == offset + 16)
06257 {
06258 cnt_16b++;
06259 break;
06260 }
06261 goto broken_opd;
06262 }
06263
06264 if (rel->r_offset == offset + 24)
06265 offset += 24;
06266 else if (rel->r_offset != offset + 16)
06267 goto broken_opd;
06268 else if (rel + 1 < relend
06269 && ELF64_R_TYPE (rel[0].r_info) == R_PPC64_ADDR64
06270 && ELF64_R_TYPE (rel[1].r_info) == R_PPC64_TOC)
06271 {
06272 offset += 16;
06273 cnt_16b++;
06274 }
06275 else if (rel + 2 < relend
06276 && ELF64_R_TYPE (rel[1].r_info) == R_PPC64_ADDR64
06277 && ELF64_R_TYPE (rel[2].r_info) == R_PPC64_TOC)
06278 {
06279 offset += 24;
06280 rel += 1;
06281 }
06282 else
06283 goto broken_opd;
06284 }
06285
06286 add_aux_fields = non_overlapping && cnt_16b > 0;
06287
06288 if (need_edit || add_aux_fields)
06289 {
06290 Elf_Internal_Rela *write_rel;
06291 bfd_byte *rptr, *wptr;
06292 bfd_byte *new_contents = NULL;
06293 bfd_boolean skip;
06294 long opd_ent_size;
06295
06296
06297
06298
06299
06300 if ((sec->flags & SEC_IN_MEMORY) == 0)
06301 {
06302 bfd_byte *loc;
06303 if (!bfd_malloc_and_get_section (ibfd, sec, &loc))
06304 {
06305 if (loc != NULL)
06306 free (loc);
06307 error_ret:
06308 if (local_syms != NULL
06309 && symtab_hdr->contents != (unsigned char *) local_syms)
06310 free (local_syms);
06311 if (elf_section_data (sec)->relocs != relstart)
06312 free (relstart);
06313 return FALSE;
06314 }
06315 sec->contents = loc;
06316 sec->flags |= (SEC_IN_MEMORY | SEC_HAS_CONTENTS);
06317 }
06318
06319 elf_section_data (sec)->relocs = relstart;
06320
06321 new_contents = sec->contents;
06322 if (add_aux_fields)
06323 {
06324 new_contents = bfd_malloc (sec->size + cnt_16b * 8);
06325 if (new_contents == NULL)
06326 return FALSE;
06327 need_pad = FALSE;
06328 }
06329 wptr = new_contents;
06330 rptr = sec->contents;
06331
06332 write_rel = relstart;
06333 skip = FALSE;
06334 offset = 0;
06335 opd_ent_size = 0;
06336 for (rel = relstart; rel < relend; rel++)
06337 {
06338 unsigned long r_symndx;
06339 asection *sym_sec;
06340 struct elf_link_hash_entry *h;
06341 Elf_Internal_Sym *sym;
06342
06343 r_symndx = ELF64_R_SYM (rel->r_info);
06344 if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
06345 r_symndx, ibfd))
06346 goto error_ret;
06347
06348 if (rel->r_offset == offset)
06349 {
06350 struct ppc_link_hash_entry *fdh = NULL;
06351
06352
06353
06354
06355 opd_ent_size = 24;
06356 if ((rel + 2 == relend && sec->size == offset + 16)
06357 || (rel + 3 < relend
06358 && rel[2].r_offset == offset + 16
06359 && rel[3].r_offset == offset + 24
06360 && ELF64_R_TYPE (rel[2].r_info) == R_PPC64_ADDR64
06361 && ELF64_R_TYPE (rel[3].r_info) == R_PPC64_TOC))
06362 opd_ent_size = 16;
06363
06364 if (h != NULL
06365 && h->root.root.string[0] == '.')
06366 {
06367 fdh = get_fdh ((struct ppc_link_hash_entry *) h,
06368 ppc_hash_table (info));
06369 if (fdh != NULL
06370 && fdh->elf.root.type != bfd_link_hash_defined
06371 && fdh->elf.root.type != bfd_link_hash_defweak)
06372 fdh = NULL;
06373 }
06374
06375 skip = (sym_sec->owner != ibfd
06376 || sym_sec->output_section == bfd_abs_section_ptr);
06377 if (skip)
06378 {
06379 if (fdh != NULL && sym_sec->owner == ibfd)
06380 {
06381
06382
06383 fdh->elf.root.u.def.value = 0;
06384 fdh->elf.root.u.def.section = sym_sec;
06385 }
06386 opd_adjust[rel->r_offset / 8] = -1;
06387 }
06388 else
06389 {
06390
06391
06392 if (fdh != NULL)
06393 {
06394
06395
06396
06397
06398
06399
06400
06401 fdh->elf.root.u.def.value = wptr - new_contents;
06402 fdh->adjust_done = 1;
06403 }
06404
06405
06406
06407
06408
06409
06410
06411 opd_adjust[rel->r_offset / 8]
06412 = (wptr - new_contents) - (rptr - sec->contents);
06413
06414 if (wptr != rptr)
06415 memcpy (wptr, rptr, opd_ent_size);
06416 wptr += opd_ent_size;
06417 if (add_aux_fields && opd_ent_size == 16)
06418 {
06419 memset (wptr, '\0', 8);
06420 wptr += 8;
06421 }
06422 }
06423 rptr += opd_ent_size;
06424 offset += opd_ent_size;
06425 }
06426
06427 if (skip)
06428 {
06429 if (!dec_dynrel_count (rel->r_info, sec, info,
06430 NULL, h, sym_sec))
06431 goto error_ret;
06432 }
06433 else
06434 {
06435
06436
06437
06438 rel->r_offset += opd_adjust[(offset - opd_ent_size) / 8];
06439 if (write_rel != rel)
06440 memcpy (write_rel, rel, sizeof (*rel));
06441 ++write_rel;
06442 }
06443 }
06444
06445 sec->size = wptr - new_contents;
06446 sec->reloc_count = write_rel - relstart;
06447 if (add_aux_fields)
06448 {
06449 free (sec->contents);
06450 sec->contents = new_contents;
06451 }
06452
06453
06454
06455 elf_section_data (sec)->rel_hdr.sh_size
06456 = sec->reloc_count * elf_section_data (sec)->rel_hdr.sh_entsize;
06457 BFD_ASSERT (elf_section_data (sec)->rel_hdr2 == NULL);
06458 some_edited = TRUE;
06459 }
06460 else if (elf_section_data (sec)->relocs != relstart)
06461 free (relstart);
06462
06463 if (local_syms != NULL
06464 && symtab_hdr->contents != (unsigned char *) local_syms)
06465 {
06466 if (!info->keep_memory)
06467 free (local_syms);
06468 else
06469 symtab_hdr->contents = (unsigned char *) local_syms;
06470 }
06471 }
06472
06473 if (some_edited)
06474 elf_link_hash_traverse (elf_hash_table (info), adjust_opd_syms, NULL);
06475
06476
06477
06478 if (need_pad != NULL && !info->relocatable)
06479 {
06480 bfd_byte *p;
06481
06482 if ((need_pad->flags & SEC_IN_MEMORY) == 0)
06483 {
06484 BFD_ASSERT (need_pad->size > 0);
06485
06486 p = bfd_malloc (need_pad->size + 8);
06487 if (p == NULL)
06488 return FALSE;
06489
06490 if (! bfd_get_section_contents (need_pad->owner, need_pad,
06491 p, 0, need_pad->size))
06492 return FALSE;
06493
06494 need_pad->contents = p;
06495 need_pad->flags |= (SEC_IN_MEMORY | SEC_HAS_CONTENTS);
06496 }
06497 else
06498 {
06499 p = bfd_realloc (need_pad->contents, need_pad->size + 8);
06500 if (p == NULL)
06501 return FALSE;
06502
06503 need_pad->contents = p;
06504 }
06505
06506 memset (need_pad->contents + need_pad->size, 0, 8);
06507 need_pad->size += 8;
06508 }
06509
06510 return TRUE;
06511 }
06512
06513
06514
06515 asection *
06516 ppc64_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
06517 {
06518 struct ppc_link_hash_table *htab;
06519
06520 htab = ppc_hash_table (info);
06521 if (htab->tls_get_addr != NULL)
06522 {
06523 struct ppc_link_hash_entry *h = htab->tls_get_addr;
06524
06525 while (h->elf.root.type == bfd_link_hash_indirect
06526 || h->elf.root.type == bfd_link_hash_warning)
06527 h = (struct ppc_link_hash_entry *) h->elf.root.u.i.link;
06528
06529 htab->tls_get_addr = h;
06530
06531 if (htab->tls_get_addr_fd == NULL
06532 && h->oh != NULL
06533 && h->oh->is_func_descriptor
06534 && (h->oh->elf.root.type == bfd_link_hash_defined
06535 || h->oh->elf.root.type == bfd_link_hash_defweak))
06536 htab->tls_get_addr_fd = h->oh;
06537 }
06538
06539 if (htab->tls_get_addr_fd != NULL)
06540 {
06541 struct ppc_link_hash_entry *h = htab->tls_get_addr_fd;
06542
06543 while (h->elf.root.type == bfd_link_hash_indirect
06544 || h->elf.root.type == bfd_link_hash_warning)
06545 h = (struct ppc_link_hash_entry *) h->elf.root.u.i.link;
06546
06547 htab->tls_get_addr_fd = h;
06548 }
06549
06550 return _bfd_elf_tls_setup (obfd, info);
06551 }
06552
06553
06554
06555
06556
06557
06558
06559
06560 bfd_boolean
06561 ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
06562 {
06563 bfd *ibfd;
06564 asection *sec;
06565 struct ppc_link_hash_table *htab;
06566
06567 if (info->relocatable || info->shared)
06568 return TRUE;
06569
06570 htab = ppc_hash_table (info);
06571 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
06572 {
06573 Elf_Internal_Sym *locsyms = NULL;
06574
06575 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
06576 if (sec->has_tls_reloc && !bfd_is_abs_section (sec->output_section))
06577 {
06578 Elf_Internal_Rela *relstart, *rel, *relend;
06579 int expecting_tls_get_addr;
06580
06581
06582 relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
06583 info->keep_memory);
06584 if (relstart == NULL)
06585 return FALSE;
06586
06587 expecting_tls_get_addr = 0;
06588 relend = relstart + sec->reloc_count;
06589 for (rel = relstart; rel < relend; rel++)
06590 {
06591 enum elf_ppc64_reloc_type r_type;
06592 unsigned long r_symndx;
06593 struct elf_link_hash_entry *h;
06594 Elf_Internal_Sym *sym;
06595 asection *sym_sec;
06596 char *tls_mask;
06597 char tls_set, tls_clear, tls_type = 0;
06598 bfd_vma value;
06599 bfd_boolean ok_tprel, is_local;
06600
06601 r_symndx = ELF64_R_SYM (rel->r_info);
06602 if (!get_sym_h (&h, &sym, &sym_sec, &tls_mask, &locsyms,
06603 r_symndx, ibfd))
06604 {
06605 err_free_rel:
06606 if (elf_section_data (sec)->relocs != relstart)
06607 free (relstart);
06608 if (locsyms != NULL
06609 && (elf_tdata (ibfd)->symtab_hdr.contents
06610 != (unsigned char *) locsyms))
06611 free (locsyms);
06612 return FALSE;
06613 }
06614
06615 if (h != NULL)
06616 {
06617 if (h->root.type != bfd_link_hash_defined
06618 && h->root.type != bfd_link_hash_defweak)
06619 continue;
06620 value = h->root.u.def.value;
06621 }
06622 else
06623
06624
06625 value = sym->st_value;
06626
06627 ok_tprel = FALSE;
06628 is_local = FALSE;
06629 if (h == NULL
06630 || !h->def_dynamic)
06631 {
06632 is_local = TRUE;
06633 value += sym_sec->output_offset;
06634 value += sym_sec->output_section->vma;
06635 value -= htab->elf.tls_sec->vma;
06636 ok_tprel = (value + TP_OFFSET + ((bfd_vma) 1 << 31)
06637 < (bfd_vma) 1 << 32);
06638 }
06639
06640 r_type = ELF64_R_TYPE (rel->r_info);
06641 switch (r_type)
06642 {
06643 case R_PPC64_GOT_TLSLD16:
06644 case R_PPC64_GOT_TLSLD16_LO:
06645 case R_PPC64_GOT_TLSLD16_HI:
06646 case R_PPC64_GOT_TLSLD16_HA:
06647
06648
06649
06650 ppc64_tlsld_got (ibfd)->refcount -= 1;
06651 if (!is_local)
06652 continue;
06653
06654
06655 tls_set = 0;
06656 tls_clear = TLS_LD;
06657 tls_type = TLS_TLS | TLS_LD;
06658 expecting_tls_get_addr = 1;
06659 break;
06660
06661 case R_PPC64_GOT_TLSGD16:
06662 case R_PPC64_GOT_TLSGD16_LO:
06663 case R_PPC64_GOT_TLSGD16_HI:
06664 case R_PPC64_GOT_TLSGD16_HA:
06665 if (ok_tprel)
06666
06667 tls_set = 0;
06668 else
06669
06670 tls_set = TLS_TLS | TLS_TPRELGD;
06671 tls_clear = TLS_GD;
06672 tls_type = TLS_TLS | TLS_GD;
06673 expecting_tls_get_addr = 1;
06674 break;
06675
06676 case R_PPC64_GOT_TPREL16_DS:
06677 case R_PPC64_GOT_TPREL16_LO_DS:
06678 case R_PPC64_GOT_TPREL16_HI:
06679 case R_PPC64_GOT_TPREL16_HA:
06680 expecting_tls_get_addr = 0;
06681 if (ok_tprel)
06682 {
06683
06684 tls_set = 0;
06685 tls_clear = TLS_TPREL;
06686 tls_type = TLS_TLS | TLS_TPREL;
06687 break;
06688 }
06689 else
06690 continue;
06691
06692 case R_PPC64_REL14:
06693 case R_PPC64_REL14_BRTAKEN:
06694 case R_PPC64_REL14_BRNTAKEN:
06695 case R_PPC64_REL24:
06696 if (h != NULL
06697 && (h == &htab->tls_get_addr->elf
06698 || h == &htab->tls_get_addr_fd->elf))
06699 {
06700 if (!expecting_tls_get_addr
06701 && rel != relstart
06702 && ((ELF64_R_TYPE (rel[-1].r_info)
06703 == R_PPC64_TOC16)
06704 || (ELF64_R_TYPE (rel[-1].r_info)
06705 == R_PPC64_TOC16_LO)))
06706 {
06707
06708 char *toc_tls;
06709 int retval;
06710
06711 retval = get_tls_mask (&toc_tls, NULL, &locsyms,
06712 rel - 1, ibfd);
06713 if (retval == 0)
06714 goto err_free_rel;
06715 if (toc_tls != NULL)
06716 expecting_tls_get_addr = retval > 1;
06717 }
06718
06719 if (expecting_tls_get_addr)
06720 {
06721 struct plt_entry *ent;
06722 for (ent = h->plt.plist; ent; ent = ent->next)
06723 if (ent->addend == 0)
06724 {
06725 if (ent->plt.refcount > 0)
06726 ent->plt.refcount -= 1;
06727 break;
06728 }
06729 }
06730 }
06731 expecting_tls_get_addr = 0;
06732 continue;
06733
06734 case R_PPC64_TPREL64:
06735 expecting_tls_get_addr = 0;
06736 if (ok_tprel)
06737 {
06738
06739 tls_set = TLS_EXPLICIT;
06740 tls_clear = TLS_TPREL;
06741 break;
06742 }
06743 else
06744 continue;
06745
06746 case R_PPC64_DTPMOD64:
06747 expecting_tls_get_addr = 0;
06748 if (rel + 1 < relend
06749 && (rel[1].r_info
06750 == ELF64_R_INFO (r_symndx, R_PPC64_DTPREL64))
06751 && rel[1].r_offset == rel->r_offset + 8)
06752 {
06753 if (ok_tprel)
06754
06755 tls_set = TLS_EXPLICIT | TLS_GD;
06756 else
06757
06758 tls_set = TLS_EXPLICIT | TLS_GD | TLS_TPRELGD;
06759 tls_clear = TLS_GD;
06760 }
06761 else
06762 {
06763 if (!is_local)
06764 continue;
06765
06766
06767 tls_set = TLS_EXPLICIT;
06768 tls_clear = TLS_LD;
06769 }
06770 break;
06771
06772 default:
06773 expecting_tls_get_addr = 0;
06774 continue;
06775 }
06776
06777 if ((tls_set & TLS_EXPLICIT) == 0)
06778 {
06779 struct got_entry *ent;
06780
06781
06782 if (h != NULL)
06783 ent = h->got.glist;
06784 else
06785 ent = elf_local_got_ents (ibfd)[r_symndx];
06786
06787 for (; ent != NULL; ent = ent->next)
06788 if (ent->addend == rel->r_addend
06789 && ent->owner == ibfd
06790 && ent->tls_type == tls_type)
06791 break;
06792 if (ent == NULL)
06793 abort ();
06794
06795 if (tls_set == 0)
06796 {
06797
06798 if (ent->got.refcount > 0)
06799 ent->got.refcount -= 1;
06800 }
06801 }
06802 else
06803 {
06804
06805
06806 if (!dec_dynrel_count (rel->r_info, sec, info,
06807 NULL, h, sym_sec))
06808 return FALSE;
06809
06810 if (tls_set == (TLS_EXPLICIT | TLS_GD))
06811 {
06812 if (!dec_dynrel_count ((rel + 1)->r_info, sec, info,
06813 NULL, h, sym_sec))
06814 return FALSE;
06815 }
06816 }
06817
06818 *tls_mask |= tls_set;
06819 *tls_mask &= ~tls_clear;
06820 }
06821
06822 if (elf_section_data (sec)->relocs != relstart)
06823 free (relstart);
06824 }
06825
06826 if (locsyms != NULL
06827 && (elf_tdata (ibfd)->symtab_hdr.contents
06828 != (unsigned char *) locsyms))
06829 {
06830 if (!info->keep_memory)
06831 free (locsyms);
06832 else
06833 elf_tdata (ibfd)->symtab_hdr.contents = (unsigned char *) locsyms;
06834 }
06835 }
06836 return TRUE;
06837 }
06838
06839
06840
06841
06842
06843
06844
06845 struct adjust_toc_info
06846 {
06847 asection *toc;
06848 unsigned long *skip;
06849 bfd_boolean global_toc_syms;
06850 };
06851
06852 static bfd_boolean
06853 adjust_toc_syms (struct elf_link_hash_entry *h, void *inf)
06854 {
06855 struct ppc_link_hash_entry *eh;
06856 struct adjust_toc_info *toc_inf = (struct adjust_toc_info *) inf;
06857
06858 if (h->root.type == bfd_link_hash_indirect)
06859 return TRUE;
06860
06861 if (h->root.type == bfd_link_hash_warning)
06862 h = (struct elf_link_hash_entry *) h->root.u.i.link;
06863
06864 if (h->root.type != bfd_link_hash_defined
06865 && h->root.type != bfd_link_hash_defweak)
06866 return TRUE;
06867
06868 eh = (struct ppc_link_hash_entry *) h;
06869 if (eh->adjust_done)
06870 return TRUE;
06871
06872 if (eh->elf.root.u.def.section == toc_inf->toc)
06873 {
06874 unsigned long skip = toc_inf->skip[eh->elf.root.u.def.value >> 3];
06875 if (skip != (unsigned long) -1)
06876 eh->elf.root.u.def.value -= skip;
06877 else
06878 {
06879 (*_bfd_error_handler)
06880 (_("%s defined in removed toc entry"), eh->elf.root.root.string);
06881 eh->elf.root.u.def.section = &bfd_abs_section;
06882 eh->elf.root.u.def.value = 0;
06883 }
06884 eh->adjust_done = 1;
06885 }
06886 else if (strcmp (eh->elf.root.u.def.section->name, ".toc") == 0)
06887 toc_inf->global_toc_syms = TRUE;
06888
06889 return TRUE;
06890 }
06891
06892
06893
06894
06895 bfd_boolean
06896 ppc64_elf_edit_toc (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
06897 {
06898 bfd *ibfd;
06899 struct adjust_toc_info toc_inf;
06900
06901 toc_inf.global_toc_syms = TRUE;
06902 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
06903 {
06904 asection *toc, *sec;
06905 Elf_Internal_Shdr *symtab_hdr;
06906 Elf_Internal_Sym *local_syms;
06907 struct elf_link_hash_entry **sym_hashes;
06908 Elf_Internal_Rela *relstart, *rel;
06909 unsigned long *skip, *drop;
06910 unsigned char *used;
06911 unsigned char *keep, last, some_unused;
06912
06913 toc = bfd_get_section_by_name (ibfd, ".toc");
06914 if (toc == NULL
06915 || toc->size == 0
06916 || toc->sec_info_type == ELF_INFO_TYPE_JUST_SYMS
06917 || elf_discarded_section (toc))
06918 continue;
06919
06920 local_syms = NULL;
06921 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
06922 sym_hashes = elf_sym_hashes (ibfd);
06923
06924
06925 skip = NULL;
06926 relstart = NULL;
06927 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
06928 {
06929 if (sec->reloc_count == 0
06930 || !elf_discarded_section (sec)
06931 || get_opd_info (sec)
06932 || (sec->flags & SEC_ALLOC) == 0
06933 || (sec->flags & SEC_DEBUGGING) != 0)
06934 continue;
06935
06936 relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL, FALSE);
06937 if (relstart == NULL)
06938 goto error_ret;
06939
06940
06941
06942 for (rel = relstart; rel < relstart + sec->reloc_count; ++rel)
06943 {
06944 enum elf_ppc64_reloc_type r_type;
06945 unsigned long r_symndx;
06946 asection *sym_sec;
06947 struct elf_link_hash_entry *h;
06948 Elf_Internal_Sym *sym;
06949 bfd_vma val;
06950
06951 r_type = ELF64_R_TYPE (rel->r_info);
06952 switch (r_type)
06953 {
06954 default:
06955 continue;
06956
06957 case R_PPC64_TOC16:
06958 case R_PPC64_TOC16_LO:
06959 case R_PPC64_TOC16_HI:
06960 case R_PPC64_TOC16_HA:
06961 case R_PPC64_TOC16_DS:
06962 case R_PPC64_TOC16_LO_DS:
06963 break;
06964 }
06965
06966 r_symndx = ELF64_R_SYM (rel->r_info);
06967 if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
06968 r_symndx, ibfd))
06969 goto error_ret;
06970
06971 if (sym_sec != toc)
06972 continue;
06973
06974 if (h != NULL)
06975 val = h->root.u.def.value;
06976 else
06977 val = sym->st_value;
06978 val += rel->r_addend;
06979
06980 if (val >= toc->size)
06981 continue;
06982
06983
06984
06985 if (val & 7)
06986 continue;
06987
06988 if (skip == NULL)
06989 {
06990 skip = bfd_zmalloc (sizeof (*skip) * (toc->size + 7) / 8);
06991 if (skip == NULL)
06992 goto error_ret;
06993 }
06994
06995 skip[val >> 3] = 1;
06996 }
06997
06998 if (elf_section_data (sec)->relocs != relstart)
06999 free (relstart);
07000 }
07001
07002 if (skip == NULL)
07003 continue;
07004
07005 used = bfd_zmalloc (sizeof (*used) * (toc->size + 7) / 8);
07006 if (used == NULL)
07007 {
07008 error_ret:
07009 if (local_syms != NULL
07010 && symtab_hdr->contents != (unsigned char *) local_syms)
07011 free (local_syms);
07012 if (sec != NULL
07013 && relstart != NULL
07014 && elf_section_data (sec)->relocs != relstart)
07015 free (relstart);
07016 if (skip != NULL)
07017 free (skip);
07018 return FALSE;
07019 }
07020
07021
07022 for (sec = ibfd->sections;
07023 sec != NULL;
07024
07025 sec = (sec == toc ? NULL
07026 : sec->next == toc && sec->next->next ? sec->next->next
07027 : sec->next == NULL ? toc
07028 : sec->next))
07029 {
07030 int repeat;
07031
07032 if (sec->reloc_count == 0
07033 || elf_discarded_section (sec)
07034 || get_opd_info (sec)
07035 || (sec->flags & SEC_ALLOC) == 0
07036 || (sec->flags & SEC_DEBUGGING) != 0)
07037 continue;
07038
07039 relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL, TRUE);
07040 if (relstart == NULL)
07041 goto error_ret;
07042
07043
07044 repeat = 0;
07045 do
07046 for (rel = relstart; rel < relstart + sec->reloc_count; ++rel)
07047 {
07048 enum elf_ppc64_reloc_type r_type;
07049 unsigned long r_symndx;
07050 asection *sym_sec;
07051 struct elf_link_hash_entry *h;
07052 Elf_Internal_Sym *sym;
07053 bfd_vma val;
07054
07055 r_type = ELF64_R_TYPE (rel->r_info);
07056 switch (r_type)
07057 {
07058 case R_PPC64_TOC16:
07059 case R_PPC64_TOC16_LO:
07060 case R_PPC64_TOC16_HI:
07061 case R_PPC64_TOC16_HA:
07062 case R_PPC64_TOC16_DS:
07063 case R_PPC64_TOC16_LO_DS:
07064
07065 case R_PPC64_ADDR64:
07066 break;
07067
07068 default:
07069 continue;
07070 }
07071
07072 r_symndx = ELF64_R_SYM (rel->r_info);
07073 if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
07074 r_symndx, ibfd))
07075 {
07076 free (used);
07077 goto error_ret;
07078 }
07079
07080 if (sym_sec != toc)
07081 continue;
07082
07083 if (h != NULL)
07084 val = h->root.u.def.value;
07085 else
07086 val = sym->st_value;
07087 val += rel->r_addend;
07088
07089 if (val >= toc->size)
07090 continue;
07091
07092
07093
07094 if (sec == toc
07095 && !used[val >> 3]
07096 && (used[rel->r_offset >> 3]
07097 || !skip[rel->r_offset >> 3]))
07098
07099
07100 repeat = 1;
07101
07102 used[val >> 3] = 1;
07103 }
07104 while (repeat);
07105 }
07106
07107
07108
07109
07110 for (drop = skip, keep = used, last = 0, some_unused = 0;
07111 drop < skip + (toc->size + 7) / 8;
07112 ++drop, ++keep)
07113 {
07114 if (*keep)
07115 {
07116 *drop = 0;
07117 last = 0;
07118 }
07119 else if (*drop)
07120 {
07121 some_unused = 1;
07122 last = 1;
07123 }
07124 else
07125 *drop = last;
07126 }
07127
07128 free (used);
07129
07130 if (some_unused)
07131 {
07132 bfd_byte *contents, *src;
07133 unsigned long off;
07134
07135
07136
07137 if (!bfd_malloc_and_get_section (ibfd, toc, &contents))
07138 goto error_ret;
07139
07140 elf_section_data (toc)->this_hdr.contents = contents;
07141
07142 for (src = contents, off = 0, drop = skip;
07143 src < contents + toc->size;
07144 src += 8, ++drop)
07145 {
07146 if (*drop)
07147 {
07148 *drop = (unsigned long) -1;
07149 off += 8;
07150 }
07151 else if (off != 0)
07152 {
07153 *drop = off;
07154 memcpy (src - off, src, 8);
07155 }
07156 }
07157 toc->rawsize = toc->size;
07158 toc->size = src - contents - off;
07159
07160 if (toc->reloc_count != 0)
07161 {
07162 Elf_Internal_Rela *wrel;
07163 bfd_size_type sz;
07164
07165
07166 relstart = _bfd_elf_link_read_relocs (ibfd, toc, NULL, NULL,
07167 TRUE);
07168 if (relstart == NULL)
07169 goto error_ret;
07170
07171
07172 wrel = relstart;
07173 for (rel = relstart; rel < relstart + toc->reloc_count; ++rel)
07174 if (skip[rel->r_offset >> 3] != (unsigned long) -1)
07175 {
07176 wrel->r_offset = rel->r_offset - skip[rel->r_offset >> 3];
07177 wrel->r_info = rel->r_info;
07178 wrel->r_addend = rel->r_addend;
07179 ++wrel;
07180 }
07181 else if (!dec_dynrel_count (rel->r_info, toc, info,
07182 &local_syms, NULL, NULL))
07183 goto error_ret;
07184
07185 toc->reloc_count = wrel - relstart;
07186 sz = elf_section_data (toc)->rel_hdr.sh_entsize;
07187 elf_section_data (toc)->rel_hdr.sh_size = toc->reloc_count * sz;
07188 BFD_ASSERT (elf_section_data (toc)->rel_hdr2 == NULL);
07189 }
07190
07191
07192 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
07193 {
07194 if (sec->reloc_count == 0
07195 || elf_discarded_section (sec))
07196 continue;
07197
07198 relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
07199 TRUE);
07200 if (relstart == NULL)
07201 goto error_ret;
07202
07203 for (rel = relstart; rel < relstart + sec->reloc_count; ++rel)
07204 {
07205 enum elf_ppc64_reloc_type r_type;
07206 unsigned long r_symndx;
07207 asection *sym_sec;
07208 struct elf_link_hash_entry *h;
07209 Elf_Internal_Sym *sym;
07210
07211 r_type = ELF64_R_TYPE (rel->r_info);
07212 switch (r_type)
07213 {
07214 default:
07215 continue;
07216
07217 case R_PPC64_TOC16:
07218 case R_PPC64_TOC16_LO:
07219 case R_PPC64_TOC16_HI:
07220 case R_PPC64_TOC16_HA:
07221 case R_PPC64_TOC16_DS:
07222 case R_PPC64_TOC16_LO_DS:
07223 case R_PPC64_ADDR64:
07224 break;
07225 }
07226
07227 r_symndx = ELF64_R_SYM (rel->r_info);
07228 if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
07229 r_symndx, ibfd))
07230 goto error_ret;
07231
07232 if (sym_sec != toc || h != NULL || sym->st_value != 0)
07233 continue;
07234
07235 rel->r_addend -= skip[rel->r_addend >> 3];
07236 }
07237 }
07238
07239
07240
07241 if (local_syms != NULL)
07242 {
07243 Elf_Internal_Sym *sym;
07244
07245 for (sym = local_syms;
07246 sym < local_syms + symtab_hdr->sh_info;
07247 ++sym)
07248 if (sym->st_shndx != SHN_UNDEF
07249 && (sym->st_shndx < SHN_LORESERVE
07250 || sym->st_shndx > SHN_HIRESERVE)
07251 && sym->st_value != 0
07252 && bfd_section_from_elf_index (ibfd, sym->st_shndx) == toc)
07253 {
07254 if (skip[sym->st_value >> 3] != (unsigned long) -1)
07255 sym->st_value -= skip[sym->st_value >> 3];
07256 else
07257 {
07258 (*_bfd_error_handler)
07259 (_("%s defined in removed toc entry"),
07260 bfd_elf_sym_name (ibfd, symtab_hdr, sym));
07261 sym->st_value = 0;
07262 sym->st_shndx = SHN_ABS;
07263 }
07264 symtab_hdr->contents = (unsigned char *) local_syms;
07265 }
07266 }
07267
07268
07269 if (toc_inf.global_toc_syms)
07270 {
07271 toc_inf.toc = toc;
07272 toc_inf.skip = skip;
07273 toc_inf.global_toc_syms = FALSE;
07274 elf_link_hash_traverse (elf_hash_table (info), adjust_toc_syms,
07275 &toc_inf);
07276 }
07277 }
07278
07279 if (local_syms != NULL
07280 && symtab_hdr->contents != (unsigned char *) local_syms)
07281 {
07282 if (!info->keep_memory)
07283 free (local_syms);
07284 else
07285 symtab_hdr->contents = (unsigned char *) local_syms;
07286 }
07287 free (skip);
07288 }
07289
07290 return TRUE;
07291 }
07292
07293
07294
07295
07296 static bfd_boolean
07297 allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
07298 {
07299 struct bfd_link_info *info;
07300 struct ppc_link_hash_table *htab;
07301 asection *s;
07302 struct ppc_link_hash_entry *eh;
07303 struct ppc_dyn_relocs *p;
07304 struct got_entry *gent;
07305
07306 if (h->root.type == bfd_link_hash_indirect)
07307 return TRUE;
07308
07309 if (h->root.type == bfd_link_hash_warning)
07310 h = (struct elf_link_hash_entry *) h->root.u.i.link;
07311
07312 info = (struct bfd_link_info *) inf;
07313 htab = ppc_hash_table (info);
07314
07315 if (htab->elf.dynamic_sections_created
07316 && h->dynindx != -1
07317 && WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
07318 {
07319 struct plt_entry *pent;
07320 bfd_boolean doneone = FALSE;
07321 for (pent = h->plt.plist; pent != NULL; pent = pent->next)
07322 if (pent->plt.refcount > 0)
07323 {
07324
07325
07326 s = htab->plt;
07327 if (s->size == 0)
07328 s->size += PLT_INITIAL_ENTRY_SIZE;
07329
07330 pent->plt.offset = s->size;
07331
07332
07333 s->size += PLT_ENTRY_SIZE;
07334
07335
07336 s = htab->glink;
07337 if (s->size == 0)
07338 s->size += GLINK_CALL_STUB_SIZE;
07339
07340 if (s->size >= GLINK_CALL_STUB_SIZE + 32768*2*4)
07341 s->size += 4;
07342 s->size += 2*4;
07343
07344
07345 s = htab->relplt;
07346 s->size += sizeof (Elf64_External_Rela);
07347 doneone = TRUE;
07348 }
07349 else
07350 pent->plt.offset = (bfd_vma) -1;
07351 if (!doneone)
07352 {
07353 h->plt.plist = NULL;
07354 h->needs_plt = 0;
07355 }
07356 }
07357 else
07358 {
07359 h->plt.plist = NULL;
07360 h->needs_plt = 0;
07361 }
07362
07363 eh = (struct ppc_link_hash_entry *) h;
07364
07365
07366 if ((eh->tls_mask & TLS_TPRELGD) != 0)
07367 for (gent = h->got.glist; gent != NULL; gent = gent->next)
07368 if (gent->got.refcount > 0
07369 && (gent->tls_type & TLS_GD) != 0)
07370 {
07371
07372
07373 struct got_entry *ent;
07374 for (ent = h->got.glist; ent != NULL; ent = ent->next)
07375 if (ent->got.refcount > 0
07376 && (ent->tls_type & TLS_TPREL) != 0
07377 && ent->addend == gent->addend
07378 && ent->owner == gent->owner)
07379 {
07380 gent->got.refcount = 0;
07381 break;
07382 }
07383
07384
07385 if (gent->got.refcount != 0)
07386 gent->tls_type = TLS_TLS | TLS_TPREL;
07387 }
07388
07389 for (gent = h->got.glist; gent != NULL; gent = gent->next)
07390 if (gent->got.refcount > 0)
07391 {
07392 bfd_boolean dyn;
07393
07394
07395
07396
07397 if (h->dynindx == -1
07398 && !h->forced_local)
07399 {
07400 if (! bfd_elf_link_record_dynamic_symbol (info, h))
07401 return FALSE;
07402 }
07403
07404 if ((gent->tls_type & TLS_LD) != 0
07405 && !h->def_dynamic)
07406 {
07407 gent->got.offset = ppc64_tlsld_got (gent->owner)->offset;
07408 continue;
07409 }
07410
07411 s = ppc64_elf_tdata (gent->owner)->got;
07412 gent->got.offset = s->size;
07413 s->size
07414 += (gent->tls_type & eh->tls_mask & (TLS_GD | TLS_LD)) ? 16 : 8;
07415 dyn = htab->elf.dynamic_sections_created;
07416 if ((info->shared
07417 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
07418 && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
07419 || h->root.type != bfd_link_hash_undefweak))
07420 ppc64_elf_tdata (gent->owner)->relgot->size
07421 += (gent->tls_type & eh->tls_mask & TLS_GD
07422 ? 2 * sizeof (Elf64_External_Rela)
07423 : sizeof (Elf64_External_Rela));
07424 }
07425 else
07426 gent->got.offset = (bfd_vma) -1;
07427
07428 if (eh->dyn_relocs == NULL)
07429 return TRUE;
07430
07431
07432
07433
07434
07435
07436
07437 if (info->shared)
07438 {
07439
07440
07441
07442
07443
07444
07445 if (SYMBOL_CALLS_LOCAL (info, h))
07446 {
07447 struct ppc_dyn_relocs **pp;
07448
07449 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
07450 {
07451 p->count -= p->pc_count;
07452 p->pc_count = 0;
07453 if (p->count == 0)
07454 *pp = p->next;
07455 else
07456 pp = &p->next;
07457 }
07458 }
07459
07460
07461
07462 if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
07463 && h->root.type == bfd_link_hash_undefweak)
07464 eh->dyn_relocs = NULL;
07465 }
07466 else if (ELIMINATE_COPY_RELOCS)
07467 {
07468
07469
07470
07471
07472 if (!h->non_got_ref
07473 && h->def_dynamic
07474 && !h->def_regular)
07475 {
07476
07477
07478 if (h->dynindx == -1
07479 && !h->forced_local)
07480 {
07481 if (! bfd_elf_link_record_dynamic_symbol (info, h))
07482 return FALSE;
07483 }
07484
07485
07486
07487 if (h->dynindx != -1)
07488 goto keep;
07489 }
07490
07491 eh->dyn_relocs = NULL;
07492
07493 keep: ;
07494 }
07495
07496
07497 for (p = eh->dyn_relocs; p != NULL; p = p->next)
07498 {
07499 asection *sreloc = elf_section_data (p->sec)->sreloc;
07500 sreloc->size += p->count * sizeof (Elf64_External_Rela);
07501 }
07502
07503 return TRUE;
07504 }
07505
07506
07507
07508 static bfd_boolean
07509 readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
07510 {
07511 struct ppc_link_hash_entry *eh;
07512 struct ppc_dyn_relocs *p;
07513
07514 if (h->root.type == bfd_link_hash_warning)
07515 h = (struct elf_link_hash_entry *) h->root.u.i.link;
07516
07517 eh = (struct ppc_link_hash_entry *) h;
07518 for (p = eh->dyn_relocs; p != NULL; p = p->next)
07519 {
07520 asection *s = p->sec->output_section;
07521
07522 if (s != NULL && (s->flags & SEC_READONLY) != 0)
07523 {
07524 struct bfd_link_info *info = inf;
07525
07526 info->flags |= DF_TEXTREL;
07527
07528
07529 return FALSE;
07530 }
07531 }
07532 return TRUE;
07533 }
07534
07535
07536
07537 static bfd_boolean
07538 ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
07539 struct bfd_link_info *info)
07540 {
07541 struct ppc_link_hash_table *htab;
07542 bfd *dynobj;
07543 asection *s;
07544 bfd_boolean relocs;
07545 bfd *ibfd;
07546
07547 htab = ppc_hash_table (info);
07548 dynobj = htab->elf.dynobj;
07549 if (dynobj == NULL)
07550 abort ();
07551
07552 if (htab->elf.dynamic_sections_created)
07553 {
07554
07555 if (info->executable)
07556 {
07557 s = bfd_get_section_by_name (dynobj, ".interp");
07558 if (s == NULL)
07559 abort ();
07560 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
07561 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
07562 }
07563 }
07564
07565
07566
07567 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
07568 {
07569 struct got_entry **lgot_ents;
07570 struct got_entry **end_lgot_ents;
07571 char *lgot_masks;
07572 bfd_size_type locsymcount;
07573 Elf_Internal_Shdr *symtab_hdr;
07574 asection *srel;
07575
07576 if (!is_ppc64_elf_target (ibfd->xvec))
07577 continue;
07578
07579 if (ppc64_tlsld_got (ibfd)->refcount > 0)
07580 {
07581 s = ppc64_elf_tdata (ibfd)->got;
07582 ppc64_tlsld_got (ibfd)->offset = s->size;
07583 s->size += 16;
07584 if (info->shared)
07585 {
07586 srel = ppc64_elf_tdata (ibfd)->relgot;
07587 srel->size += sizeof (Elf64_External_Rela);
07588 }
07589 }
07590 else
07591 ppc64_tlsld_got (ibfd)->offset = (bfd_vma) -1;
07592
07593 for (s = ibfd->sections; s != NULL; s = s->next)
07594 {
07595 struct ppc_dyn_relocs *p;
07596
07597 for (p = *((struct ppc_dyn_relocs **)
07598 &elf_section_data (s)->local_dynrel);
07599 p != NULL;
07600 p = p->next)
07601 {
07602 if (!bfd_is_abs_section (p->sec)
07603 && bfd_is_abs_section (p->sec->output_section))
07604 {
07605
07606
07607
07608
07609 }
07610 else if (p->count != 0)
07611 {
07612 srel = elf_section_data (p->sec)->sreloc;
07613 srel->size += p->count * sizeof (Elf64_External_Rela);
07614 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
07615 info->flags |= DF_TEXTREL;
07616 }
07617 }
07618 }
07619
07620 lgot_ents = elf_local_got_ents (ibfd);
07621 if (!lgot_ents)
07622 continue;
07623
07624 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
07625 locsymcount = symtab_hdr->sh_info;
07626 end_lgot_ents = lgot_ents + locsymcount;
07627 lgot_masks = (char *) end_lgot_ents;
07628 s = ppc64_elf_tdata (ibfd)->got;
07629 srel = ppc64_elf_tdata (ibfd)->relgot;
07630 for (; lgot_ents < end_lgot_ents; ++lgot_ents, ++lgot_masks)
07631 {
07632 struct got_entry *ent;
07633
07634 for (ent = *lgot_ents; ent != NULL; ent = ent->next)
07635 if (ent->got.refcount > 0)
07636 {
07637 if ((ent->tls_type & *lgot_masks & TLS_LD) != 0)
07638 {
07639 if (ppc64_tlsld_got (ibfd)->offset == (bfd_vma) -1)
07640 {
07641 ppc64_tlsld_got (ibfd)->offset = s->size;
07642 s->size += 16;
07643 if (info->shared)
07644 srel->size += sizeof (Elf64_External_Rela);
07645 }
07646 ent->got.offset = ppc64_tlsld_got (ibfd)->offset;
07647 }
07648 else
07649 {
07650 ent->got.offset = s->size;
07651 if ((ent->tls_type & *lgot_masks & TLS_GD) != 0)
07652 {
07653 s->size += 16;
07654 if (info->shared)
07655 srel->size += 2 * sizeof (Elf64_External_Rela);
07656 }
07657 else
07658 {
07659 s->size += 8;
07660 if (info->shared)
07661 srel->size += sizeof (Elf64_External_Rela);
07662 }
07663 }
07664 }
07665 else
07666 ent->got.offset = (bfd_vma) -1;
07667 }
07668 }
07669
07670
07671
07672 elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
07673
07674
07675
07676 relocs = FALSE;
07677 for (s = dynobj->sections; s != NULL; s = s->next)
07678 {
07679 if ((s->flags & SEC_LINKER_CREATED) == 0)
07680 continue;
07681
07682 if (s == htab->brlt || s == htab->relbrlt)
07683
07684 continue;
07685 else if (s == htab->got
07686 || s == htab->plt
07687 || s == htab->glink)
07688 {
07689
07690
07691 }
07692 else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
07693 {
07694 if (s->size == 0)
07695 {
07696
07697
07698
07699
07700
07701
07702
07703
07704
07705 }
07706 else
07707 {
07708 if (s != htab->relplt)
07709 relocs = TRUE;
07710
07711
07712
07713 s->reloc_count = 0;
07714 }
07715 }
07716 else
07717 {
07718
07719 continue;
07720 }
07721
07722 if (s->size == 0)
07723 {
07724 _bfd_strip_section_from_output (info, s);
07725 continue;
07726 }
07727
07728
07729 if (s == htab->plt)
07730 continue;
07731
07732
07733
07734
07735
07736
07737
07738
07739 s->contents = bfd_zalloc (dynobj, s->size);
07740 if (s->contents == NULL)
07741 return FALSE;
07742 }
07743
07744 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
07745 {
07746 if (!is_ppc64_elf_target (ibfd->xvec))
07747 continue;
07748
07749 s = ppc64_elf_tdata (ibfd)->got;
07750 if (s != NULL && s != htab->got)
07751 {
07752 if (s->size == 0)
07753 _bfd_strip_section_from_output (info, s);
07754 else
07755 {
07756 s->contents = bfd_zalloc (ibfd, s->size);
07757 if (s->contents == NULL)
07758 return FALSE;
07759 }
07760 }
07761 s = ppc64_elf_tdata (ibfd)->relgot;
07762 if (s != NULL)
07763 {
07764 if (s->size == 0)
07765 _bfd_strip_section_from_output (info, s);
07766 else
07767 {
07768 s->contents = bfd_zalloc (ibfd, s->size);
07769 if (s->contents == NULL)
07770 return FALSE;
07771 relocs = TRUE;
07772 s->reloc_count = 0;
07773 }
07774 }
07775 }
07776
07777 if (htab->elf.dynamic_sections_created)
07778 {
07779
07780
07781
07782
07783
07784 #define add_dynamic_entry(TAG, VAL) \
07785 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
07786
07787 if (info->executable)
07788 {
07789 if (!add_dynamic_entry (DT_DEBUG, 0))
07790 return FALSE;
07791 }
07792
07793 if (htab->plt != NULL && htab->plt->size != 0)
07794 {
07795 if (!add_dynamic_entry (DT_PLTGOT, 0)
07796 || !add_dynamic_entry (DT_PLTRELSZ, 0)
07797 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
07798 || !add_dynamic_entry (DT_JMPREL, 0)
07799 || !add_dynamic_entry (DT_PPC64_GLINK, 0))
07800 return FALSE;
07801 }
07802
07803 if (NO_OPD_RELOCS)
07804 {
07805 if (!add_dynamic_entry (DT_PPC64_OPD, 0)
07806 || !add_dynamic_entry (DT_PPC64_OPDSZ, 0))
07807 return FALSE;
07808 }
07809
07810 if (relocs)
07811 {
07812 if (!add_dynamic_entry (DT_RELA, 0)
07813 || !add_dynamic_entry (DT_RELASZ, 0)
07814 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
07815 return FALSE;
07816
07817
07818
07819 if ((info->flags & DF_TEXTREL) == 0)
07820 elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info);
07821
07822 if ((info->flags & DF_TEXTREL) != 0)
07823 {
07824 if (!add_dynamic_entry (DT_TEXTREL, 0))
07825 return FALSE;
07826 }
07827 }
07828 }
07829 #undef add_dynamic_entry
07830
07831 return TRUE;
07832 }
07833
07834
07835
07836 static inline enum ppc_stub_type
07837 ppc_type_of_stub (asection *input_sec,
07838 const Elf_Internal_Rela *rel,
07839 struct ppc_link_hash_entry **hash,
07840 bfd_vma destination)
07841 {
07842 struct ppc_link_hash_entry *h = *hash;
07843 bfd_vma location;
07844 bfd_vma branch_offset;
07845 bfd_vma max_branch_offset;
07846 enum elf_ppc64_reloc_type r_type;
07847
07848 if (h != NULL)
07849 {
07850 if (h->oh != NULL
07851 && h->oh->is_func_descriptor)
07852 h = h->oh;
07853
07854 if (h->elf.dynindx != -1)
07855 {
07856 struct plt_entry *ent;
07857
07858 for (ent = h->elf.plt.plist; ent != NULL; ent = ent->next)
07859 if (ent->addend == rel->r_addend
07860 && ent->plt.offset != (bfd_vma) -1)
07861 {
07862 *hash = h;
07863 return ppc_stub_plt_call;
07864 }
07865 }
07866
07867 if (!(h->elf.root.type == bfd_link_hash_defined
07868 || h->elf.root.type == bfd_link_hash_defweak)
07869 || h->elf.root.u.def.section->output_section == NULL)
07870 return ppc_stub_none;
07871 }
07872
07873
07874 location = (input_sec->output_offset
07875 + input_sec->output_section->vma
07876 + rel->r_offset);
07877
07878 branch_offset = destination - location;
07879 r_type = ELF64_R_TYPE (rel->r_info);
07880
07881
07882 max_branch_offset = 1 << 25;
07883 if (r_type != R_PPC64_REL24)
07884 max_branch_offset = 1 << 15;
07885
07886 if (branch_offset + max_branch_offset >= 2 * max_branch_offset)
07887
07888
07889 return ppc_stub_long_branch;
07890
07891 return ppc_stub_none;
07892 }
07893
07894
07895
07896 static inline bfd_byte *
07897 build_plt_stub (bfd *obfd, bfd_byte *p, int offset)
07898 {
07899 #define PPC_LO(v) ((v) & 0xffff)
07900 #define PPC_HI(v) (((v) >> 16) & 0xffff)
07901 #define PPC_HA(v) PPC_HI ((v) + 0x8000)
07902
07903 bfd_put_32 (obfd, ADDIS_R12_R2 | PPC_HA (offset), p), p += 4;
07904 bfd_put_32 (obfd, STD_R2_40R1, p), p += 4;
07905 bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset), p), p += 4;
07906 if (PPC_HA (offset + 8) != PPC_HA (offset))
07907 bfd_put_32 (obfd, ADDIS_R12_R12 | 1, p), p += 4;
07908 offset += 8;
07909 bfd_put_32 (obfd, LD_R2_0R12 | PPC_LO (offset), p), p += 4;
07910 if (PPC_HA (offset + 8) != PPC_HA (offset))
07911 bfd_put_32 (obfd, ADDIS_R12_R12 | 1, p), p += 4;
07912 offset += 8;
07913 bfd_put_32 (obfd, MTCTR_R11, p), p += 4;
07914 bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset), p), p += 4;
07915 bfd_put_32 (obfd, BCTR, p), p += 4;
07916 return p;
07917 }
07918
07919 static bfd_boolean
07920 ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
07921 {
07922 struct ppc_stub_hash_entry *stub_entry;
07923 struct ppc_branch_hash_entry *br_entry;
07924 struct bfd_link_info *info;
07925 struct ppc_link_hash_table *htab;
07926 bfd_byte *loc;
07927 bfd_byte *p;
07928 unsigned int indx;
07929 struct plt_entry *ent;
07930 bfd_vma dest, off;
07931 int size;
07932
07933
07934 stub_entry = (struct ppc_stub_hash_entry *) gen_entry;
07935 info = in_arg;
07936
07937 htab = ppc_hash_table (info);
07938
07939
07940 stub_entry->stub_offset = stub_entry->stub_sec->size;
07941 loc = stub_entry->stub_sec->contents + stub_entry->stub_offset;
07942
07943 htab->stub_count[stub_entry->stub_type - 1] += 1;
07944 switch (stub_entry->stub_type)
07945 {
07946 case ppc_stub_long_branch:
07947 case ppc_stub_long_branch_r2off:
07948
07949 off = dest = (stub_entry->target_value
07950 + stub_entry->target_section->output_offset
07951 + stub_entry->target_section->output_section->vma);
07952
07953
07954 off -= (stub_entry->stub_offset
07955 + stub_entry->stub_sec->output_offset
07956 + stub_entry->stub_sec->output_section->vma);
07957
07958 if (stub_entry->stub_type != ppc_stub_long_branch_r2off)
07959 size = 4;
07960 else
07961 {
07962 bfd_vma r2off;
07963
07964 r2off = (htab->stub_group[stub_entry->target_section->id].toc_off
07965 - htab->stub_group[stub_entry->id_sec->id].toc_off);
07966 bfd_put_32 (htab->stub_bfd, STD_R2_40R1, loc);
07967 loc += 4;
07968 bfd_put_32 (htab->stub_bfd, ADDIS_R2_R2 | PPC_HA (r2off), loc);
07969 loc += 4;
07970 bfd_put_32 (htab->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
07971 loc += 4;
07972 off -= 12;
07973 size = 16;
07974 }
07975 bfd_put_32 (htab->stub_bfd, B_DOT | (off & 0x3fffffc), loc);
07976
07977 BFD_ASSERT (off + (1 << 25) < (bfd_vma) (1 << 26));
07978
07979 if (info->emitrelocations)
07980 {
07981 Elf_Internal_Rela *relocs, *r;
07982 struct bfd_elf_section_data *elfsec_data;
07983
07984 elfsec_data = elf_section_data (stub_entry->stub_sec);
07985 relocs = elfsec_data->relocs;
07986 if (relocs == NULL)
07987 {
07988 bfd_size_type relsize;
07989 relsize = stub_entry->stub_sec->reloc_count * sizeof (*relocs);
07990 relocs = bfd_alloc (htab->stub_bfd, relsize);
07991 if (relocs == NULL)
07992 return FALSE;
07993 elfsec_data->relocs = relocs;
07994 elfsec_data->rel_hdr.sh_size = relsize;
07995 elfsec_data->rel_hdr.sh_entsize = 24;
07996 stub_entry->stub_sec->reloc_count = 0;
07997 }
07998 r = relocs + stub_entry->stub_sec->reloc_count;
07999 stub_entry->stub_sec->reloc_count += 1;
08000 r->r_offset = loc - stub_entry->stub_sec->contents;
08001 r->r_info = ELF64_R_INFO (0, R_PPC64_REL24);
08002 r->r_addend = dest;
08003 if (stub_entry->h != NULL)
08004 {
08005 struct elf_link_hash_entry **hashes;
08006 unsigned long symndx;
08007 struct ppc_link_hash_entry *h;
08008
08009 hashes = elf_sym_hashes (htab->stub_bfd);
08010 if (hashes == NULL)
08011 {
08012 bfd_size_type hsize;
08013
08014 hsize = (htab->stub_globals + 1) * sizeof (*hashes);
08015 hashes = bfd_zalloc (htab->stub_bfd, hsize);
08016 if (hashes == NULL)
08017 return FALSE;
08018 elf_sym_hashes (htab->stub_bfd) = hashes;
08019 htab->stub_globals = 1;
08020 }
08021 symndx = htab->stub_globals++;
08022 h = stub_entry->h;
08023 hashes[symndx] = &h->elf;
08024 r->r_info = ELF64_R_INFO (symndx, R_PPC64_REL24);
08025 if (h->oh != NULL && h->oh->is_func)
08026 h = h->oh;
08027 if (h->elf.root.u.def.section != stub_entry->target_section)
08028
08029 r->r_addend = 0;
08030 else
08031 {
08032 off = (h->elf.root.u.def.value
08033 + h->elf.root.u.def.section->output_offset
08034 + h->elf.root.u.def.section->output_section->vma);
08035 r->r_addend -= off;
08036 }
08037 }
08038 }
08039 break;
08040
08041 case ppc_stub_plt_branch:
08042 case ppc_stub_plt_branch_r2off:
08043 br_entry = ppc_branch_hash_lookup (&htab->branch_hash_table,
08044 stub_entry->root.string + 9,
08045 FALSE, FALSE);
08046 if (br_entry == NULL)
08047 {
08048 (*_bfd_error_handler) (_("can't find branch stub `%s'"),
08049 stub_entry->root.string + 9);
08050 htab->stub_error = TRUE;
08051 return FALSE;
08052 }
08053
08054 off = (stub_entry->target_value
08055 + stub_entry->target_section->output_offset
08056 + stub_entry->target_section->output_section->vma);
08057
08058 bfd_put_64 (htab->brlt->owner, off,
08059 htab->brlt->contents + br_entry->offset);
08060
08061 if (htab->relbrlt != NULL)
08062 {
08063
08064 Elf_Internal_Rela rela;
08065 bfd_byte *rl;
08066
08067 rela.r_offset = (br_entry->offset
08068 + htab->brlt->output_offset
08069 + htab->brlt->output_section->vma);
08070 rela.r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
08071 rela.r_addend = off;
08072
08073 rl = htab->relbrlt->contents;
08074 rl += htab->relbrlt->reloc_count++ * sizeof (Elf64_External_Rela);
08075 bfd_elf64_swap_reloca_out (htab->relbrlt->owner, &rela, rl);
08076 }
08077
08078 off = (br_entry->offset
08079 + htab->brlt->output_offset
08080 + htab->brlt->output_section->vma
08081 - elf_gp (htab->brlt->output_section->owner)
08082 - htab->stub_group[stub_entry->id_sec->id].toc_off);
08083
08084 if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
08085 {
08086 (*_bfd_error_handler)
08087 (_("linkage table error against `%s'"),
08088 stub_entry->root.string);
08089 bfd_set_error (bfd_error_bad_value);
08090 htab->stub_error = TRUE;
08091 return FALSE;
08092 }
08093
08094 indx = off;
08095 if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
08096 {
08097 bfd_put_32 (htab->stub_bfd, ADDIS_R12_R2 | PPC_HA (indx), loc);
08098 loc += 4;
08099 bfd_put_32 (htab->stub_bfd, LD_R11_0R12 | PPC_LO (indx), loc);
08100 size = 16;
08101 }
08102 else
08103 {
08104 bfd_vma r2off;
08105
08106 r2off = (htab->stub_group[stub_entry->target_section->id].toc_off
08107 - htab->stub_group[stub_entry->id_sec->id].toc_off);
08108 bfd_put_32 (htab->stub_bfd, STD_R2_40R1, loc);
08109 loc += 4;
08110 bfd_put_32 (htab->stub_bfd, ADDIS_R12_R2 | PPC_HA (indx), loc);
08111 loc += 4;
08112 bfd_put_32 (htab->stub_bfd, LD_R11_0R12 | PPC_LO (indx), loc);
08113 loc += 4;
08114 bfd_put_32 (htab->stub_bfd, ADDIS_R2_R2 | PPC_HA (r2off), loc);
08115 loc += 4;
08116 bfd_put_32 (htab->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
08117 size = 28;
08118 }
08119 loc += 4;
08120 bfd_put_32 (htab->stub_bfd, MTCTR_R11, loc);
08121 loc += 4;
08122 bfd_put_32 (htab->stub_bfd, BCTR, loc);
08123 break;
08124
08125 case ppc_stub_plt_call:
08126
08127
08128
08129 if (stub_entry->h->oh != NULL
08130 && stub_entry->h->oh->elf.root.type != bfd_link_hash_defined
08131 && stub_entry->h->oh->elf.root.type != bfd_link_hash_defweak)
08132 {
08133
08134
08135
08136
08137
08138 stub_entry->h->oh->elf.root.type = bfd_link_hash_defined;
08139 stub_entry->h->oh->elf.root.u.def.section = stub_entry->stub_sec;
08140 stub_entry->h->oh->elf.root.u.def.value = stub_entry->stub_offset;
08141 }
08142
08143
08144 off = (bfd_vma) -1;
08145 for (ent = stub_entry->h->elf.plt.plist; ent != NULL; ent = ent->next)
08146 if (ent->addend == stub_entry->addend)
08147 {
08148 off = ent->plt.offset;
08149 break;
08150 }
08151 if (off >= (bfd_vma) -2)
08152 abort ();
08153
08154 off &= ~ (bfd_vma) 1;
08155 off += (htab->plt->output_offset
08156 + htab->plt->output_section->vma
08157 - elf_gp (htab->plt->output_section->owner)
08158 - htab->stub_group[stub_entry->id_sec->id].toc_off);
08159
08160 if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
08161 {
08162 (*_bfd_error_handler)
08163 (_("linkage table error against `%s'"),
08164 stub_entry->h->elf.root.root.string);
08165 bfd_set_error (bfd_error_bad_value);
08166 htab->stub_error = TRUE;
08167 return FALSE;
08168 }
08169
08170 p = build_plt_stub (htab->stub_bfd, loc, off);
08171 size = p - loc;
08172 break;
08173
08174 default:
08175 BFD_FAIL ();
08176 return FALSE;
08177 }
08178
08179 stub_entry->stub_sec->size += size;
08180
08181 if (htab->emit_stub_syms)
08182 {
08183 struct elf_link_hash_entry *h;
08184 size_t len1, len2;
08185 char *name;
08186 const char *const stub_str[] = { "long_branch",
08187 "long_branch_r2off",
08188 "plt_branch",
08189 "plt_branch_r2off",
08190 "plt_call" };
08191
08192 len1 = strlen (stub_str[stub_entry->stub_type - 1]);
08193 len2 = strlen (stub_entry->root.string);
08194 name = bfd_malloc (len1 + len2 + 2);
08195 if (name == NULL)
08196 return FALSE;
08197 memcpy (name, stub_entry->root.string, 9);
08198 memcpy (name + 9, stub_str[stub_entry->stub_type - 1], len1);
08199 memcpy (name + len1 + 9, stub_entry->root.string + 8, len2 - 8 + 1);
08200 h = elf_link_hash_lookup (&htab->elf, name, TRUE, FALSE, FALSE);
08201 if (h == NULL)
08202 return FALSE;
08203 if (h->root.type == bfd_link_hash_new)
08204 {
08205 h->root.type = bfd_link_hash_defined;
08206 h->root.u.def.section = stub_entry->stub_sec;
08207 h->root.u.def.value = stub_entry->stub_offset;
08208 h->ref_regular = 1;
08209 h->def_regular = 1;
08210 h->ref_regular_nonweak = 1;
08211 h->forced_local = 1;
08212 h->non_elf = 0;
08213 }
08214 }
08215
08216 return TRUE;
08217 }
08218
08219
08220
08221
08222
08223 static bfd_boolean
08224 ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
08225 {
08226 struct ppc_stub_hash_entry *stub_entry;
08227 struct bfd_link_info *info;
08228 struct ppc_link_hash_table *htab;
08229 bfd_vma off;
08230 int size;
08231
08232
08233 stub_entry = (struct ppc_stub_hash_entry *) gen_entry;
08234 info = in_arg;
08235
08236 htab = ppc_hash_table (info);
08237
08238 if (stub_entry->stub_type == ppc_stub_plt_call)
08239 {
08240 struct plt_entry *ent;
08241 off = (bfd_vma) -1;
08242 for (ent = stub_entry->h->elf.plt.plist; ent != NULL; ent = ent->next)
08243 if (ent->addend == stub_entry->addend)
08244 {
08245 off = ent->plt.offset & ~(bfd_vma) 1;
08246 break;
08247 }
08248 if (off >= (bfd_vma) -2)
08249 abort ();
08250 off += (htab->plt->output_offset
08251 + htab->plt->output_section->vma
08252 - elf_gp (htab->plt->output_section->owner)
08253 - htab->stub_group[stub_entry->id_sec->id].toc_off);
08254
08255 size = PLT_CALL_STUB_SIZE;
08256 if (PPC_HA (off + 16) != PPC_HA (off))
08257 size += 4;
08258 }
08259 else
08260 {
08261
08262
08263 off = (stub_entry->target_value
08264 + stub_entry->target_section->output_offset
08265 + stub_entry->target_section->output_section->vma);
08266 off -= (stub_entry->stub_sec->size
08267 + stub_entry->stub_sec->output_offset
08268 + stub_entry->stub_sec->output_section->vma);
08269
08270
08271
08272 if (stub_entry->stub_type >= ppc_stub_plt_branch)
08273 stub_entry->stub_type += ppc_stub_long_branch - ppc_stub_plt_branch;
08274
08275 size = 4;
08276 if (stub_entry->stub_type == ppc_stub_long_branch_r2off)
08277 {
08278 off -= 12;
08279 size = 16;
08280 }
08281
08282
08283 if (off + (1 << 25) >= (bfd_vma) (1 << 26))
08284 {
08285 struct ppc_branch_hash_entry *br_entry;
08286
08287 br_entry = ppc_branch_hash_lookup (&htab->branch_hash_table,
08288 stub_entry->root.string + 9,
08289 TRUE, FALSE);
08290 if (br_entry == NULL)
08291 {
08292 (*_bfd_error_handler) (_("can't build branch stub `%s'"),
08293 stub_entry->root.string + 9);
08294 htab->stub_error = TRUE;
08295 return FALSE;
08296 }
08297
08298 if (br_entry->iter != htab->stub_iteration)
08299 {
08300 br_entry->iter = htab->stub_iteration;
08301 br_entry->offset = htab->brlt->size;
08302 htab->brlt->size += 8;
08303
08304 if (htab->relbrlt != NULL)
08305 htab->relbrlt->size += sizeof (Elf64_External_Rela);
08306 }
08307
08308 stub_entry->stub_type += ppc_stub_plt_branch - ppc_stub_long_branch;
08309 size = 16;
08310 if (stub_entry->stub_type != ppc_stub_plt_branch)
08311 size = 28;
08312 }
08313
08314 if (info->emitrelocations
08315 && (stub_entry->stub_type == ppc_stub_long_branch
08316 || stub_entry->stub_type == ppc_stub_long_branch_r2off))
08317 stub_entry->stub_sec->reloc_count += 1;
08318 }
08319
08320 stub_entry->stub_sec->size += size;
08321 return TRUE;
08322 }
08323
08324
08325
08326
08327
08328 int
08329 ppc64_elf_setup_section_lists (bfd *output_bfd,
08330 struct bfd_link_info *info,
08331 int no_multi_toc)
08332 {
08333 bfd *input_bfd;
08334 int top_id, top_index, id;
08335 asection *section;
08336 asection **input_list;
08337 bfd_size_type amt;
08338 struct ppc_link_hash_table *htab = ppc_hash_table (info);
08339
08340 htab->no_multi_toc = no_multi_toc;
08341
08342 if (htab->brlt == NULL)
08343 return 0;
08344
08345
08346 for (input_bfd = info->input_bfds, top_id = 3;
08347 input_bfd != NULL;
08348 input_bfd = input_bfd->link_next)
08349 {
08350 for (section = input_bfd->sections;
08351 section != NULL;
08352 section = section->next)
08353 {
08354 if (top_id < section->id)
08355 top_id = section->id;
08356 }
08357 }
08358
08359 htab->top_id = top_id;
08360 amt = sizeof (struct map_stub) * (top_id + 1);
08361 htab->stub_group = bfd_zmalloc (amt);
08362 if (htab->stub_group == NULL)
08363 return -1;
08364
08365
08366 for (id = 0; id < 3; id++)
08367 htab->stub_group[id].toc_off = TOC_BASE_OFF;
08368
08369 elf_gp (output_bfd) = htab->toc_curr = ppc64_elf_toc (output_bfd);
08370
08371
08372
08373
08374 for (section = output_bfd->sections, top_index = 0;
08375 section != NULL;
08376 section = section->next)
08377 {
08378 if (top_index < section->index)
08379 top_index = section->index;
08380 }
08381
08382 htab->top_index = top_index;
08383 amt = sizeof (asection *) * (top_index + 1);
08384 input_list = bfd_zmalloc (amt);
08385 htab->input_list = input_list;
08386 if (input_list == NULL)
08387 return -1;
08388
08389 return 1;
08390 }
08391
08392
08393
08394
08395
08396
08397 void
08398 ppc64_elf_next_toc_section (struct bfd_link_info *info, asection *isec)
08399 {
08400 struct ppc_link_hash_table *htab = ppc_hash_table (info);
08401
08402 if (!htab->no_multi_toc)
08403 {
08404 bfd_vma addr = isec->output_offset + isec->output_section->vma;
08405 bfd_vma off = addr - htab->toc_curr;
08406
08407 if (off + isec->size > 0x10000)
08408 htab->toc_curr = addr;
08409
08410 elf_gp (isec->owner) = (htab->toc_curr
08411 - elf_gp (isec->output_section->owner)
08412 + TOC_BASE_OFF);
08413 }
08414 }
08415
08416
08417
08418 void
08419 ppc64_elf_reinit_toc (bfd *output_bfd, struct bfd_link_info *info)
08420 {
08421 struct ppc_link_hash_table *htab = ppc_hash_table (info);
08422
08423 htab->multi_toc_needed = htab->toc_curr != elf_gp (output_bfd);
08424
08425
08426
08427 htab->toc_curr = TOC_BASE_OFF;
08428 }
08429
08430
08431
08432
08433
08434
08435
08436
08437
08438 static int
08439 toc_adjusting_stub_needed (struct bfd_link_info *info, asection *isec)
08440 {
08441 Elf_Internal_Rela *relstart, *rel;
08442 Elf_Internal_Sym *local_syms;
08443 int ret;
08444 struct ppc_link_hash_table *htab;
08445
08446
08447 if ((isec->flags & SEC_LINKER_CREATED) != 0)
08448 return 0;
08449
08450 if (isec->size == 0)
08451 return 0;
08452
08453 if (isec->output_section == NULL)
08454 return 0;
08455
08456
08457
08458 if (strcmp (isec->name, ".fixup") == 0)
08459 return 0;
08460
08461 if (isec->reloc_count == 0)
08462 return 0;
08463
08464 relstart = _bfd_elf_link_read_relocs (isec->owner, isec, NULL, NULL,
08465 info->keep_memory);
08466 if (relstart == NULL)
08467 return -1;
08468
08469
08470 local_syms = NULL;
08471 ret = 0;
08472 htab = ppc_hash_table (info);
08473 for (rel = relstart; rel < relstart + isec->reloc_count; ++rel)
08474 {
08475 enum elf_ppc64_reloc_type r_type;
08476 unsigned long r_symndx;
08477 struct elf_link_hash_entry *h;
08478 Elf_Internal_Sym *sym;
08479 asection *sym_sec;
08480 long *opd_adjust;
08481 bfd_vma sym_value;
08482 bfd_vma dest;
08483
08484 r_type = ELF64_R_TYPE (rel->r_info);
08485 if (r_type != R_PPC64_REL24
08486 && r_type != R_PPC64_REL14
08487 && r_type != R_PPC64_REL14_BRTAKEN
08488 && r_type != R_PPC64_REL14_BRNTAKEN)
08489 continue;
08490
08491 r_symndx = ELF64_R_SYM (rel->r_info);
08492 if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms, r_symndx,
08493 isec->owner))
08494 {
08495 ret = -1;
08496 break;
08497 }
08498
08499
08500
08501
08502
08503 if (sym_sec == NULL)
08504 {
08505 struct ppc_link_hash_entry *eh = (struct ppc_link_hash_entry *) h;
08506 if (eh != NULL
08507 && eh->oh != NULL
08508 && eh->oh->elf.plt.plist != NULL)
08509 {
08510 ret = 1;
08511 break;
08512 }
08513
08514
08515 continue;
08516 }
08517
08518
08519
08520 if (sym_sec->output_section == NULL)
08521 {
08522 ret = 1;
08523 break;
08524 }
08525
08526 if (h == NULL)
08527 sym_value = sym->st_value;
08528 else
08529 {
08530 if (h->root.type != bfd_link_hash_defined
08531 && h->root.type != bfd_link_hash_defweak)
08532 abort ();
08533 sym_value = h->root.u.def.value;
08534 }
08535 sym_value += rel->r_addend;
08536
08537
08538 opd_adjust = get_opd_info (sym_sec);
08539 if (opd_adjust != NULL)
08540 {
08541 if (h == NULL)
08542 {
08543 long adjust;
08544
08545 adjust = opd_adjust[sym->st_value / 8];
08546 if (adjust == -1)
08547
08548 continue;
08549 sym_value += adjust;
08550 }
08551
08552 dest = opd_entry_value (sym_sec, sym_value, &sym_sec, NULL);
08553 if (dest == (bfd_vma) -1)
08554 continue;
08555 }
08556 else
08557 dest = (sym_value
08558 + sym_sec->output_offset
08559 + sym_sec->output_section->vma);
08560
08561
08562 if (sym_sec == isec)
08563 continue;
08564
08565
08566 if (sym_sec->has_toc_reloc
08567 || sym_sec->makes_toc_func_call)
08568 {
08569 ret = 1;
08570 break;
08571 }
08572
08573
08574
08575 else if (dest - (isec->output_offset
08576 + isec->output_section->vma
08577 + rel->r_offset) + (1 << 25) >= (2 << 25))
08578 {
08579 ret = 1;
08580 break;
08581 }
08582
08583
08584
08585
08586 else if (sym_sec->call_check_in_progress)
08587 ret = 2;
08588
08589
08590
08591 else if (sym_sec->id <= htab->top_id
08592 && htab->stub_group[sym_sec->id].toc_off == 0)
08593 {
08594 int recur;
08595
08596
08597
08598
08599 isec->call_check_in_progress = 1;
08600 recur = toc_adjusting_stub_needed (info, sym_sec);
08601 isec->call_check_in_progress = 0;
08602
08603 if (recur < 0)
08604 {
08605
08606 ret = -1;
08607 break;
08608 }
08609 else if (recur <= 1)
08610 {
08611
08612 htab->stub_group[sym_sec->id].toc_off = 1;
08613 if (recur != 0)
08614 {
08615 sym_sec->makes_toc_func_call = 1;
08616 ret = 1;
08617 break;
08618 }
08619 }
08620 else
08621 {
08622
08623 ret = 2;
08624 }
08625 }
08626 }
08627
08628 if (local_syms != NULL
08629 && (elf_tdata (isec->owner)->symtab_hdr.contents
08630 != (unsigned char *) local_syms))
08631 free (local_syms);
08632 if (elf_section_data (isec)->relocs != relstart)
08633 free (relstart);
08634
08635 return ret;
08636 }
08637
08638
08639
08640
08641
08642
08643 bfd_boolean
08644 ppc64_elf_next_input_section (struct bfd_link_info *info, asection *isec)
08645 {
08646 struct ppc_link_hash_table *htab = ppc_hash_table (info);
08647
08648 if ((isec->output_section->flags & SEC_CODE) != 0
08649 && isec->output_section->index <= htab->top_index)
08650 {
08651 asection **list = htab->input_list + isec->output_section->index;
08652
08653 #define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
08654
08655
08656 PREV_SEC (isec) = *list;
08657 *list = isec;
08658 }
08659
08660 if (htab->multi_toc_needed)
08661 {
08662
08663
08664
08665
08666 if (isec->has_toc_reloc || (isec->flags & SEC_CODE) == 0)
08667 {
08668 if (elf_gp (isec->owner) != 0)
08669 htab->toc_curr = elf_gp (isec->owner);
08670 }
08671 else if (htab->stub_group[isec->id].toc_off == 0)
08672 {
08673 int ret = toc_adjusting_stub_needed (info, isec);
08674 if (ret < 0)
08675 return FALSE;
08676 else
08677 isec->makes_toc_func_call = ret & 1;
08678 }
08679 }
08680
08681
08682
08683
08684 htab->stub_group[isec->id].toc_off = htab->toc_curr;
08685 return TRUE;
08686 }
08687
08688
08689
08690
08691
08692
08693
08694
08695 static void
08696 group_sections (struct ppc_link_hash_table *htab,
08697 bfd_size_type stub_group_size,
08698 bfd_boolean stubs_always_before_branch)
08699 {
08700 asection **list = htab->input_list + htab->top_index;
08701 do
08702 {
08703 asection *tail = *list;
08704 while (tail != NULL)
08705 {
08706 asection *curr;
08707 asection *prev;
08708 bfd_size_type total;
08709 bfd_boolean big_sec;
08710 bfd_vma curr_toc;
08711
08712 curr = tail;
08713 total = tail->size;
08714 big_sec = total >= stub_group_size;
08715 curr_toc = htab->stub_group[tail->id].toc_off;
08716
08717 while ((prev = PREV_SEC (curr)) != NULL
08718 && ((total += curr->output_offset - prev->output_offset)
08719 < stub_group_size)
08720 && htab->stub_group[prev->id].toc_off == curr_toc)
08721 curr = prev;
08722
08723
08724
08725
08726
08727
08728
08729
08730
08731
08732
08733 do
08734 {
08735 prev = PREV_SEC (tail);
08736
08737 htab->stub_group[tail->id].link_sec = curr;
08738 }
08739 while (tail != curr && (tail = prev) != NULL);
08740
08741
08742
08743
08744
08745
08746 if (!stubs_always_before_branch && !big_sec)
08747 {
08748 total = 0;
08749 while (prev != NULL
08750 && ((total += tail->output_offset - prev->output_offset)
08751 < stub_group_size)
08752 && htab->stub_group[prev->id].toc_off == curr_toc)
08753 {
08754 tail = prev;
08755 prev = PREV_SEC (tail);
08756 htab->stub_group[tail->id].link_sec = curr;
08757 }
08758 }
08759 tail = prev;
08760 }
08761 }
08762 while (list-- != htab->input_list);
08763 free (htab->input_list);
08764 #undef PREV_SEC
08765 }
08766
08767
08768
08769
08770
08771
08772
08773 bfd_boolean
08774 ppc64_elf_size_stubs (bfd *output_bfd,
08775 struct bfd_link_info *info,
08776 bfd_signed_vma group_size,
08777 asection *(*add_stub_section) (const char *, asection *),
08778 void (*layout_sections_again) (void))
08779 {
08780 bfd_size_type stub_group_size;
08781 bfd_boolean stubs_always_before_branch;
08782 struct ppc_link_hash_table *htab = ppc_hash_table (info);
08783
08784
08785 htab->add_stub_section = add_stub_section;
08786 htab->layout_sections_again = layout_sections_again;
08787 stubs_always_before_branch = group_size < 0;
08788 if (group_size < 0)
08789 stub_group_size = -group_size;
08790 else
08791 stub_group_size = group_size;
08792 if (stub_group_size == 1)
08793 {
08794
08795 if (stubs_always_before_branch)
08796 {
08797 stub_group_size = 0x1e00000;
08798 if (htab->has_14bit_branch)
08799 stub_group_size = 0x7800;
08800 }
08801 else
08802 {
08803 stub_group_size = 0x1c00000;
08804 if (htab->has_14bit_branch)
08805 stub_group_size = 0x7000;
08806 }
08807 }
08808
08809 group_sections (htab, stub_group_size, stubs_always_before_branch);
08810
08811 while (1)
08812 {
08813 bfd *input_bfd;
08814 unsigned int bfd_indx;
08815 asection *stub_sec;
08816 bfd_boolean stub_changed;
08817
08818 htab->stub_iteration += 1;
08819 stub_changed = FALSE;
08820
08821 for (input_bfd = info->input_bfds, bfd_indx = 0;
08822 input_bfd != NULL;
08823 input_bfd = input_bfd->link_next, bfd_indx++)
08824 {
08825 Elf_Internal_Shdr *symtab_hdr;
08826 asection *section;
08827 Elf_Internal_Sym *local_syms = NULL;
08828
08829
08830 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
08831 if (symtab_hdr->sh_info == 0)
08832 continue;
08833
08834
08835 for (section = input_bfd->sections;
08836 section != NULL;
08837 section = section->next)
08838 {
08839 Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
08840
08841
08842
08843 if ((section->flags & SEC_RELOC) == 0
08844 || section->reloc_count == 0)
08845 continue;
08846
08847
08848
08849 if (section->output_section == NULL
08850 || section->output_section->owner != output_bfd)
08851 continue;
08852
08853
08854 internal_relocs
08855 = _bfd_elf_link_read_relocs (input_bfd, section, NULL, NULL,
08856 info->keep_memory);
08857 if (internal_relocs == NULL)
08858 goto error_ret_free_local;
08859
08860
08861 irela = internal_relocs;
08862 irelaend = irela + section->reloc_count;
08863 for (; irela < irelaend; irela++)
08864 {
08865 enum elf_ppc64_reloc_type r_type;
08866 unsigned int r_indx;
08867 enum ppc_stub_type stub_type;
08868 struct ppc_stub_hash_entry *stub_entry;
08869 asection *sym_sec, *code_sec;
08870 bfd_vma sym_value;
08871 bfd_vma destination;
08872 bfd_boolean ok_dest;
08873 struct ppc_link_hash_entry *hash;
08874 struct ppc_link_hash_entry *fdh;
08875 struct elf_link_hash_entry *h;
08876 Elf_Internal_Sym *sym;
08877 char *stub_name;
08878 const asection *id_sec;
08879 long *opd_adjust;
08880
08881 r_type = ELF64_R_TYPE (irela->r_info);
08882 r_indx = ELF64_R_SYM (irela->r_info);
08883
08884 if (r_type >= R_PPC64_max)
08885 {
08886 bfd_set_error (bfd_error_bad_value);
08887 goto error_ret_free_internal;
08888 }
08889
08890
08891 if (r_type != R_PPC64_REL24
08892 && r_type != R_PPC64_REL14
08893 && r_type != R_PPC64_REL14_BRTAKEN
08894 && r_type != R_PPC64_REL14_BRNTAKEN)
08895 continue;
08896
08897
08898
08899 if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
08900 r_indx, input_bfd))
08901 goto error_ret_free_internal;
08902 hash = (struct ppc_link_hash_entry *) h;
08903
08904 ok_dest = FALSE;
08905 fdh = NULL;
08906 if (hash == NULL)
08907 {
08908 sym_value = sym->st_value;
08909 ok_dest = TRUE;
08910 }
08911 else
08912 {
08913 sym_value = 0;
08914
08915
08916 if (hash->elf.root.root.string[0] == '.'
08917 && (fdh = get_fdh (hash, htab)) != NULL)
08918 {
08919 if (fdh->elf.root.type == bfd_link_hash_defined
08920 || fdh->elf.root.type == bfd_link_hash_defweak)
08921 {
08922 sym_sec = fdh->elf.root.u.def.section;
08923 sym_value = fdh->elf.root.u.def.value;
08924 if (sym_sec->output_section != NULL)
08925 ok_dest = TRUE;
08926 }
08927 else
08928 fdh = NULL;
08929 }
08930 else if (hash->elf.root.type == bfd_link_hash_defined
08931 || hash->elf.root.type == bfd_link_hash_defweak)
08932 {
08933 sym_value = hash->elf.root.u.def.value;
08934 if (sym_sec->output_section != NULL)
08935 ok_dest = TRUE;
08936 }
08937 else if (hash->elf.root.type == bfd_link_hash_undefweak)
08938 ;
08939 else if (hash->elf.root.type == bfd_link_hash_undefined)
08940 ;
08941 else
08942 {
08943 bfd_set_error (bfd_error_bad_value);
08944 goto error_ret_free_internal;
08945 }
08946 }
08947
08948 destination = 0;
08949 if (ok_dest)
08950 {
08951 sym_value += irela->r_addend;
08952 destination = (sym_value
08953 + sym_sec->output_offset
08954 + sym_sec->output_section->vma);
08955 }
08956
08957 code_sec = sym_sec;
08958 opd_adjust = get_opd_info (sym_sec);
08959 if (opd_adjust != NULL)
08960 {
08961 bfd_vma dest;
08962
08963 if (hash == NULL)
08964 {
08965 long adjust = opd_adjust[sym_value / 8];
08966 if (adjust == -1)
08967 continue;
08968 sym_value += adjust;
08969 }
08970 dest = opd_entry_value (sym_sec, sym_value,
08971 &code_sec, &sym_value);
08972 if (dest != (bfd_vma) -1)
08973 {
08974 destination = dest;
08975 if (fdh != NULL)
08976 {
08977
08978
08979 hash->elf.root.type = bfd_link_hash_defweak;
08980 hash->elf.root.u.def.section = code_sec;
08981 hash->elf.root.u.def.value = sym_value;
08982 }
08983 }
08984 }
08985
08986
08987 stub_type = ppc_type_of_stub (section, irela, &hash,
08988 destination);
08989
08990 if (stub_type != ppc_stub_plt_call)
08991 {
08992
08993
08994
08995
08996
08997
08998 if (code_sec != NULL
08999 && code_sec->output_section != NULL
09000 && (htab->stub_group[code_sec->id].toc_off
09001 != htab->stub_group[section->id].toc_off)
09002 && (code_sec->has_toc_reloc
09003 || code_sec->makes_toc_func_call))
09004 stub_type = ppc_stub_long_branch_r2off;
09005 }
09006
09007 if (stub_type == ppc_stub_none)
09008 continue;
09009
09010
09011 if (stub_type != ppc_stub_plt_call
09012 && hash != NULL
09013 && (hash == htab->tls_get_addr
09014 || hash == htab->tls_get_addr_fd)
09015 && section->has_tls_reloc
09016 && irela != internal_relocs)
09017 {
09018
09019 char *tls_mask;
09020
09021 if (!get_tls_mask (&tls_mask, NULL, &local_syms,
09022 irela - 1, input_bfd))
09023 goto error_ret_free_internal;
09024 if (*tls_mask != 0)
09025 continue;
09026 }
09027
09028
09029 id_sec = htab->stub_group[section->id].link_sec;
09030
09031
09032 stub_name = ppc_stub_name (id_sec, sym_sec, hash, irela);
09033 if (!stub_name)
09034 goto error_ret_free_internal;
09035
09036 stub_entry = ppc_stub_hash_lookup (&htab->stub_hash_table,
09037 stub_name, FALSE, FALSE);
09038 if (stub_entry != NULL)
09039 {
09040
09041 free (stub_name);
09042 continue;
09043 }
09044
09045 stub_entry = ppc_add_stub (stub_name, section, htab);
09046 if (stub_entry == NULL)
09047 {
09048 free (stub_name);
09049 error_ret_free_internal:
09050 if (elf_section_data (section)->relocs == NULL)
09051 free (internal_relocs);
09052 error_ret_free_local:
09053 if (local_syms != NULL
09054 && (symtab_hdr->contents
09055 != (unsigned char *) local_syms))
09056 free (local_syms);
09057 return FALSE;
09058 }
09059
09060 stub_entry->stub_type = stub_type;
09061 stub_entry->target_value = sym_value;
09062 stub_entry->target_section = code_sec;
09063 stub_entry->h = hash;
09064 stub_entry->addend = irela->r_addend;
09065
09066 if (stub_entry->h != NULL)
09067 htab->stub_globals += 1;
09068
09069 stub_changed = TRUE;
09070 }
09071
09072
09073 if (elf_section_data (section)->relocs != internal_relocs)
09074 free (internal_relocs);
09075 }
09076
09077 if (local_syms != NULL
09078 && symtab_hdr->contents != (unsigned char *) local_syms)
09079 {
09080 if (!info->keep_memory)
09081 free (local_syms);
09082 else
09083 symtab_hdr->contents = (unsigned char *) local_syms;
09084 }
09085 }
09086
09087 if (!stub_changed)
09088 break;
09089
09090
09091
09092 for (stub_sec = htab->stub_bfd->sections;
09093 stub_sec != NULL;
09094 stub_sec = stub_sec->next)
09095 if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
09096 {
09097 stub_sec->size = 0;
09098 stub_sec->reloc_count = 0;
09099 }
09100
09101 htab->brlt->size = 0;
09102 if (htab->relbrlt != NULL)
09103 htab->relbrlt->size = 0;
09104
09105 bfd_hash_traverse (&htab->stub_hash_table, ppc_size_one_stub, info);
09106
09107
09108 (*htab->layout_sections_again) ();
09109 }
09110
09111
09112
09113
09114
09115
09116 return TRUE;
09117 }
09118
09119
09120
09121
09122 bfd_vma
09123 ppc64_elf_toc (bfd *obfd)
09124 {
09125 asection *s;
09126 bfd_vma TOCstart;
09127
09128
09129
09130 s = bfd_get_section_by_name (obfd, ".got");
09131 if (s == NULL)
09132 s = bfd_get_section_by_name (obfd, ".toc");
09133 if (s == NULL)
09134 s = bfd_get_section_by_name (obfd, ".tocbss");
09135 if (s == NULL)
09136 s = bfd_get_section_by_name (obfd, ".plt");
09137 if (s == NULL)
09138 {
09139
09140
09141
09142
09143
09144
09145
09146
09147
09148
09149 for (s = obfd->sections; s != NULL; s = s->next)
09150 if ((s->flags & (SEC_ALLOC | SEC_SMALL_DATA | SEC_READONLY))
09151 == (SEC_ALLOC | SEC_SMALL_DATA))
09152 break;
09153 if (s == NULL)
09154 for (s = obfd->sections; s != NULL; s = s->next)
09155 if ((s->flags & (SEC_ALLOC | SEC_SMALL_DATA))
09156 == (SEC_ALLOC | SEC_SMALL_DATA))
09157 break;
09158 if (s == NULL)
09159 for (s = obfd->sections; s != NULL; s = s->next)
09160 if ((s->flags & (SEC_ALLOC | SEC_READONLY)) == SEC_ALLOC)
09161 break;
09162 if (s == NULL)
09163 for (s = obfd->sections; s != NULL; s = s->next)
09164 if ((s->flags & SEC_ALLOC) == SEC_ALLOC)
09165 break;
09166 }
09167
09168 TOCstart = 0;
09169 if (s != NULL)
09170 TOCstart = s->output_section->vma + s->output_offset;
09171
09172 return TOCstart;
09173 }
09174
09175
09176
09177
09178
09179 bfd_boolean
09180 ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
09181 struct bfd_link_info *info,
09182 char **stats)
09183 {
09184 struct ppc_link_hash_table *htab = ppc_hash_table (info);
09185 asection *stub_sec;
09186 bfd_byte *p;
09187 int stub_sec_count = 0;
09188
09189 htab->emit_stub_syms = emit_stub_syms;
09190
09191
09192 for (stub_sec = htab->stub_bfd->sections;
09193 stub_sec != NULL;
09194 stub_sec = stub_sec->next)
09195 if ((stub_sec->flags & SEC_LINKER_CREATED) == 0
09196 && stub_sec->size != 0)
09197 {
09198 stub_sec->contents = bfd_zalloc (htab->stub_bfd, stub_sec->size);
09199 if (stub_sec->contents == NULL)
09200 return FALSE;
09201
09202
09203 stub_sec->rawsize = stub_sec->size;
09204 stub_sec->size = 0;
09205 }
09206
09207 if (htab->plt != NULL)
09208 {
09209 unsigned int indx;
09210 bfd_vma plt0;
09211
09212
09213 plt0 = (htab->plt->output_section->vma
09214 + htab->plt->output_offset
09215 - (htab->glink->output_section->vma
09216 + htab->glink->output_offset
09217 + GLINK_CALL_STUB_SIZE));
09218 if (plt0 + 0x80008000 > 0xffffffff)
09219 {
09220 (*_bfd_error_handler) (_(".glink and .plt too far apart"));
09221 bfd_set_error (bfd_error_bad_value);
09222 return FALSE;
09223 }
09224
09225 if (htab->emit_stub_syms)
09226 {
09227 struct elf_link_hash_entry *h;
09228 h = elf_link_hash_lookup (&htab->elf, "__glink", TRUE, FALSE, FALSE);
09229 if (h == NULL)
09230 return FALSE;
09231 if (h->root.type == bfd_link_hash_new)
09232 {
09233 h->root.type = bfd_link_hash_defined;
09234 h->root.u.def.section = htab->glink;
09235 h->root.u.def.value = 0;
09236 h->ref_regular = 1;
09237 h->def_regular = 1;
09238 h->ref_regular_nonweak = 1;
09239 h->forced_local = 1;
09240 h->non_elf = 0;
09241 }
09242 }
09243 p = htab->glink->contents;
09244 bfd_put_32 (htab->glink->owner, MFCTR_R12, p);
09245 p += 4;
09246 bfd_put_32 (htab->glink->owner, SLDI_R11_R0_3, p);
09247 p += 4;
09248 bfd_put_32 (htab->glink->owner, ADDIC_R2_R0_32K, p);
09249 p += 4;
09250 bfd_put_32 (htab->glink->owner, SUB_R12_R12_R11, p);
09251 p += 4;
09252 bfd_put_32 (htab->glink->owner, SRADI_R2_R2_63, p);
09253 p += 4;
09254 bfd_put_32 (htab->glink->owner, SLDI_R11_R0_2, p);
09255 p += 4;
09256 bfd_put_32 (htab->glink->owner, AND_R2_R2_R11, p);
09257 p += 4;
09258 bfd_put_32 (htab->glink->owner, SUB_R12_R12_R11, p);
09259 p += 4;
09260 bfd_put_32 (htab->glink->owner, ADD_R12_R12_R2, p);
09261 p += 4;
09262 bfd_put_32 (htab->glink->owner, ADDIS_R12_R12 | PPC_HA (plt0), p);
09263 p += 4;
09264 bfd_put_32 (htab->glink->owner, LD_R11_0R12 | PPC_LO (plt0), p);
09265 p += 4;
09266 bfd_put_32 (htab->glink->owner, ADDI_R12_R12 | PPC_LO (plt0), p);
09267 p += 4;
09268 bfd_put_32 (htab->glink->owner, LD_R2_0R12 | 8, p);
09269 p += 4;
09270 bfd_put_32 (htab->glink->owner, MTCTR_R11, p);
09271 p += 4;
09272 bfd_put_32 (htab->glink->owner, LD_R11_0R12 | 16, p);
09273 p += 4;
09274 bfd_put_32 (htab->glink->owner, BCTR, p);
09275 p += 4;
09276
09277
09278 indx = 0;
09279 while (p < htab->glink->contents + htab->glink->size)
09280 {
09281 if (indx < 0x8000)
09282 {
09283 bfd_put_32 (htab->glink->owner, LI_R0_0 | indx, p);
09284 p += 4;
09285 }
09286 else
09287 {
09288 bfd_put_32 (htab->glink->owner, LIS_R0_0 | PPC_HI (indx), p);
09289 p += 4;
09290 bfd_put_32 (htab->glink->owner, ORI_R0_R0_0 | PPC_LO (indx), p);
09291 p += 4;
09292 }
09293 bfd_put_32 (htab->glink->owner,
09294 B_DOT | ((htab->glink->contents - p) & 0x3fffffc), p);
09295 indx++;
09296 p += 4;
09297 }
09298 htab->glink->rawsize = p - htab->glink->contents;
09299 }
09300
09301 if (htab->brlt->size != 0)
09302 {
09303 htab->brlt->contents = bfd_zalloc (htab->brlt->owner,
09304 htab->brlt->size);
09305 if (htab->brlt->contents == NULL)
09306 return FALSE;
09307 }
09308 if (htab->relbrlt != NULL && htab->relbrlt->size != 0)
09309 {
09310 htab->relbrlt->contents = bfd_zalloc (htab->relbrlt->owner,
09311 htab->relbrlt->size);
09312 if (htab->relbrlt->contents == NULL)
09313 return FALSE;
09314 }
09315
09316
09317 bfd_hash_traverse (&htab->stub_hash_table, ppc_build_one_stub, info);
09318
09319 for (stub_sec = htab->stub_bfd->sections;
09320 stub_sec != NULL;
09321 stub_sec = stub_sec->next)
09322 if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
09323 {
09324 stub_sec_count += 1;
09325 if (stub_sec->rawsize != stub_sec->size)
09326 break;
09327 }
09328
09329 if (stub_sec != NULL
09330 || htab->glink->rawsize != htab->glink->size)
09331 {
09332 htab->stub_error = TRUE;
09333 (*_bfd_error_handler) (_("stubs don't match calculated size"));
09334 }
09335
09336 if (htab->stub_error)
09337 return FALSE;
09338
09339 if (stats != NULL)
09340 {
09341 *stats = bfd_malloc (500);
09342 if (*stats == NULL)
09343 return FALSE;
09344
09345 sprintf (*stats, _("linker stubs in %u group%s\n"
09346 " branch %lu\n"
09347 " toc adjust %lu\n"
09348 " long branch %lu\n"
09349 " long toc adj %lu\n"
09350 " plt call %lu"),
09351 stub_sec_count,
09352 stub_sec_count == 1 ? "" : "s",
09353 htab->stub_count[ppc_stub_long_branch - 1],
09354 htab->stub_count[ppc_stub_long_branch_r2off - 1],
09355 htab->stub_count[ppc_stub_plt_branch - 1],
09356 htab->stub_count[ppc_stub_plt_branch_r2off - 1],
09357 htab->stub_count[ppc_stub_plt_call - 1]);
09358 }
09359 return TRUE;
09360 }
09361
09362
09363
09364 static bfd_boolean
09365 undo_symbol_twiddle (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
09366 {
09367 struct ppc_link_hash_entry *eh;
09368
09369 if (h->root.type == bfd_link_hash_indirect)
09370 return TRUE;
09371
09372 if (h->root.type == bfd_link_hash_warning)
09373 h = (struct elf_link_hash_entry *) h->root.u.i.link;
09374
09375 eh = (struct ppc_link_hash_entry *) h;
09376 if (eh->elf.root.type != bfd_link_hash_undefweak || !eh->was_undefined)
09377 return TRUE;
09378
09379 eh->elf.root.type = bfd_link_hash_undefined;
09380 return TRUE;
09381 }
09382
09383 void
09384 ppc64_elf_restore_symbols (struct bfd_link_info *info)
09385 {
09386 struct ppc_link_hash_table *htab = ppc_hash_table (info);
09387 elf_link_hash_traverse (&htab->elf, undo_symbol_twiddle, info);
09388 }
09389
09390
09391
09392
09393
09394
09395
09396
09397
09398
09399
09400
09401
09402
09403
09404
09405
09406
09407
09408
09409
09410
09411
09412
09413
09414
09415
09416
09417
09418
09419 static bfd_boolean
09420 ppc64_elf_relocate_section (bfd *output_bfd,
09421 struct bfd_link_info *info,
09422 bfd *input_bfd,
09423 asection *input_section,
09424 bfd_byte *contents,
09425 Elf_Internal_Rela *relocs,
09426 Elf_Internal_Sym *local_syms,
09427 asection **local_sections)
09428 {
09429 struct ppc_link_hash_table *htab;
09430 Elf_Internal_Shdr *symtab_hdr;
09431 struct elf_link_hash_entry **sym_hashes;
09432 Elf_Internal_Rela *rel;
09433 Elf_Internal_Rela *relend;
09434 Elf_Internal_Rela outrel;
09435 bfd_byte *loc;
09436 struct got_entry **local_got_ents;
09437 bfd_vma TOCstart;
09438 bfd_boolean ret = TRUE;
09439 bfd_boolean is_opd;
09440
09441 bfd_boolean is_power4 = FALSE;
09442
09443 if (info->relocatable)
09444 return TRUE;
09445
09446
09447 if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
09448 ppc_howto_init ();
09449
09450 htab = ppc_hash_table (info);
09451
09452
09453 if (input_section->owner == htab->stub_bfd)
09454 return TRUE;
09455
09456 local_got_ents = elf_local_got_ents (input_bfd);
09457 TOCstart = elf_gp (output_bfd);
09458 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
09459 sym_hashes = elf_sym_hashes (input_bfd);
09460 is_opd = ppc64_elf_section_data (input_section)->opd.adjust != NULL;
09461
09462 rel = relocs;
09463 relend = relocs + input_section->reloc_count;
09464 for (; rel < relend; rel++)
09465 {
09466 enum elf_ppc64_reloc_type r_type;
09467 bfd_vma addend;
09468 bfd_reloc_status_type r;
09469 Elf_Internal_Sym *sym;
09470 asection *sec;
09471 struct elf_link_hash_entry *h_elf;
09472 struct ppc_link_hash_entry *h;
09473 struct ppc_link_hash_entry *fdh;
09474 const char *sym_name;
09475 unsigned long r_symndx, toc_symndx;
09476 char tls_mask, tls_gd, tls_type;
09477 char sym_type;
09478 bfd_vma relocation;
09479 bfd_boolean unresolved_reloc;
09480 bfd_boolean warned;
09481 unsigned long insn, mask;
09482 struct ppc_stub_hash_entry *stub_entry;
09483 bfd_vma max_br_offset;
09484 bfd_vma from;
09485
09486 r_type = ELF64_R_TYPE (rel->r_info);
09487 r_symndx = ELF64_R_SYM (rel->r_info);
09488
09489
09490
09491
09492 if (rel->r_info == ELF64_R_INFO (0, R_PPC64_TOC)
09493 && rel != relocs
09494 && ELF64_R_TYPE (rel[-1].r_info) == R_PPC64_ADDR64
09495 && is_opd)
09496 r_symndx = ELF64_R_SYM (rel[-1].r_info);
09497
09498 sym = NULL;
09499 sec = NULL;
09500 h_elf = NULL;
09501 sym_name = NULL;
09502 unresolved_reloc = FALSE;
09503 warned = FALSE;
09504
09505 if (r_symndx < symtab_hdr->sh_info)
09506 {
09507
09508 long *opd_adjust;
09509
09510 sym = local_syms + r_symndx;
09511 sec = local_sections[r_symndx];
09512 sym_name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym);
09513 sym_type = ELF64_ST_TYPE (sym->st_info);
09514 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
09515 opd_adjust = get_opd_info (sec);
09516 if (opd_adjust != NULL)
09517 {
09518 long adjust = opd_adjust[(sym->st_value + rel->r_addend) / 8];
09519 if (adjust == -1)
09520 relocation = 0;
09521 else
09522 relocation += adjust;
09523 }
09524 }
09525 else
09526 {
09527 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
09528 r_symndx, symtab_hdr, sym_hashes,
09529 h_elf, sec, relocation,
09530 unresolved_reloc, warned);
09531 sym_name = h_elf->root.root.string;
09532 sym_type = h_elf->type;
09533 }
09534 h = (struct ppc_link_hash_entry *) h_elf;
09535
09536
09537
09538
09539
09540 tls_mask = 0;
09541 tls_gd = 0;
09542 toc_symndx = 0;
09543 if (IS_PPC64_TLS_RELOC (r_type))
09544 {
09545 if (h != NULL)
09546 tls_mask = h->tls_mask;
09547 else if (local_got_ents != NULL)
09548 {
09549 char *lgot_masks;
09550 lgot_masks = (char *) (local_got_ents + symtab_hdr->sh_info);
09551 tls_mask = lgot_masks[r_symndx];
09552 }
09553 if (tls_mask == 0 && r_type == R_PPC64_TLS)
09554 {
09555
09556 char *toc_tls;
09557
09558 if (!get_tls_mask (&toc_tls, &toc_symndx, &local_syms,
09559 rel, input_bfd))
09560 return FALSE;
09561
09562 if (toc_tls)
09563 tls_mask = *toc_tls;
09564 }
09565 }
09566
09567
09568
09569 if (r_symndx != 0
09570 && r_type != R_PPC64_NONE
09571 && (h == NULL
09572 || h->elf.root.type == bfd_link_hash_defined
09573 || h->elf.root.type == bfd_link_hash_defweak)
09574 && IS_PPC64_TLS_RELOC (r_type) != (sym_type == STT_TLS))
09575 {
09576 if (r_type == R_PPC64_TLS && tls_mask != 0)
09577
09578 ;
09579 else
09580 (*_bfd_error_handler)
09581 (sym_type == STT_TLS
09582 ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
09583 : _("%B(%A+0x%lx): %s used with non-TLS symbol %s"),
09584 input_bfd,
09585 input_section,
09586 (long) rel->r_offset,
09587 ppc64_elf_howto_table[r_type]->name,
09588 sym_name);
09589 }
09590
09591
09592 if (R_PPC64_TOC16_LO_DS != R_PPC64_TOC16_DS + 1
09593 || R_PPC64_TOC16_LO != R_PPC64_TOC16 + 1
09594 || (R_PPC64_GOT_TLSLD16 & 3) != (R_PPC64_GOT_TLSGD16 & 3)
09595 || (R_PPC64_GOT_TLSLD16_LO & 3) != (R_PPC64_GOT_TLSGD16_LO & 3)
09596 || (R_PPC64_GOT_TLSLD16_HI & 3) != (R_PPC64_GOT_TLSGD16_HI & 3)
09597 || (R_PPC64_GOT_TLSLD16_HA & 3) != (R_PPC64_GOT_TLSGD16_HA & 3)
09598 || (R_PPC64_GOT_TLSLD16 & 3) != (R_PPC64_GOT_TPREL16_DS & 3)
09599 || (R_PPC64_GOT_TLSLD16_LO & 3) != (R_PPC64_GOT_TPREL16_LO_DS & 3)
09600 || (R_PPC64_GOT_TLSLD16_HI & 3) != (R_PPC64_GOT_TPREL16_HI & 3)
09601 || (R_PPC64_GOT_TLSLD16_HA & 3) != (R_PPC64_GOT_TPREL16_HA & 3))
09602 abort ();
09603
09604 switch (r_type)
09605 {
09606 default:
09607 break;
09608
09609 case R_PPC64_TOC16:
09610 case R_PPC64_TOC16_LO:
09611 case R_PPC64_TOC16_DS:
09612 case R_PPC64_TOC16_LO_DS:
09613 {
09614
09615 char *toc_tls;
09616 int retval;
09617
09618 retval = get_tls_mask (&toc_tls, &toc_symndx, &local_syms,
09619 rel, input_bfd);
09620 if (retval == 0)
09621 return FALSE;
09622
09623 if (toc_tls)
09624 {
09625 tls_mask = *toc_tls;
09626 if (r_type == R_PPC64_TOC16_DS
09627 || r_type == R_PPC64_TOC16_LO_DS)
09628 {
09629 if (tls_mask != 0
09630 && (tls_mask & (TLS_DTPREL | TLS_TPREL)) == 0)
09631 goto toctprel;
09632 }
09633 else
09634 {
09635
09636
09637 if (retval == 2)
09638 {
09639 tls_gd = TLS_TPRELGD;
09640 if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)
09641 goto tls_get_addr_check;
09642 }
09643 else if (retval == 3)
09644 {
09645 if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
09646 goto tls_get_addr_check;
09647 }
09648 }
09649 }
09650 }
09651 break;
09652
09653 case R_PPC64_GOT_TPREL16_DS:
09654 case R_PPC64_GOT_TPREL16_LO_DS:
09655 if (tls_mask != 0
09656 && (tls_mask & TLS_TPREL) == 0)
09657 {
09658 toctprel:
09659 insn = bfd_get_32 (output_bfd, contents + rel->r_offset - 2);
09660 insn &= 31 << 21;
09661 insn |= 0x3c0d0000;
09662 bfd_put_32 (output_bfd, insn, contents + rel->r_offset - 2);
09663 r_type = R_PPC64_TPREL16_HA;
09664 if (toc_symndx != 0)
09665 {
09666 rel->r_info = ELF64_R_INFO (toc_symndx, r_type);
09667
09668
09669 rel--;
09670 continue;
09671 }
09672 else
09673 rel->r_info = ELF64_R_INFO (r_symndx, r_type);
09674 }
09675 break;
09676
09677 case R_PPC64_TLS:
09678 if (tls_mask != 0
09679 && (tls_mask & TLS_TPREL) == 0)
09680 {
09681 bfd_vma rtra;
09682 insn = bfd_get_32 (output_bfd, contents + rel->r_offset);
09683 if ((insn & ((0x3f << 26) | (31 << 11)))
09684 == ((31 << 26) | (13 << 11)))
09685 rtra = insn & ((1 << 26) - (1 << 16));
09686 else if ((insn & ((0x3f << 26) | (31 << 16)))
09687 == ((31 << 26) | (13 << 16)))
09688 rtra = (insn & (31 << 21)) | ((insn & (31 << 11)) << 5);
09689 else
09690 abort ();
09691 if ((insn & ((1 << 11) - (1 << 1))) == 266 << 1)
09692
09693 insn = 14 << 26;
09694 else if ((insn & (31 << 1)) == 23 << 1
09695 && ((insn & (31 << 6)) < 14 << 6
09696 || ((insn & (31 << 6)) >= 16 << 6
09697 && (insn & (31 << 6)) < 24 << 6)))
09698
09699 insn = (32 | ((insn >> 6) & 31)) << 26;
09700 else if ((insn & (31 << 1)) == 21 << 1
09701 && (insn & (0x1a << 6)) == 0)
09702
09703 insn = (((58 | ((insn >> 6) & 4)) << 26)
09704 | ((insn >> 6) & 1));
09705 else if ((insn & (31 << 1)) == 21 << 1
09706 && (insn & ((1 << 11) - (1 << 1))) == 341 << 1)
09707
09708 insn = (58 << 26) | 2;
09709 else
09710 abort ();
09711 insn |= rtra;
09712 bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
09713
09714
09715 rel->r_offset += 2;
09716 r_type = R_PPC64_TPREL16_LO;
09717 if (toc_symndx != 0)
09718 {
09719 rel->r_info = ELF64_R_INFO (toc_symndx, r_type);
09720
09721
09722 rel--;
09723 continue;
09724 }
09725 else
09726 rel->r_info = ELF64_R_INFO (r_symndx, r_type);
09727 }
09728 break;
09729
09730 case R_PPC64_GOT_TLSGD16_HI:
09731 case R_PPC64_GOT_TLSGD16_HA:
09732 tls_gd = TLS_TPRELGD;
09733 if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)
09734 goto tls_gdld_hi;
09735 break;
09736
09737 case R_PPC64_GOT_TLSLD16_HI:
09738 case R_PPC64_GOT_TLSLD16_HA:
09739 if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
09740 {
09741 tls_gdld_hi:
09742 if ((tls_mask & tls_gd) != 0)
09743 r_type = (((r_type - (R_PPC64_GOT_TLSGD16 & 3)) & 3)
09744 + R_PPC64_GOT_TPREL16_DS);
09745 else
09746 {
09747 bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
09748 rel->r_offset -= 2;
09749 r_type = R_PPC64_NONE;
09750 }
09751 rel->r_info = ELF64_R_INFO (r_symndx, r_type);
09752 }
09753 break;
09754
09755 case R_PPC64_GOT_TLSGD16:
09756 case R_PPC64_GOT_TLSGD16_LO:
09757 tls_gd = TLS_TPRELGD;
09758 if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)
09759 goto tls_get_addr_check;
09760 break;
09761
09762 case R_PPC64_GOT_TLSLD16:
09763 case R_PPC64_GOT_TLSLD16_LO:
09764 if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
09765 {
09766 tls_get_addr_check:
09767 if (rel + 1 < relend)
09768 {
09769 enum elf_ppc64_reloc_type r_type2;
09770 unsigned long r_symndx2;
09771 struct elf_link_hash_entry *h2;
09772 bfd_vma insn1, insn2, insn3;
09773 bfd_vma offset;
09774
09775
09776
09777 r_type2 = ELF64_R_TYPE (rel[1].r_info);
09778 r_symndx2 = ELF64_R_SYM (rel[1].r_info);
09779 if (r_symndx2 < symtab_hdr->sh_info
09780 || (r_type2 != R_PPC64_REL14
09781 && r_type2 != R_PPC64_REL14_BRTAKEN
09782 && r_type2 != R_PPC64_REL14_BRNTAKEN
09783 && r_type2 != R_PPC64_REL24))
09784 break;
09785
09786 h2 = sym_hashes[r_symndx2 - symtab_hdr->sh_info];
09787 while (h2->root.type == bfd_link_hash_indirect
09788 || h2->root.type == bfd_link_hash_warning)
09789 h2 = (struct elf_link_hash_entry *) h2->root.u.i.link;
09790 if (h2 == NULL || (h2 != &htab->tls_get_addr->elf
09791 && h2 != &htab->tls_get_addr_fd->elf))
09792 break;
09793
09794
09795 offset = rel[1].r_offset;
09796 insn1 = bfd_get_32 (output_bfd,
09797 contents + rel->r_offset - 2);
09798 insn3 = bfd_get_32 (output_bfd,
09799 contents + offset + 4);
09800 if ((tls_mask & tls_gd) != 0)
09801 {
09802
09803 insn1 &= (1 << 26) - (1 << 2);
09804 insn1 |= 58 << 26;
09805 insn2 = 0x7c636a14;
09806 rel[1].r_info = ELF64_R_INFO (r_symndx2, R_PPC64_NONE);
09807 if ((tls_mask & TLS_EXPLICIT) == 0)
09808 r_type = (((r_type - (R_PPC64_GOT_TLSGD16 & 3)) & 3)
09809 + R_PPC64_GOT_TPREL16_DS);
09810 else
09811 r_type += R_PPC64_TOC16_DS - R_PPC64_TOC16;
09812 rel->r_info = ELF64_R_INFO (r_symndx, r_type);
09813 }
09814 else
09815 {
09816
09817 insn1 = 0x3c6d0000;
09818 insn2 = 0x38630000;
09819 if (tls_gd == 0)
09820 {
09821
09822 r_symndx = 0;
09823 rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
09824 rel[1].r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
09825 }
09826 else if (toc_symndx != 0)
09827 r_symndx = toc_symndx;
09828 r_type = R_PPC64_TPREL16_HA;
09829 rel->r_info = ELF64_R_INFO (r_symndx, r_type);
09830 rel[1].r_info = ELF64_R_INFO (r_symndx,
09831 R_PPC64_TPREL16_LO);
09832 rel[1].r_offset += 2;
09833 }
09834 if (insn3 == NOP
09835 || insn3 == CROR_151515 || insn3 == CROR_313131)
09836 {
09837 insn3 = insn2;
09838 insn2 = NOP;
09839 rel[1].r_offset += 4;
09840 }
09841 bfd_put_32 (output_bfd, insn1, contents + rel->r_offset - 2);
09842 bfd_put_32 (output_bfd, insn2, contents + offset);
09843 bfd_put_32 (output_bfd, insn3, contents + offset + 4);
09844 if (tls_gd == 0 || toc_symndx != 0)
09845 {
09846
09847
09848 rel--;
09849 continue;
09850 }
09851 }
09852 }
09853 break;
09854
09855 case R_PPC64_DTPMOD64:
09856 if (rel + 1 < relend
09857 && rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_DTPREL64)
09858 && rel[1].r_offset == rel->r_offset + 8)
09859 {
09860 if ((tls_mask & TLS_GD) == 0)
09861 {
09862 rel[1].r_info = ELF64_R_INFO (r_symndx, R_PPC64_NONE);
09863 if ((tls_mask & TLS_TPRELGD) != 0)
09864 r_type = R_PPC64_TPREL64;
09865 else
09866 {
09867 bfd_put_64 (output_bfd, 1, contents + rel->r_offset);
09868 r_type = R_PPC64_NONE;
09869 }
09870 rel->r_info = ELF64_R_INFO (r_symndx, r_type);
09871 }
09872 }
09873 else
09874 {
09875 if ((tls_mask & TLS_LD) == 0)
09876 {
09877 bfd_put_64 (output_bfd, 1, contents + rel->r_offset);
09878 r_type = R_PPC64_NONE;
09879 rel->r_info = ELF64_R_INFO (r_symndx, r_type);
09880 }
09881 }
09882 break;
09883
09884 case R_PPC64_TPREL64:
09885 if ((tls_mask & TLS_TPREL) == 0)
09886 {
09887 r_type = R_PPC64_NONE;
09888 rel->r_info = ELF64_R_INFO (r_symndx, r_type);
09889 }
09890 break;
09891 }
09892
09893
09894 insn = 0;
09895 max_br_offset = 1 << 25;
09896 addend = rel->r_addend;
09897 switch (r_type)
09898 {
09899 default:
09900 break;
09901
09902
09903 case R_PPC64_ADDR14_BRTAKEN:
09904 case R_PPC64_REL14_BRTAKEN:
09905 insn = 0x01 << 21;
09906
09907
09908
09909 case R_PPC64_ADDR14_BRNTAKEN:
09910 case R_PPC64_REL14_BRNTAKEN:
09911 insn |= bfd_get_32 (output_bfd,
09912 contents + rel->r_offset) & ~(0x01 << 21);
09913
09914
09915 case R_PPC64_REL14:
09916 max_br_offset = 1 << 15;
09917
09918
09919 case R_PPC64_REL24:
09920
09921
09922
09923
09924
09925
09926 stub_entry = NULL;
09927 fdh = h;
09928 if (((h != NULL
09929 && (((fdh = h->oh) != NULL
09930 && fdh->elf.plt.plist != NULL)
09931 || (fdh = h)->elf.plt.plist != NULL))
09932 || (sec != NULL
09933 && sec->output_section != NULL
09934 && sec->id <= htab->top_id
09935 && (htab->stub_group[sec->id].toc_off
09936 != htab->stub_group[input_section->id].toc_off)))
09937 && (stub_entry = ppc_get_stub_entry (input_section, sec, fdh,
09938 rel, htab)) != NULL
09939 && (stub_entry->stub_type == ppc_stub_plt_call
09940 || stub_entry->stub_type == ppc_stub_plt_branch_r2off
09941 || stub_entry->stub_type == ppc_stub_long_branch_r2off))
09942 {
09943 bfd_boolean can_plt_call = FALSE;
09944
09945 if (rel->r_offset + 8 <= input_section->size)
09946 {
09947 unsigned long nop;
09948 nop = bfd_get_32 (input_bfd, contents + rel->r_offset + 4);
09949 if (nop == NOP
09950 || nop == CROR_151515 || nop == CROR_313131)
09951 {
09952 bfd_put_32 (input_bfd, LD_R2_40R1,
09953 contents + rel->r_offset + 4);
09954 can_plt_call = TRUE;
09955 }
09956 }
09957
09958 if (!can_plt_call)
09959 {
09960 if (stub_entry->stub_type == ppc_stub_plt_call)
09961 {
09962
09963
09964 unsigned long br;
09965 br = bfd_get_32 (input_bfd, contents + rel->r_offset);
09966 if ((br & 1) == 0)
09967 can_plt_call = TRUE;
09968 }
09969 else if (h != NULL
09970 && strcmp (h->elf.root.root.string,
09971 ".__libc_start_main") == 0)
09972 {
09973
09974 can_plt_call = TRUE;
09975 }
09976 else
09977 {
09978 if (strcmp (input_section->output_section->name,
09979 ".init") == 0
09980 || strcmp (input_section->output_section->name,
09981 ".fini") == 0)
09982 (*_bfd_error_handler)
09983 (_("%B(%A+0x%lx): automatic multiple TOCs "
09984 "not supported using your crt files; "
09985 "recompile with -mminimal-toc or upgrade gcc"),
09986 input_bfd,
09987 input_section,
09988 (long) rel->r_offset);
09989 else
09990 (*_bfd_error_handler)
09991 (_("%B(%A+0x%lx): sibling call optimization to `%s' "
09992 "does not allow automatic multiple TOCs; "
09993 "recompile with -mminimal-toc or "
09994 "-fno-optimize-sibling-calls, "
09995 "or make `%s' extern"),
09996 input_bfd,
09997 input_section,
09998 (long) rel->r_offset,
09999 sym_name,
10000 sym_name);
10001 bfd_set_error (bfd_error_bad_value);
10002 ret = FALSE;
10003 }
10004 }
10005
10006 if (can_plt_call
10007 && stub_entry->stub_type == ppc_stub_plt_call)
10008 unresolved_reloc = FALSE;
10009 }
10010
10011 if (stub_entry == NULL
10012 && get_opd_info (sec) != NULL)
10013 {
10014
10015 bfd_vma off = (relocation - sec->output_section->vma
10016 - sec->output_offset + rel->r_addend);
10017 bfd_vma dest = opd_entry_value (sec, off, NULL, NULL);
10018 if (dest != (bfd_vma) -1)
10019 {
10020 relocation = dest;
10021 addend = 0;
10022 }
10023 }
10024
10025
10026
10027 from = (rel->r_offset
10028 + input_section->output_offset
10029 + input_section->output_section->vma);
10030
10031 if (stub_entry == NULL
10032 && (relocation + rel->r_addend - from + max_br_offset
10033 >= 2 * max_br_offset)
10034 && r_type != R_PPC64_ADDR14_BRTAKEN
10035 && r_type != R_PPC64_ADDR14_BRNTAKEN)
10036 stub_entry = ppc_get_stub_entry (input_section, sec, h, rel,
10037 htab);
10038
10039 if (stub_entry != NULL)
10040 {
10041
10042
10043 relocation = (stub_entry->stub_offset
10044 + stub_entry->stub_sec->output_offset
10045 + stub_entry->stub_sec->output_section->vma);
10046 addend = 0;
10047 }
10048
10049 if (insn != 0)
10050 {
10051 if (is_power4)
10052 {
10053
10054
10055
10056 if ((insn & (0x14 << 21)) == (0x04 << 21))
10057 insn |= 0x02 << 21;
10058 else if ((insn & (0x14 << 21)) == (0x10 << 21))
10059 insn |= 0x08 << 21;
10060 else
10061 break;
10062 }
10063 else
10064 {
10065
10066 if ((bfd_signed_vma) (relocation + rel->r_addend - from) < 0)
10067 insn ^= 0x01 << 21;
10068 }
10069
10070 bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
10071 }
10072
10073
10074
10075
10076 else if (h != NULL
10077 && h->elf.root.type == bfd_link_hash_undefweak
10078 && r_type == R_PPC64_REL24
10079 && relocation == 0
10080 && rel->r_addend == 0)
10081 {
10082 bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
10083 continue;
10084 }
10085 break;
10086 }
10087
10088
10089 tls_type = 0;
10090 switch (r_type)
10091 {
10092 default:
10093 (*_bfd_error_handler)
10094 (_("%B: unknown relocation type %d for symbol %s"),
10095 input_bfd, (int) r_type, sym_name);
10096
10097 bfd_set_error (bfd_error_bad_value);
10098 ret = FALSE;
10099 continue;
10100
10101 case R_PPC64_NONE:
10102 case R_PPC64_TLS:
10103 case R_PPC64_GNU_VTINHERIT:
10104 case R_PPC64_GNU_VTENTRY:
10105 continue;
10106
10107
10108
10109
10110
10111 case R_PPC64_GOT_TLSGD16:
10112 case R_PPC64_GOT_TLSGD16_LO:
10113 case R_PPC64_GOT_TLSGD16_HI:
10114 case R_PPC64_GOT_TLSGD16_HA:
10115 tls_type = TLS_TLS | TLS_GD;
10116 goto dogot;
10117
10118 case R_PPC64_GOT_TLSLD16:
10119 case R_PPC64_GOT_TLSLD16_LO:
10120 case R_PPC64_GOT_TLSLD16_HI:
10121 case R_PPC64_GOT_TLSLD16_HA:
10122 tls_type = TLS_TLS | TLS_LD;
10123 goto dogot;
10124
10125 case R_PPC64_GOT_TPREL16_DS:
10126 case R_PPC64_GOT_TPREL16_LO_DS:
10127 case R_PPC64_GOT_TPREL16_HI:
10128 case R_PPC64_GOT_TPREL16_HA:
10129 tls_type = TLS_TLS | TLS_TPREL;
10130 goto dogot;
10131
10132 case R_PPC64_GOT_DTPREL16_DS:
10133 case R_PPC64_GOT_DTPREL16_LO_DS:
10134 case R_PPC64_GOT_DTPREL16_HI:
10135 case R_PPC64_GOT_DTPREL16_HA:
10136 tls_type = TLS_TLS | TLS_DTPREL;
10137 goto dogot;
10138
10139 case R_PPC64_GOT16:
10140 case R_PPC64_GOT16_LO:
10141 case R_PPC64_GOT16_HI:
10142 case R_PPC64_GOT16_HA:
10143 case R_PPC64_GOT16_DS:
10144 case R_PPC64_GOT16_LO_DS:
10145 dogot:
10146 {
10147
10148
10149 asection *got;
10150 bfd_vma *offp;
10151 bfd_vma off;
10152 unsigned long indx = 0;
10153
10154 if (tls_type == (TLS_TLS | TLS_LD)
10155 && (h == NULL
10156 || !h->elf.def_dynamic))
10157 offp = &ppc64_tlsld_got (input_bfd)->offset;
10158 else
10159 {
10160 struct got_entry *ent;
10161
10162 if (h != NULL)
10163 {
10164 bfd_boolean dyn = htab->elf.dynamic_sections_created;
10165 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared,
10166 &h->elf)
10167 || (info->shared
10168 && SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
10169
10170
10171
10172
10173 ;
10174 else
10175 {
10176 indx = h->elf.dynindx;
10177 unresolved_reloc = FALSE;
10178 }
10179 ent = h->elf.got.glist;
10180 }
10181 else
10182 {
10183 if (local_got_ents == NULL)
10184 abort ();
10185 ent = local_got_ents[r_symndx];
10186 }
10187
10188 for (; ent != NULL; ent = ent->next)
10189 if (ent->addend == rel->r_addend
10190 && ent->owner == input_bfd
10191 && ent->tls_type == tls_type)
10192 break;
10193 if (ent == NULL)
10194 abort ();
10195 offp = &ent->got.offset;
10196 }
10197
10198 got = ppc64_elf_tdata (input_bfd)->got;
10199 if (got == NULL)
10200 abort ();
10201
10202
10203
10204
10205 off = *offp;
10206 if ((off & 1) != 0)
10207 off &= ~1;
10208 else
10209 {
10210
10211
10212
10213 asection *relgot = ppc64_elf_tdata (input_bfd)->relgot;
10214
10215 *offp = off | 1;
10216 if ((info->shared || indx != 0)
10217 && (h == NULL
10218 || ELF_ST_VISIBILITY (h->elf.other) == STV_DEFAULT
10219 || h->elf.root.type != bfd_link_hash_undefweak))
10220 {
10221 outrel.r_offset = (got->output_section->vma
10222 + got->output_offset
10223 + off);
10224 outrel.r_addend = rel->r_addend;
10225 if (tls_type & (TLS_LD | TLS_GD))
10226 {
10227 outrel.r_addend = 0;
10228 outrel.r_info = ELF64_R_INFO (indx, R_PPC64_DTPMOD64);
10229 if (tls_type == (TLS_TLS | TLS_GD))
10230 {
10231 loc = relgot->contents;
10232 loc += (relgot->reloc_count++
10233 * sizeof (Elf64_External_Rela));
10234 bfd_elf64_swap_reloca_out (output_bfd,
10235 &outrel, loc);
10236 outrel.r_offset += 8;
10237 outrel.r_addend = rel->r_addend;
10238 outrel.r_info
10239 = ELF64_R_INFO (indx, R_PPC64_DTPREL64);
10240 }
10241 }
10242 else if (tls_type == (TLS_TLS | TLS_DTPREL))
10243 outrel.r_info = ELF64_R_INFO (indx, R_PPC64_DTPREL64);
10244 else if (tls_type == (TLS_TLS | TLS_TPREL))
10245 outrel.r_info = ELF64_R_INFO (indx, R_PPC64_TPREL64);
10246 else if (indx == 0)
10247 {
10248 outrel.r_info = ELF64_R_INFO (indx, R_PPC64_RELATIVE);
10249
10250
10251
10252 loc = got->contents + off;
10253 bfd_put_64 (output_bfd, outrel.r_addend + relocation,
10254 loc);
10255 }
10256 else
10257 outrel.r_info = ELF64_R_INFO (indx, R_PPC64_GLOB_DAT);
10258
10259 if (indx == 0 && tls_type != (TLS_TLS | TLS_LD))
10260 {
10261 outrel.r_addend += relocation;
10262 if (tls_type & (TLS_GD | TLS_DTPREL | TLS_TPREL))
10263 outrel.r_addend -= htab->elf.tls_sec->vma;
10264 }
10265 loc = relgot->contents;
10266 loc += (relgot->reloc_count++
10267 * sizeof (Elf64_External_Rela));
10268 bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
10269 }
10270
10271
10272
10273 else
10274 {
10275 relocation += rel->r_addend;
10276 if (tls_type == (TLS_TLS | TLS_LD))
10277 relocation = 1;
10278 else if (tls_type != 0)
10279 {
10280 relocation -= htab->elf.tls_sec->vma + DTP_OFFSET;
10281 if (tls_type == (TLS_TLS | TLS_TPREL))
10282 relocation += DTP_OFFSET - TP_OFFSET;
10283
10284 if (tls_type == (TLS_TLS | TLS_GD))
10285 {
10286 bfd_put_64 (output_bfd, relocation,
10287 got->contents + off + 8);
10288 relocation = 1;
10289 }
10290 }
10291
10292 bfd_put_64 (output_bfd, relocation,
10293 got->contents + off);
10294 }
10295 }
10296
10297 if (off >= (bfd_vma) -2)
10298 abort ();
10299
10300 relocation = got->output_offset + off;
10301
10302
10303 addend = -TOC_BASE_OFF;
10304 }
10305 break;
10306
10307 case R_PPC64_PLT16_HA:
10308 case R_PPC64_PLT16_HI:
10309 case R_PPC64_PLT16_LO:
10310 case R_PPC64_PLT32:
10311 case R_PPC64_PLT64:
10312
10313
10314
10315
10316
10317 if (h == NULL)
10318 break;
10319
10320
10321
10322
10323
10324 if (htab->plt != NULL)
10325 {
10326 struct plt_entry *ent;
10327 for (ent = h->elf.plt.plist; ent != NULL; ent = ent->next)
10328 if (ent->addend == rel->r_addend
10329 && ent->plt.offset != (bfd_vma) -1)
10330 {
10331 relocation = (htab->plt->output_section->vma
10332 + htab->plt->output_offset
10333 + ent->plt.offset);
10334 unresolved_reloc = FALSE;
10335 }
10336 }
10337 break;
10338
10339 case R_PPC64_TOC:
10340
10341 relocation = TOCstart;
10342 if (r_symndx == 0)
10343 relocation += htab->stub_group[input_section->id].toc_off;
10344 else if (unresolved_reloc)
10345 ;
10346 else if (sec != NULL && sec->id <= htab->top_id)
10347 relocation += htab->stub_group[sec->id].toc_off;
10348 else
10349 unresolved_reloc = TRUE;
10350 goto dodyn2;
10351
10352
10353
10354
10355
10356 case R_PPC64_TOC16:
10357 case R_PPC64_TOC16_LO:
10358 case R_PPC64_TOC16_HI:
10359 case R_PPC64_TOC16_DS:
10360 case R_PPC64_TOC16_LO_DS:
10361 case R_PPC64_TOC16_HA:
10362 addend -= TOCstart + htab->stub_group[input_section->id].toc_off;
10363 break;
10364
10365
10366 case R_PPC64_SECTOFF:
10367 case R_PPC64_SECTOFF_LO:
10368 case R_PPC64_SECTOFF_HI:
10369 case R_PPC64_SECTOFF_DS:
10370 case R_PPC64_SECTOFF_LO_DS:
10371 case R_PPC64_SECTOFF_HA:
10372 if (sec != NULL)
10373 addend -= sec->output_section->vma;
10374 break;
10375
10376 case R_PPC64_REL14:
10377 case R_PPC64_REL14_BRNTAKEN:
10378 case R_PPC64_REL14_BRTAKEN:
10379 case R_PPC64_REL24:
10380 break;
10381
10382 case R_PPC64_TPREL16:
10383 case R_PPC64_TPREL16_LO:
10384 case R_PPC64_TPREL16_HI:
10385 case R_PPC64_TPREL16_HA:
10386 case R_PPC64_TPREL16_DS:
10387 case R_PPC64_TPREL16_LO_DS:
10388 case R_PPC64_TPREL16_HIGHER:
10389 case R_PPC64_TPREL16_HIGHERA:
10390 case R_PPC64_TPREL16_HIGHEST:
10391 case R_PPC64_TPREL16_HIGHESTA:
10392 addend -= htab->elf.tls_sec->vma + TP_OFFSET;
10393 if (info->shared)
10394
10395
10396
10397 goto dodyn;
10398 break;
10399
10400 case R_PPC64_DTPREL16:
10401 case R_PPC64_DTPREL16_LO:
10402 case R_PPC64_DTPREL16_HI:
10403 case R_PPC64_DTPREL16_HA:
10404 case R_PPC64_DTPREL16_DS:
10405 case R_PPC64_DTPREL16_LO_DS:
10406 case R_PPC64_DTPREL16_HIGHER:
10407 case R_PPC64_DTPREL16_HIGHERA:
10408 case R_PPC64_DTPREL16_HIGHEST:
10409 case R_PPC64_DTPREL16_HIGHESTA:
10410 addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
10411 break;
10412
10413 case R_PPC64_DTPMOD64:
10414 relocation = 1;
10415 addend = 0;
10416 goto dodyn;
10417
10418 case R_PPC64_TPREL64:
10419 addend -= htab->elf.tls_sec->vma + TP_OFFSET;
10420 goto dodyn;
10421
10422 case R_PPC64_DTPREL64:
10423 addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
10424
10425
10426
10427
10428 case R_PPC64_REL30:
10429 case R_PPC64_REL32:
10430 case R_PPC64_REL64:
10431 case R_PPC64_ADDR14:
10432 case R_PPC64_ADDR14_BRNTAKEN:
10433 case R_PPC64_ADDR14_BRTAKEN:
10434 case R_PPC64_ADDR16:
10435 case R_PPC64_ADDR16_DS:
10436 case R_PPC64_ADDR16_HA:
10437 case R_PPC64_ADDR16_HI:
10438 case R_PPC64_ADDR16_HIGHER:
10439 case R_PPC64_ADDR16_HIGHERA:
10440 case R_PPC64_ADDR16_HIGHEST:
10441 case R_PPC64_ADDR16_HIGHESTA:
10442 case R_PPC64_ADDR16_LO:
10443 case R_PPC64_ADDR16_LO_DS:
10444 case R_PPC64_ADDR24:
10445 case R_PPC64_ADDR32:
10446 case R_PPC64_ADDR64:
10447 case R_PPC64_UADDR16:
10448 case R_PPC64_UADDR32:
10449 case R_PPC64_UADDR64:
10450
10451
10452
10453 dodyn:
10454 if (r_symndx == 0)
10455 break;
10456
10457
10458 dodyn2:
10459 if ((input_section->flags & SEC_ALLOC) == 0)
10460 break;
10461
10462 if (NO_OPD_RELOCS && is_opd)
10463 break;
10464
10465 if ((info->shared
10466 && (h == NULL
10467 || ELF_ST_VISIBILITY (h->elf.other) == STV_DEFAULT
10468 || h->elf.root.type != bfd_link_hash_undefweak)
10469 && (MUST_BE_DYN_RELOC (r_type)
10470 || !SYMBOL_CALLS_LOCAL (info, &h->elf)))
10471 || (ELIMINATE_COPY_RELOCS
10472 && !info->shared
10473 && h != NULL
10474 && h->elf.dynindx != -1
10475 && !h->elf.non_got_ref
10476 && h->elf.def_dynamic
10477 && !h->elf.def_regular))
10478 {
10479 Elf_Internal_Rela outrel;
10480 bfd_boolean skip, relocate;
10481 asection *sreloc;
10482 bfd_byte *loc;
10483 bfd_vma out_off;
10484
10485
10486
10487
10488
10489 skip = FALSE;
10490 relocate = FALSE;
10491
10492 out_off = _bfd_elf_section_offset (output_bfd, info,
10493 input_section, rel->r_offset);
10494 if (out_off == (bfd_vma) -1)
10495 skip = TRUE;
10496 else if (out_off == (bfd_vma) -2)
10497 skip = TRUE, relocate = TRUE;
10498 out_off += (input_section->output_section->vma
10499 + input_section->output_offset);
10500 outrel.r_offset = out_off;
10501 outrel.r_addend = rel->r_addend;
10502
10503
10504 if ((r_type == R_PPC64_ADDR64 && (out_off & 7) != 0)
10505 || (r_type == R_PPC64_UADDR64 && (out_off & 7) == 0))
10506 r_type ^= R_PPC64_ADDR64 ^ R_PPC64_UADDR64;
10507 else if ((r_type == R_PPC64_ADDR32 && (out_off & 3) != 0)
10508 || (r_type == R_PPC64_UADDR32 && (out_off & 3) == 0))
10509 r_type ^= R_PPC64_ADDR32 ^ R_PPC64_UADDR32;
10510 else if ((r_type == R_PPC64_ADDR16 && (out_off & 1) != 0)
10511 || (r_type == R_PPC64_UADDR16 && (out_off & 1) == 0))
10512 r_type ^= R_PPC64_ADDR16 ^ R_PPC64_UADDR16;
10513
10514 if (skip)
10515 memset (&outrel, 0, sizeof outrel);
10516 else if (!SYMBOL_REFERENCES_LOCAL (info, &h->elf)
10517 && !is_opd
10518 && r_type != R_PPC64_TOC)
10519 outrel.r_info = ELF64_R_INFO (h->elf.dynindx, r_type);
10520 else
10521 {
10522
10523
10524
10525 outrel.r_addend += relocation;
10526 if (r_type == R_PPC64_ADDR64 || r_type == R_PPC64_TOC)
10527 {
10528 if (is_opd && h != NULL)
10529 {
10530
10531
10532
10533
10534
10535
10536
10537
10538
10539
10540 unresolved_reloc = FALSE;
10541 }
10542 outrel.r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
10543
10544
10545
10546
10547
10548 relocate = TRUE;
10549 }
10550 else
10551 {
10552 long indx = 0;
10553
10554 if (bfd_is_abs_section (sec))
10555 ;
10556 else if (sec == NULL || sec->owner == NULL)
10557 {
10558 bfd_set_error (bfd_error_bad_value);
10559 return FALSE;
10560 }
10561 else
10562 {
10563 asection *osec;
10564
10565 osec = sec->output_section;
10566 indx = elf_section_data (osec)->dynindx;
10567
10568
10569
10570
10571
10572
10573 outrel.r_addend -= osec->vma;
10574 }
10575
10576 outrel.r_info = ELF64_R_INFO (indx, r_type);
10577 }
10578 }
10579
10580 sreloc = elf_section_data (input_section)->sreloc;
10581 if (sreloc == NULL)
10582 abort ();
10583
10584 loc = sreloc->contents;
10585 loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
10586 bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
10587
10588
10589
10590
10591
10592 if (! relocate)
10593 {
10594 unresolved_reloc = FALSE;
10595
10596
10597
10598
10599
10600 relocation = 0;
10601 addend = 0;
10602
10603
10604
10605 if (r_type == R_PPC64_ADDR64)
10606 addend = outrel.r_addend;
10607
10608 else if (ppc64_elf_howto_table[r_type]->pc_relative)
10609 addend = (input_section->output_section->vma
10610 + input_section->output_offset
10611 + rel->r_offset);
10612 }
10613 }
10614 break;
10615
10616 case R_PPC64_COPY:
10617 case R_PPC64_GLOB_DAT:
10618 case R_PPC64_JMP_SLOT:
10619 case R_PPC64_RELATIVE:
10620
10621
10622
10623
10624 case R_PPC64_PLTGOT16:
10625 case R_PPC64_PLTGOT16_DS:
10626 case R_PPC64_PLTGOT16_HA:
10627 case R_PPC64_PLTGOT16_HI:
10628 case R_PPC64_PLTGOT16_LO:
10629 case R_PPC64_PLTGOT16_LO_DS:
10630 case R_PPC64_PLTREL32:
10631 case R_PPC64_PLTREL64:
10632
10633
10634 (*_bfd_error_handler)
10635 (_("%B: relocation %s is not supported for symbol %s."),
10636 input_bfd,
10637 ppc64_elf_howto_table[r_type]->name, sym_name);
10638
10639 bfd_set_error (bfd_error_invalid_operation);
10640 ret = FALSE;
10641 continue;
10642 }
10643
10644
10645 switch (r_type)
10646 {
10647 default:
10648 break;
10649
10650 case R_PPC64_ADDR16_HA:
10651 case R_PPC64_ADDR16_HIGHERA:
10652 case R_PPC64_ADDR16_HIGHESTA:
10653 case R_PPC64_GOT16_HA:
10654 case R_PPC64_PLTGOT16_HA:
10655 case R_PPC64_PLT16_HA:
10656 case R_PPC64_TOC16_HA:
10657 case R_PPC64_SECTOFF_HA:
10658 case R_PPC64_TPREL16_HA:
10659 case R_PPC64_DTPREL16_HA:
10660 case R_PPC64_GOT_TLSGD16_HA:
10661 case R_PPC64_GOT_TLSLD16_HA:
10662 case R_PPC64_GOT_TPREL16_HA:
10663 case R_PPC64_GOT_DTPREL16_HA:
10664 case R_PPC64_TPREL16_HIGHER:
10665 case R_PPC64_TPREL16_HIGHERA:
10666 case R_PPC64_TPREL16_HIGHEST:
10667 case R_PPC64_TPREL16_HIGHESTA:
10668 case R_PPC64_DTPREL16_HIGHER:
10669 case R_PPC64_DTPREL16_HIGHERA:
10670 case R_PPC64_DTPREL16_HIGHEST:
10671 case R_PPC64_DTPREL16_HIGHESTA:
10672
10673
10674
10675
10676 if (sec != NULL)
10677
10678
10679 addend += 0x8000;
10680 break;
10681
10682 case R_PPC64_ADDR16_DS:
10683 case R_PPC64_ADDR16_LO_DS:
10684 case R_PPC64_GOT16_DS:
10685 case R_PPC64_GOT16_LO_DS:
10686 case R_PPC64_PLT16_LO_DS:
10687 case R_PPC64_SECTOFF_DS:
10688 case R_PPC64_SECTOFF_LO_DS:
10689 case R_PPC64_TOC16_DS:
10690 case R_PPC64_TOC16_LO_DS:
10691 case R_PPC64_PLTGOT16_DS:
10692 case R_PPC64_PLTGOT16_LO_DS:
10693 case R_PPC64_GOT_TPREL16_DS:
10694 case R_PPC64_GOT_TPREL16_LO_DS:
10695 case R_PPC64_GOT_DTPREL16_DS:
10696 case R_PPC64_GOT_DTPREL16_LO_DS:
10697 case R_PPC64_TPREL16_DS:
10698 case R_PPC64_TPREL16_LO_DS:
10699 case R_PPC64_DTPREL16_DS:
10700 case R_PPC64_DTPREL16_LO_DS:
10701 insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
10702 mask = 3;
10703
10704
10705
10706
10707
10708
10709 if ((insn & (0x3f << 26)) == (56u << 26))
10710 mask = 15;
10711 if (((relocation + addend) & mask) != 0)
10712 {
10713 (*_bfd_error_handler)
10714 (_("%B: error: relocation %s not a multiple of %d"),
10715 input_bfd,
10716 ppc64_elf_howto_table[r_type]->name,
10717 mask + 1);
10718 bfd_set_error (bfd_error_bad_value);
10719 ret = FALSE;
10720 continue;
10721 }
10722 break;
10723 }
10724
10725
10726
10727
10728 if (unresolved_reloc
10729 && !((input_section->flags & SEC_DEBUGGING) != 0
10730 && h->elf.def_dynamic))
10731 {
10732 (*_bfd_error_handler)
10733 (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
10734 input_bfd,
10735 input_section,
10736 (long) rel->r_offset,
10737 ppc64_elf_howto_table[(int) r_type]->name,
10738 h->elf.root.root.string);
10739 ret = FALSE;
10740 }
10741
10742 r = _bfd_final_link_relocate (ppc64_elf_howto_table[(int) r_type],
10743 input_bfd,
10744 input_section,
10745 contents,
10746 rel->r_offset,
10747 relocation,
10748 addend);
10749
10750 if (r != bfd_reloc_ok)
10751 {
10752 if (sym_name == NULL)
10753 sym_name = "(null)";
10754 if (r == bfd_reloc_overflow)
10755 {
10756 if (warned)
10757 continue;
10758 if (h != NULL
10759 && h->elf.root.type == bfd_link_hash_undefweak
10760 && ppc64_elf_howto_table[r_type]->pc_relative)
10761 {
10762
10763
10764
10765
10766
10767
10768 continue;
10769 }
10770
10771 if (!((*info->callbacks->reloc_overflow)
10772 (info, (h ? &h->elf.root : NULL), sym_name,
10773 ppc64_elf_howto_table[r_type]->name,
10774 rel->r_addend, input_bfd, input_section, rel->r_offset)))
10775 return FALSE;
10776 }
10777 else
10778 {
10779 (*_bfd_error_handler)
10780 (_("%B(%A+0x%lx): %s reloc against `%s': error %d"),
10781 input_bfd,
10782 input_section,
10783 (long) rel->r_offset,
10784 ppc64_elf_howto_table[r_type]->name,
10785 sym_name,
10786 (int) r);
10787 ret = FALSE;
10788 }
10789 }
10790 }
10791
10792
10793
10794
10795
10796
10797 if (is_opd && info->emitrelocations)
10798 {
10799 bfd_size_type amt;
10800 amt = input_section->reloc_count * sizeof (Elf_Internal_Rela);
10801 rel = bfd_alloc (input_bfd, amt);
10802 BFD_ASSERT (ppc64_elf_tdata (input_bfd)->opd_relocs == NULL);
10803 ppc64_elf_tdata (input_bfd)->opd_relocs = rel;
10804 if (rel == NULL)
10805 return FALSE;
10806 memcpy (rel, relocs, amt);
10807 }
10808 return ret;
10809 }
10810
10811
10812
10813 static bfd_boolean
10814 ppc64_elf_output_symbol_hook (struct bfd_link_info *info,
10815 const char *name ATTRIBUTE_UNUSED,
10816 Elf_Internal_Sym *elfsym,
10817 asection *input_sec,
10818 struct elf_link_hash_entry *h)
10819 {
10820 long *opd_adjust, adjust;
10821 bfd_vma value;
10822
10823 if (h != NULL)
10824 return TRUE;
10825
10826 opd_adjust = get_opd_info (input_sec);
10827 if (opd_adjust == NULL)
10828 return TRUE;
10829
10830 value = elfsym->st_value - input_sec->output_offset;
10831 if (!info->relocatable)
10832 value -= input_sec->output_section->vma;
10833
10834 adjust = opd_adjust[value / 8];
10835 if (adjust == -1)
10836 elfsym->st_value = 0;
10837 else
10838 elfsym->st_value += adjust;
10839 return TRUE;
10840 }
10841
10842
10843
10844
10845 static bfd_boolean
10846 ppc64_elf_finish_dynamic_symbol (bfd *output_bfd,
10847 struct bfd_link_info *info,
10848 struct elf_link_hash_entry *h,
10849 Elf_Internal_Sym *sym)
10850 {
10851 struct ppc_link_hash_table *htab;
10852 bfd *dynobj;
10853 struct plt_entry *ent;
10854 Elf_Internal_Rela rela;
10855 bfd_byte *loc;
10856
10857 htab = ppc_hash_table (info);
10858 dynobj = htab->elf.dynobj;
10859
10860 for (ent = h->plt.plist; ent != NULL; ent = ent->next)
10861 if (ent->plt.offset != (bfd_vma) -1)
10862 {
10863
10864
10865
10866 if (htab->plt == NULL
10867 || htab->relplt == NULL
10868 || htab->glink == NULL)
10869 abort ();
10870
10871
10872
10873 rela.r_offset = (htab->plt->output_section->vma
10874 + htab->plt->output_offset
10875 + ent->plt.offset);
10876 rela.r_info = ELF64_R_INFO (h->dynindx, R_PPC64_JMP_SLOT);
10877 rela.r_addend = ent->addend;
10878
10879 loc = htab->relplt->contents;
10880 loc += ((ent->plt.offset - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE
10881 * sizeof (Elf64_External_Rela));
10882 bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
10883 }
10884
10885 if (h->needs_copy)
10886 {
10887 Elf_Internal_Rela rela;
10888 bfd_byte *loc;
10889
10890
10891
10892 if (h->dynindx == -1
10893 || (h->root.type != bfd_link_hash_defined
10894 && h->root.type != bfd_link_hash_defweak)
10895 || htab->relbss == NULL)
10896 abort ();
10897
10898 rela.r_offset = (h->root.u.def.value
10899 + h->root.u.def.section->output_section->vma
10900 + h->root.u.def.section->output_offset);
10901 rela.r_info = ELF64_R_INFO (h->dynindx, R_PPC64_COPY);
10902 rela.r_addend = 0;
10903 loc = htab->relbss->contents;
10904 loc += htab->relbss->reloc_count++ * sizeof (Elf64_External_Rela);
10905 bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
10906 }
10907
10908
10909 if (strcmp (h->root.root.string, "_DYNAMIC") == 0)
10910 sym->st_shndx = SHN_ABS;
10911
10912 return TRUE;
10913 }
10914
10915
10916
10917
10918 static enum elf_reloc_type_class
10919 ppc64_elf_reloc_type_class (const Elf_Internal_Rela *rela)
10920 {
10921 enum elf_ppc64_reloc_type r_type;
10922
10923 r_type = ELF64_R_TYPE (rela->r_info);
10924 switch (r_type)
10925 {
10926 case R_PPC64_RELATIVE:
10927 return reloc_class_relative;
10928 case R_PPC64_JMP_SLOT:
10929 return reloc_class_plt;
10930 case R_PPC64_COPY:
10931 return reloc_class_copy;
10932 default:
10933 return reloc_class_normal;
10934 }
10935 }
10936
10937
10938
10939 static bfd_boolean
10940 ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
10941 struct bfd_link_info *info)
10942 {
10943 struct ppc_link_hash_table *htab;
10944 bfd *dynobj;
10945 asection *sdyn;
10946
10947 htab = ppc_hash_table (info);
10948 dynobj = htab->elf.dynobj;
10949 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
10950
10951 if (htab->elf.dynamic_sections_created)
10952 {
10953 Elf64_External_Dyn *dyncon, *dynconend;
10954
10955 if (sdyn == NULL || htab->got == NULL)
10956 abort ();
10957
10958 dyncon = (Elf64_External_Dyn *) sdyn->contents;
10959 dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
10960 for (; dyncon < dynconend; dyncon++)
10961 {
10962 Elf_Internal_Dyn dyn;
10963 asection *s;
10964
10965 bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
10966
10967 switch (dyn.d_tag)
10968 {
10969 default:
10970 continue;
10971
10972 case DT_PPC64_GLINK:
10973 s = htab->glink;
10974 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
10975
10976
10977
10978
10979 dyn.d_un.d_ptr += GLINK_CALL_STUB_SIZE - 32;
10980 break;
10981
10982 case DT_PPC64_OPD:
10983 s = bfd_get_section_by_name (output_bfd, ".opd");
10984 if (s == NULL)
10985 continue;
10986 dyn.d_un.d_ptr = s->vma;
10987 break;
10988
10989 case DT_PPC64_OPDSZ:
10990 s = bfd_get_section_by_name (output_bfd, ".opd");
10991 if (s == NULL)
10992 continue;
10993 dyn.d_un.d_val = s->size;
10994 break;
10995
10996 case DT_PLTGOT:
10997 s = htab->plt;
10998 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
10999 break;
11000
11001 case DT_JMPREL:
11002 s = htab->relplt;
11003 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
11004 break;
11005
11006 case DT_PLTRELSZ:
11007 dyn.d_un.d_val = htab->relplt->size;
11008 break;
11009
11010 case DT_RELASZ:
11011
11012
11013 s = htab->relplt;
11014 if (s == NULL)
11015 continue;
11016 dyn.d_un.d_val -= s->size;
11017 break;
11018
11019 case DT_RELA:
11020
11021
11022
11023 s = htab->relplt;
11024 if (s == NULL)
11025 continue;
11026 if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset)
11027 continue;
11028 dyn.d_un.d_ptr += s->size;
11029 break;
11030 }
11031
11032 bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
11033 }
11034 }
11035
11036 if (htab->got != NULL && htab->got->size != 0)
11037 {
11038
11039
11040 bfd_put_64 (output_bfd,
11041 elf_gp (output_bfd) + TOC_BASE_OFF,
11042 htab->got->contents);
11043
11044
11045 elf_section_data (htab->got->output_section)->this_hdr.sh_entsize = 8;
11046 }
11047
11048 if (htab->plt != NULL && htab->plt->size != 0)
11049 {
11050
11051 elf_section_data (htab->plt->output_section)->this_hdr.sh_entsize
11052 = PLT_ENTRY_SIZE;
11053 }
11054
11055
11056
11057
11058 while ((dynobj = dynobj->link_next) != NULL)
11059 {
11060 asection *s;
11061
11062 if (!is_ppc64_elf_target (dynobj->xvec))
11063 continue;
11064
11065 s = ppc64_elf_tdata (dynobj)->got;
11066 if (s != NULL
11067 && s->size != 0
11068 && s->output_section != bfd_abs_section_ptr
11069 && !bfd_set_section_contents (output_bfd, s->output_section,
11070 s->contents, s->output_offset,
11071 s->size))
11072 return FALSE;
11073 s = ppc64_elf_tdata (dynobj)->relgot;
11074 if (s != NULL
11075 && s->size != 0
11076 && s->output_section != bfd_abs_section_ptr
11077 && !bfd_set_section_contents (output_bfd, s->output_section,
11078 s->contents, s->output_offset,
11079 s->size))
11080 return FALSE;
11081 }
11082
11083 return TRUE;
11084 }
11085
11086 #include "elf64-target.h"