This patch allows the user to override powerpc64-ld's default for
providing linker generated register save and restore functions as used
by gcc -Os code. Normally these are not provided by ld -r, so Linux
kernel modules have needed to include their own copies.
bfd/
* elf64-ppc.h (struct ppc64_elf_params): Add save_restore_funcs.
* elf64-ppc.c (ppc64_elf_func_desc_adjust): Use it to control
provision of out-of-line register save/restore routines.
ld/
* emultempl/ppc64elf.em (params): Init new field.
(ppc_create_output_section_statements): Set params.save_restore_funcs
default.
(PARSE_AND_LIST_*): Add support for --save-restore-funcs and
--no-save-restore-funcs.
Moves assorted variables used to communicate between ld and bfd into
a struct, hooks it into the bfd link_hash_table early, and removes
all other places where such variables were passed piecemeal.
bfd/
* elf64-ppc.h (struct ppc64_elf_params): Define.
(ppc64_elf_init_stub_bfd, ppc64_elf_edit_opd, ppc64_elf_tls_setup,
ppc64_elf_setup_section_lists, ppc64_elf_size_stubs,
ppc64_elf_build_stubs): Update prototype.
* elf64-ppp.c (struct ppc_link_hash_table): Add params, delete other
fields now in params. Adjust code throughout file.
(ppc64_elf_init_stub_bfd): Delete "abfd" parameter, add "params".
Save params pointer in htab.
(ppc64_elf_edit_opd, ppc64_elf_tls_setup,
ppc64_elf_setup_section_lists, ppc64_elf_size_stubs,
ppc64_elf_build_stubs): Remove parameters now in "params".
ld/
* emultemps/ppc64elf.em (params): New static struct replacing
various other static vars. Adjust code throughout file.
* elf64-ppc.h (ppc64_elf_toc): Delete.
(ppc64_elf_set_toc): Declare.
* elf64-ppc.c (ppc64_elf_toc_reloc): Replace call to ppc64_elf_toc
with call the ppc64_elf_set_toc.
(ppc64_elf_toc_ha_reloc, ppc64_elf_toc64_reloc): Likewise.
(ppc64_elf_start_multitoc_partition): Likewise.
(struct ppc_link_hash_table): Delete dot_toc_dot. Replace all uses
with elf.hgot.
(ppc64_elf_process_dot_syms): Don't make a fake function descriptor
for ".TOC.".
(ppc64_elf_check_relocs): Mark sections with a reference to .TOC.
as needing a toc pointer.
(ppc64_elf_size_stubs): Don't set dot_toc_dot here.
(ppc64_elf_set_toc): Rename from ppc64_elf_toc. Add info param.
Set elf.hgot value.
ld/
* emultempl/ppc64elf.em: (ppc_layout_sections_again): Call
ppc64_elf_set_toc rather than ppc64_elf_toc/_bfd_set_gp_value.
(gld${EMULATION_NAME}_after_allocation): Likewise.
* elf64-ppc.c: Define more insns used in plt call stubs.
(ppc64_elf_brtaken_reloc): Assume isa version 2 or above.
(ppc64_elf_relocate_section): Likewise.
(enum ppc_stub_type): Add ppc_stub_plt_call_r2save.
(struct ppc_link_hash_table): Increase size of stub_count array.
Add plt_stub_align and plt_thread_safe.
(ALWAYS_USE_FAKE_DEP, ALWAYS_EMIT_R2SAVE): Define.
(plt_stub_size, plt_stub_pad): New functions.
(build_plt_stub): Emit barriers for power7 thread safety. Don't
emit needless save of r2.
(build_tls_get_addr_stub): Adjust params.
(ppc_build_one_stub): Handle ppc_stub_plt_call_r2save and aligning
plt stubs. Adjust build_*plt_stub calls.
(ppc_size_one_stub): Similarly.
(ppc64_elf_size_stubs): Accept plt_thread_safe and plt_stub_align
params. Choose default for plt_thread_safe based on existence of
calls to thread creation functions. Modify plt_call to
plt_call_r2save when no tocsave reloc found. Align tail of stub
sections.
(ppc64_elf_build_stubs): Align tail of stub sections. Adjust
output of stub statistics.
(ppc64_elf_relocate_section): Handle ppc_stub_plt_call_r2save.
* elf64-ppc.h (ppc64_elf_size_stubs): Update prototype.
ld/
* emultempl/ppc64elf.em (PARSE_AND_LIST_PROLOGUE,
PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS,
PARSE_AND_LIST_ARGS_CASES): Handle --{no-,}plt-thread-safe and
--{no-,}plt-align.
(plt_thread_safe, plt_stub_align): New vars.
(gld${EMULATION_NAME}_after_allocation): Pass them to
ppc64_elf_size_stubs. Align stub sections according to plt_stub_align.
* ld.texinfo: Document new command line options, and an old
undocumented option.
PR ld/11378
* elf64-ppc.h (ppc64_elf_check_init_fini): Declare.
* elf64-ppc.c (call_check_done): Define.
(ppc64_elf_add_symbol_hook): Substitute bfd_get_section_name macro.
(ppc64_elf_check_relocs, ppc64_elf_size_dynamic_sections): Likewise.
(ppc64_elf_finish_multitoc_partition): Remove unnecessary check.
(toc_adjusting_stub_needed): Use call_check_done rather than toc_off.
Simplify return logic. Iterate over all .init and .fini fragments
by recursion. Set makes_toc_func_call here..
(ppc64_elf_next_input_section): ..rather than here.
(check_pasted_section, ppc64_elf_check_init_fini): New functions.
ld/
PR ld/11378
* emultempl/ppc64elf.em (gld${EMULATION_NAME}_after_allocation): Call
ppc64_elf_check_init_fini and warn if .init/.fini use different TOCs.
* elf64-ppc.c (struct plt_entry): Move earlier in file.
(struct got_entry): Likewise. Add is_indirect and got.ent fields.
(struct ppc64_elf_obj_tdata): Change tlsld_got to be a struct got_entry.
Update all uses.
(struct ppc_link_hash_table): Add got_reli_size and second_toc_pass.
Remove no_multi_toc.
(update_local_sym_info, ppc64_elf_check_relocs): Clear is_indirect
when allocating a new struct got_entry.
(allocate_got): New function, extracted from..
(allocate_dynrelocs): ..here. Abort on got entry in non-ppc64 bfd.
(ppc64_elf_size_dynamic_sections): Track got relocs allocated in
.reliplt by got_reli_size. Set owner on ppc64_tlsld_got entries.
(ppc64_elf_setup_section_lists): Remove output_bfd param and
no_multi_toc, add add_stub_section and layout_sections_again. Stash
new params in htab. Extract some code to..
(ppc64_elf_start_multitoc_partition): ..here. New function.
(ppc64_elf_next_toc_section): Check for linker script errors. Handle
second pass toc scan.
(merge_got_entries, merge_global_got, reallocate_got): New functions.
(ppc64_elf_reinit_toc): Rename to..
(ppc64_elf_finish_multitoc_partition): ..this.
(ppc64_elf_layout_multitoc): New function.
(ppc64_elf_size_stubs): Delete output_bfd, add_stub_section and
layout_sections_again params.
(ppc64_elf_relocate_section): Handle indirect got entries.
* elf64-ppc.h: Update prototypes. Declare new functions.
ld/
* emultempl/ppc64elf.em (build_toc_list): Report errors from
ppc64_elf_next_toc_section.
(after_allocation): Update for changed function names and params.
Run second pass of multitoc partitioning.
PR 5604
* elf-bfd.h (struct elf_backend_data): Add gc_keep. Remove param
names from others.
(_bfd_elf_gc_keep): Declare.
* elfxx-target.h (elf_backend_gc_keep): Define.
(elfNN_bed): Init new field.
* elflink.c (_bfd_elf_gc_keep): New function.
(bfd_elf_gc_sections): Call gc_keep.
* elf64-ppc.c (elf_backend_gc_keep): Define.
(struct _ppc64_elf_section_data): Move .opd related fields to
a struct so they don't occupy the same storage. Adjust accesses
throughout file.
(ppc64_elf_gc_keep): New function, split out from..
(ppc64_elf_gc_mark_hook): ..here. Don't call _bfd_elf_gc_mark
to mark .opd section, just set gc_mark.
(ppc64_elf_edit_opd): Remove no_opd_opt parm. Don't set opd->adjust
unless we are changing .opd. Test non-NULL opd->adjust at all
accesses throughout file.
* elf64-ppc.h (ppc64_elf_edit_opd): Update prototype.
ld/
PR 5604
* ldlang.c (lang_gc_sections): Move code to set SEC_KEEP on entry
syms to _bfd_elf_gc_keep.
* emultempl/ppc64elf.em (ppc_before_allocation): Don't call
ppc64_elf_edit_opd if no_opd_opt.
* elf-bfd.h (_bfd_elf_gc_mark): Declare.
* elflink.c (elf_link_input_bfd): Formatting.
(_bfd_elf_gc_mark): Rename from elf_gc_mark and make global. Adjust
all callers.
* elf64-ppc.c (struct ppc_link_hash_entry): Remove is_entry.
(link_hash_newfunc): Don't set it.
(ppc64_elf_copy_indirect_symbol): Nor copy it.
(ppc64_elf_mark_entry_syms): Delete.
(ppc64_elf_gc_mark_hook): Mark entry syms here. Also mark opd
sections. Use get_opd_info.
* elf64-ppc.h (ppc64_elf_mark_entry_syms): Delete.
ld/
* emultempl/ppc64elf.em (ppc_after_open): Delete.
(LDEMUL_AFTER_OPEN): Don't define.
(ppc64_elf_next_input_section): Use it here to set has_gp_reloc.
Return error condition.
(ppc64_elf_size_stubs): Restrict toc adjusting stubs to sections
that have has_gp_reloc set.
(struct ppc_link_hash_table): Add stub_count.
(ppc_build_one_stub): Increment it.
(ppc64_elf_link_hash_table_create): zmalloc rather than clearing
individual fields.
* elf64-ppc.h (ppc64_elf_next_input_section): Update prototype.
(TLS_GD): ..define this instead and update all uses.
(TLS_TPRELGD): Define.
(ppc64_elf_link_hash_table_create): Tweak initialization of
init_refcount and init_offset.
(ppc64_elf_check_relocs): Add one extra element to t_symndx array.
Mark second slot of GD or LD toc entries.
(get_tls_type): Return an int. Distinguish toc GD and LD entries
from other tls types.
(ppc64_elf_tls_setup): New function, split out from..
(ppc64_elf_tls_optimize): ..here. Don't optimize when symbols are
defined in a dynamic object. Fix LD optimization. Don't set TLS_TPREL
on GD->IE optimization, use TLS_TPRELGD instead. Use get_tls_type
return value to properly decide whether toc GD and LD entries can
optimize away __tls_get_addr call. Check next reloc after DTPMOD64
to determine GD or LD rather than looking at TLS_LD flag. Don't
attempt to adjust got entry tls_type here..
(allocate_dynrelocs): ..instead, adjust got entry tls_type here, and
look for possible merges.
(ppc64_elf_size_dynamic_sections): Adjust local got entries for
optimization.
(ppc64_elf_size_stubs): Tweak __tls_get_addr fudge.
(ppc64_elf_relocate_section): Rename some vars to better reflect usage.
Make use of return value from get_tls_type to properly detect GD and
LD optimizations. Split tlsld/gd hi/ha from lo/ds case. Don't
handle tls_get_addr removal when looking at REL24 relocs, do it when
looking at the previous reloc. Check reloc after DTPMOD64 to determine
GD or LD.
* elf64-ppc.h (ppc64_elf_tls_setup): Declare.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.
* elf64-ppc.c (TP_OFFSET, DTP_OFFSET): Declare.
(ppc64_elf_howto_raw): Add TLS howto's. Adjust R_PPC64_NONE to be
against a 32 bit field.
(ppc64_elf_reloc_type_lookup): Handle TLS relocs.
(_ppc64_elf_section_data): Add t_symndx and comments.
(ppc64_elf_section_data): Use elf_section_data macro.
(ppc64_elf_new_section_hook): American spelling.
(struct got_entry, struct plt_entry): New.
(MUST_BE_DYN_RELOC): Rename from IS_ABSOLUTE_RELOC.
(struct ppc_stub_hash_entry): Add "addend" field.
(struct ppc_link_hash_entry): Add "tls_type".
(TLS_TLS, TLS_GD_LD, TLS_LD, TLS_TPREL, TLS_DTPREL,
TLS_EXPLICIT): Define.
(struct ppc_link_hash_table): Add tls_sec, tls_get_addr, tlsld_got.
(link_hash_newfunc): Init new fields.
(ppc64_elf_link_hash_table_create): Likewise. Set init_relcount and
init_offset to NULL.
(ppc64_elf_copy_indirect_symbol): Copy got and plt info. Don't call
_bfd_elf_link_hash_copy_indirect, rather insert relevant code from
there.
(update_local_sym_info, update_plt_info): New functions.
(ppc64_elf_check_relocs): Use them. Handle TLS relocs. Adjust GOT
handling to use got.glist rather than got.refcount. Likewise for PLT.
(ppc64_elf_gc_sweep_hook): Handle TLS relocs, new GOT and PLT lists.
(func_desc_adjust): Adjust for new PLT list.
(ppc64_elf_adjust_dynamic_symbol): Likewise.
(get_sym_h, get_tls_type): New functions.
(ppc64_elf_edit_opd): Remove unused variable. Use get_sym_h.
(ppc64_elf_tls_optimize): New function.
(allocate_dynrelocs): Adjust for new PLT and GOT lists. Allocate
TLS relocs.
(ppc64_elf_size_dynamic_sections): Likewise.
(ppc_type_of_stub): Adjust for new PLT list.
(ppc_build_one_stub): Likewise.
(ppc64_elf_size_stubs): Likewise. Use get_sym_h. Treat __tls_get_addr
calls specially.
(ppc64_elf_relocate_section): Adjust for new GOT and PLT lists. Handle
TLS relocs. Report local syms using bfd_elf_local_sym_name. Don't
init GOT entries that have a reloc. Generate GOT relocs here..
(ppc64_elf_finish_dynamic_symbol): ..not here. Adjust for PLT list.
* elf64-ppc.h (ppc64_elf_tls_optimize): Declare.
relocatable link too.
(elf_link_input_bfd): When emitting relocs, adjust offsets for
eh_frame and stab sections. Zap deleted relocs.
(elf_reloc_symbol_deleted_p): Return true for zero r_symndx.
(elf_bfd_discard_info): Run for relocatable link too.
* elf64-ppc.c (ppc64_elf_edit_opd): Rename from edit_opd. Make global.
Handle ld -r case.
(ppc64_elf_size_dynamic_sections): Don't call edit_opd from here.
* elf64-ppc.h (ppc64_elf_edit_opd): Declare.
(ppc64_elf_ha_reloc): New function.
(ppc64_elf_brtaken_reloc): New function.
(ppc64_elf_sectoff_reloc): New function.
(ppc64_elf_sectoff_ha_reloc): New function.
(ppc64_elf_toc_reloc): New function.
(ppc64_elf_toc_ha_reloc): New function.
(ppc64_elf_toc64_reloc): New function.
(ppc64_elf_unhandled_reloc): New function.
(ppc64_elf_howto_raw): Use the above.
<R_PPC64_RELATIVE>: Mark pc_relative, pcrel_offset.
<R_PPC64_SECTOFF>: Not pc_relative or pcrel_offset. Fix dst_mask.
<R_PPC64_SECTOFF_DS>: Likewise.
(IS_ABSOLUTE_RELOC): Update.
(struct ppc_link_hash_table): Add have_undefweak.
(ppc64_elf_link_hash_table_create): Init.
(func_desc_adjust): Set have_undefweak.
(ppc64_elf_func_desc_adjust): Call func_desc_adjust earlier. Only
add the .sfpr blr when have_undefweak.
(ppc64_elf_setup_section_lists): Check hash table flavour.
(ppc64_elf_next_input_section): Move output_section->owner test to
ppc64elf.em.
(ppc64_elf_set_toc): Rename to ppc64_elf_toc, remove info param
and relocatable test. Return TOCstart and don't set elf_gp.
(ppc64_elf_relocate_section): Correct BRTAKEN/BRNTAKEN branch
offset calculation. Add assert on weak sym branch tweaks.
* elf64-ppc.h (ppc64_elf_set_toc): Delete.
(ppc64_elf_toc): Declare.
(ppc64_elf_next_input_section): Update.
* emultempl/ppc64elf.em (gld${EMULATION_NAME}_after_allocation):
Adjust for ppc64_elf_set_toc change. #include libbfd.h.
(build_section_lists): Do output_section tests here.
(ppc64_elf_relocate_section): Use them. Don't look for plt calls
on R_PPC64_ADDR24 relocs. Require a nop or no link reg on plt
call branches. Correct undefined weak destination.
(ppc64_elf_func_desc_adjust): Always create at least one blr in
.sfpr, and correct case where either only savef* or restf* is
needed.
Long branch stubs, multiple stub sections.
* elf64-ppc.h (ppc64_elf_setup_section_lists): Declare.
(ppc64_elf_next_input_section): Declare.
* elf64-ppc.c: Move linker-only prototypes.
(STUB_SUFFIX): Define.
(enum ppc_stub_type): New.
(struct ppc_stub_hash_entry): New.
(struct ppc_branch_hash_entry): New.
(struct ppc_link_hash_entry): Add stub_cache, oh.
(struct ppc_link_hash_table): Add stub_hash_table etc. Remove
sstub. Add sbrlt, srelbrlt, has_14bit_branch, stub_iteration.
Rename plt_overflow to stub_error.
(ppc_stub_hash_lookup): Define.
(ppc_branch_hash_lookup): Define.
(stub_hash_newfunc): New function.
(branch_hash_newfunc): New function.
(link_hash_newfunc): Init new fields.
(ppc64_elf_link_hash_table_create): Likewise.
(ppc64_elf_link_hash_table_free): New function.
(ppc_stub_name): New function.
(ppc_get_stub_entry): New function.
(ppc_add_stub): New function.
(create_linkage_sections): Use bfd_make_section_anyway. Create
.branch_lt and .rela.branch_lt sections. Don't create .stub.
(ppc64_elf_check_relocs): Set has_14bit_branch on R_PPC64_REL14*,
and set up for plt call stubs. Link func and func desc syms.
(ppc64_elf_gc_sweep_hook): Handle REL14* as per REL24.
(func_desc_adjust): Avoid hash lookup when func desc sym available
via shortcut, and set links when processing.
(ppc64_elf_hide_symbol): Likewise.
(allocate_dynrelocs): Don't allocate stub section here.
(ppc64_elf_size_dynamic_sections): Handle sbrlt and srelbrlt.
Remove sstub code.
(ppc_type_of_stub): New function.
(build_one_stub): Delete.
(ppc_build_one_stub): New function.
(ppc_size_one_stub): New function.
(ppc64_elf_setup_section_lists): New function.
(ppc64_elf_next_input_section): New function.
(group_sections): New function.
(get_local_syms): New function.
(ppc64_elf_size_stubs): Rewrite.
(ppc64_elf_build_stubs): Rewrite.
(ppc64_elf_relocate_section): Look up stub entry for REL24
relocs. Don't propagate REL14* to dynamic objects. Look for long
branch stubs if REL14* or REL24 relocs won't reach.
(bfd_elf64_bfd_link_hash_table_free): Define.