Age | Commit message (Collapse) | Author | Files | Lines |
|
We were attempting to set a BSS style section contents.
PR 29542
* powerpc.cc (Output_data_plt_powerpc::do_write): Don't set .plt,
.iplt or .lplt section contents when position independent.
|
|
Prior to the inline plt call support (commit 08be322439), the only
local syms with plt entries were local ifunc symbols. There shouldn't
be stubs for other local symbols so don't look for them. The patch
also fixes minor bugs in get_reference_flags; Many relocs are valid
only for ppc64 and a couple only for ppc32.
PR 29462
* powerpc.cc (Target_powerpc::Relocate::relocate): Rename
use_plt_offset to pltcal_to_direct, invert logic. For relocs
not used with inline plt sequences against local symbols, only
look for stubs when the symbol is an ifunc.
(Target_powerpc::Scan::get_reference_flags): Correct reloc
handling for relocs not valid for both 32-bit and 64-bit.
|
|
The result of running etc/update-copyright.py --this-year, fixing all
the files whose mode is changed by the script, plus a build with
--enable-maintainer-mode --enable-cgen-maint=yes, then checking
out */po/*.pot which we don't update frequently.
The copy of cgen was with commit d1dd5fcc38ead reverted as that commit
breaks building of bfp opcodes files.
|
|
Gold version of commit 7aba54da42.
elfcpp/
* powerpc.h (R_PPC64_REL24_P9NOTOC): Define.
gold/
* powerpc.cc (Target_powerpc::maybe_skip_tls_get_addr_call,
is_branch_reloc, max_branch_delta): Handle R_PPC64_REL24_P9NOTOC.
(Target_powerpc::Branch_info::make_stub): Likewise.
(struct Plt_stub_ent): Add p9notoc_, p9off_, tsize_.
(struct Branch_stub_ent): Add p9notoc_, p9off_.
(Stub_table::add_plt_call_entry): Handle R_PPC64_REL24_P9NOTOC.
(Stub_table::add_long_branch_entry): Likewise.
(Stub_table::add_eh_frame): Likewise.
(Stub_table::plt_call_size): Return aligned size. Adjust callers.
Handle p9notoc_ sizing.
(Stub_table::do_write): Write out p9notoc_ stubs.
(Target_powerpc::Scan::get_reference_flags, local, global):
Handle R_PPC64_REL24_P9NOTOC.
(Target_powerpc::Relocate::relocate): Likewise.
|
|
The fixes gold failures to handle inline PLT sequences properly.
PowerPC gold was always turning these back into direct calls due to
gsym->use_plt_offset() returning false. This is fixed for dynamic
linking by correcting get_reference_flags, and for static linking by
overriding use_plt_offset() in relocate(). The rest of the patch
revolves around needing to create PLT entries for inline PLT calls
when statically linking (for gcc -mlongcall). The lplt section
handled that for local symbols, now it does globals too.
* powerpc.cc (Target_powerpc::plt_off): Return proper section
for static link.
(Target_powerpc::symval_for_branch): Make public.
(Target_powerpc::make_lplt_section): Add Symbol_table* param.
Adjust all calls.
(Target_powerpc::make_local_plt_entry): Likewise.
(Target_powerpc::make_local_plt_entry): New variant for global syms.
(Powerpc_relobj::do_relocate_sections): Don't write lplt contents.
(Output_data_plt_powerpc::do_write): Write lplt contents here.
(Output_data_plt_powerpc::Output_data_plt_powerpc): Save
symbol table pointer. Adjust all uses.
(Output_data_plt_powerpc::add_entry): Add stash parameter. Don't
do dynamic reloc handling when no reloc section. Save symbol
for local plt entries.
(Output_data_plt_powerpc::add_local_entry): Save symbol.
(Output_data_plt_powerpc::Local_plt_ent): New class.
(Output_data_plt_powerpc::sym_ents_): New vector.
(Target_powerpc::Scan::get_reference_flags): Return
FUNCTION_CALL|RELATIVE_REF for inline plt relocs.
(Target_powerpc::Scan::global): Make entries in lplt for inline
plt call relocation symbols.
(Target_powerpc::Relocate::relocate): Rename has_plt_offset to
use_plt_offset. Set use_plt_offset for inline plt relocs.
|
|
My previous PR27625 patch had a problem or two. For one, the error
"__tls_get_addr call lacks marker reloc" on processing some calls
before hitting a call without markers typically isn't seen. Instead a
gold assertion fails. Either way it would be a hard error, which
triggers on a file contained in libphobos.a when running the gcc
testsuite. A warning isn't even appropriate since the call involved
is one built by hand without any of the arg setup relocations that
might result in linker optimisation.
So this patch reverts most of commit 0af4fcc25dd5, instead entirely
ignoring the problem of mis-optimising old-style __tls_get_addr calls
without marker relocs. We can't handle them gracefully without
another pass over relocations before decisions are made about GOT
entries in Scan::global or Scan::local. That seems too costly, just
to link object files from 2009. What's more, there doesn't seem to be
any way to allow the libphobos explicit __tls_get_addr call, but not
old TLS sequences without marker relocs. Examining instructions
before the __tls_get_addr call is out of the question: program flow
might reach the call via a branch. Putting an R_PPC64_TLSGD marker
with zero sym on the call might be a solution, but current linkers
will then merrily optimise away the call!
PR gold/27625
* powerpc.cc (Powerpc_relobj): Delete no_tls_marker_, tls_marker_,
and tls_opt_error_ variables and accessors. Remove all uses.
|
|
We can't get at section->address() until everything is laid out, so
trying to generalise the offset calculation rather than using a value
of 0x8000 (the old object->toc_base_offset()) was bound to fail.
got->g_o_t() is a little better than a hard-coded 0x8000.
* powerpc.cc (Target_powerpc::Scan::local, global): Don't use
toc_pointer() here.
|
|
Split .got into two piece, one with the header and entries for small
model got entries, the other with entries for medium/large model got
entries. The idea is to better support mixed pcrel/non-pcrel code
where non-pcrel small-model .toc entries need to be within 32k of the
toc pointer.
* target.h (Target::tls_offset_for_local): Add got param.
(Target::tls_offset_for_global): Likewise.
(Target::do_tls_offset_for_local, do_tls_offset_for_global): Likewise.
* output.h (Output_data_got::Got_entry::write): Add got param.
* output.cc (Output_data_got::Got_entry::write): Likewise, pass to
tls_offset_for_local/global calls.
(Output_data_got::do_write): Adjust to suit.
* s390.cc (Target_s390::do_tls_offset_for_local): Likewise.
(Target_s390::do_tls_offset_for_global): Likewise.
* powerpc.cc (enum Got_type): Extend with small types, move from
class Target_powerpc.
(Target_powerpc::biggot_): New.
(Traget_powerpc::do_tls_offset_for_local, do_tls_offset_for_global,
got_size, got_section, got_base_offset): Handle biggot_.
(Target_powerpc::do_define_standard_symbols): Adjust.
(Target_powerpc::make_plt_section, do_finalize_sections): Likewise.
(Output_data_got_powerpc::Output_data_got_powerpc): Only make
64-bit header for small got section.
(Output_data_got_powerpc::g_o_t): Only return a result for small
got section.
(Output_data_got_powerpc::write): Only write small got section
header.
(Target_powerpc::Scan::local, global): Select small/big Got_type
and section to suit reloc.
(Target_powerpc::Relocate::relocate): Similarly.
(Sort_toc_sections): Rewrite.
|
|
Code in powerpc.cc is pretending to support a per-object toc pointer
value, but powerpc gold has no real support for multi-toc. This patch
removes the pretense, tidying quite a lot in preparation for a
followup patch. If multi-toc is ever to be supported, don't revert
this patch but start by adding object parameter to toc_pointer() and
an object to Branch_stub_key.
* powerpc.cc (Powerpc_relobj::toc_base_offset): Delete.
(Target_powerpc::toc_pointer): New function. Use throughout.
(Target_powerpc::got_base_offset): New function. Use throughout..
(Output_data_got_powerpc::got_base_offset): ..in place of
this. Delete.
(Output_data_got_powerpc::Output_data_got_powerpc): Init
header_index_ to -1u for 64-bit, and make header here.
(Output_data_got_powerpc::set_final_data_size, reserve_ent): Don't
make 64-bit header here.
(Output_data_got_powerpc::g_o_t): Return toc pointer offset in
section for 64-bit. Use throughout.
(Stub_table): Remove toc_base_off_ from Branch_stub_key, and
object param on add_long_branch_entry and find_long_branch_entry.
Adjust all uses.
|
|
Pass addends to all the GOT handling functions, plus remove some
extraneous asserts.
PR 28192
* powerpc.cc (Output_data_got_powerpc): Add addend parameter to
all methods creating got entries.
(Target_powerpc::Scan::local): Pass reloc addend to got handling
functions, and when creating dynamic got relocations.
(Target_powerpc::Scan::global): Likewise.
(Target_powerpc::Relocate::relocate): Likewise. Remove extraneous
assertions.
|
|
This takes care of writing out GOT entries with addends. The local
symbol case was already largely handled, except for passing the addend
to tls_offset_for_local which might need the addend in a
local_got_offset call. That's needed also in tls_offset_for_global.
I'm assuming here that GOT entries for function symbols won't ever
have addends, and in particular that a GOT entry referencing PLT call
stub code won't want an offset into the code.
PR 28192
* output.cc (Output_data_got::Got_entry::write): Include addend
in global symbol value. Pass addend to tls_offset_for_*.
* powerpc.cc (Target_powerpc::do_tls_offset_for_local): Handle addend.
(Target_powerpc::do_tls_offset_for_global): Likewise.
* s390.cc (Target_s390::do_tls_offset_for_local): Likewise.
(Target_s390::do_tls_offset_for_global): Likewise.
* target.h (Target::tls_offset_for_local): Add addend param.
(Target::tls_offset_for_global): Likewise.
(Target::do_tls_offset_for_local): Likewise.
(Target::do_tls_offset_for_global): Likewise.
|
|
Fixes a silly mistake in calculating the address of -Os out-of-line
register save/restore function copies. Copies of these linker defined
functions are added to stub sections when the original (in
target->savres_section) can't be reached.
* powerpc.cc (Target_powerpc::Relocate::relocate): Correct address
calculation of out-of-line save/restore function copies.
|
|
This patch supports linking powerpc64 glibc with gold, specifically
the __tls_get_addr call in elf/dl-sym.c. That call lacks marker
relocations tying it to the arg setup instructions, but the arg setup
insns are also contructed lacking the usual relocations on a Global
Dynamic TLS code sequence. So there is no chance that anything in
that sequence might be wrongly edited by the linker.
In fact, the aim of linking glibc could have been supported by simply
omitting the error whenever TLS optimisation is disabled, as it is
when linking a shared library. The patch goes further than that,
disabling TLS GD and LD sequence optimisation on a per-object basis
for object files lacking marker relocs.
PR gold/27625
* powerpc.cc (Powerpc_relobj): Add no_tls_marker_, tls_marker_,
and tls_opt_error_ variables and accessors.
(Target_powerpc::Scan::local, global): Call set_tls_marker and
set_no_tls_marker for GD and LD code sequence relocations.
(Target_powerpc::Relocate::relocate): Downgrade the "lacks marker
reloc" error to a warning when safe to do so, and omit the error
entirely if not optimising TLS sequences. Do not optimise GD and
LD sequences for objects lacking marker relocs.
(Target_powerpc::relocate_relocs): Heed no_tls_marker here too.
|
|
A testcase with only ifuncs can result in no plt section (ifunc plt
entries might instead be in iplt), which means we can get to this code
without a static link.
PR 27203
* powerpc.cc (do_plt_fde_location): Remove doing_static_link
assertion.
|
|
This fixes a thinko in commit fa40fbe4849. st_other global entry bits
are relevant only for 64-bit ELFv2. PowerPC gold leaves local sym
vector of st_other bits as NULL for 32-bit, hence the segfault.
PR 27140
* powerpc.cc (Target_powerpc::Branch_info::make_stub): Only access
object->st_other() when 64-bit.
(Stub_table::add_long_branch_entry): Ignore "other" when 32-bit.
|
|
|
|
incremental-dump wants to instantiate Target_powerpc without options
being set up. This patch fixes
internal error in options, at gold/parameters.h:92
* powerpc.cc (Target_powerpc::no_tprel_opt_): Rename from tprel_opt_.
Init to false.
(Target_powerpc::tprel_opt): Test parameters->options().tls_optimize().
(Target_powerpc::set_tprel_opt): Delete.
(Target_powerpc::set_no_tprel_opt): New function. Update all uses
of set_tprel_opt.
|
|
PR 26902
* powerpc.cc (Relocate::relocate): Do not include local entry
offset of target function when computing the address of a stub.
|
|
* powerpc.cc (Target_powerpc::tocsave_loc): Return a pointer.
(Target_powerpc::Relocate::relocate): Avoid -Wdangling-gsl error.
|
|
Calling non-pcrel functions from pcrel code requires a stub to set up
r2. Gold created the stub, but an "optimisation" made the stub jump
to the function local entry, ie. r2 was not initialised.
This patch fixes that long branch stub problem, and another that might
occur for plt call stubs to local functions.
bfd/
* elf64-ppc.c (write_plt_relocs_for_local_syms): Don't do local
entry offset optimisation.
gold/
* powerpc.cc (Powerpc_relobj::do_relocate_sections): Don't do
local entry offset optimisation for lplt_section.
(Target_powerpc::Branch_info::make_stub): Don't add local
entry offset to long branch dest passed to
add_long_branch_entry. Do pass st_other bits.
(Stub_table::Branch_stub_ent): Add "other_" field.
(Stub_table::add_long_branch_entry): Add "other" param, and
save.
(Stub_table::branch_stub_size): Adjust long branch offset.
(Stub_table::do_write): Likewise.
(Target_powerpc::Relocate::relocate): Likewise.
|
|
GOT relocations can refer directly to a function in a fixed position
executable, unlike ADDR64 which needs a global entry stub, or branch
relocs, which need PLT stubs.
* powerpc.cc (is_got_reloc): New function.
(Target_powerpc::Relocate::relocate): Use it here, exclude GOT
relocs when looking for stubs.
|
|
Gold version of commit 3cd7c7d7ef.
* powerpc.cc (Target_powerpc): Rename power10_stubs_ to
power10_relocs_.
(Target_powerpc::set_power10_relocs): New accessor.
(Target_powerpc::set_power10_stubs): Delete.
(Target_powerpc::power10_stubs): Adjust.
(Target_powerpc::has_localentry0): New accessor.
(ld_0_11): New constant.
(glink_eh_frame_fde_64v1, glink_eh_frame_fde_64v2): Adjust.
(glink_eh_frame_fde_64v2_localentry0): New.
(Output_data_glink::pltresolve_size): Update.
(Output_data_glink::add_eh_frame): Use localentry0 version eh_frame.
(Output_data_glink::do_write): Move r2 save to start of ELFv2 stub
and only emit for has_localentry0. Don't use r2 in the stub.
(Target_powerpc::Scan::local, global): Adjust for
set_power10_relocs renaming.
(Target_powerpc::scan_relocs): Warn and reset plt_localentry0_.
|
|
This stub doesn't have the r2 store at the beginning.
* powerpc.cc (Target_powerpc::Relocate::relocate): Don't skip
first insn of __tls_get_addr_opt stub.
|
|
ppc64 ld optimises sequences like the following
addis 3,13,wot@tprel@ha
lwz 3,wot@tprel@l(3)
to
nop
lwz 3,wot@tprel(13)
when "wot" is located near enough to the thread pointer.
However, the ABI doesn't require that R_PPC64_TPREL16_HA always be on
an addis rt,13,imm instruction, and while ld checked for that on the
high-part instruction it didn't disable the optimisation on the
low-part instruction. This patch fixes that problem, disabling the
tprel optimisation globally if high-part instructions don't pass
sanity checks. The optimisation is also enabled for ppc32, where
before ld.bfd had the code in the wrong place and ld.gold had it in a
block only enabled for ppc64.
bfd/
* elf32-ppc.c (ppc_elf_check_relocs): Set has_tls_reloc for
high part tprel16 relocs.
(ppc_elf_tls_optimize): Sanity check high part tprel16 relocs.
Clear do_tls_opt on odd instructions.
(ppc_elf_relocate_section): Move TPREL16_HA/LO optimisation later.
Don't sanity check them here.
* elf64-ppc.c (ppc64_elf_check_relocs): Set has_tls_reloc for
high part tprel16 relocs.
(ppc64_elf_tls_optimize): Sanity check high part tprel16 relocs.
Clear do_tls_opt on odd instructions.
(ppc64_elf_relocate_section): Don't sanity check TPREL16_HA.
ld/
* testsuite/ld-powerpc/tls32.d: Update for TPREL_HA/LO optimisation.
* testsuite/ld-powerpc/tlsexe32.d: Likewise.
* testsuite/ld-powerpc/tlsldopt32.d: Likewise.
* testsuite/ld-powerpc/tlsmark32.d: Likewise.
* testsuite/ld-powerpc/tlsopt4_32.d: Likewise.
* testsuite/ld-powerpc/tprel.s,
* testsuite/ld-powerpc/tprel.d,
* testsuite/ld-powerpc/tprel32.d: New tests.
* testsuite/ld-powerpc/tprelbad.s,
* testsuite/ld-powerpc/tprelbad.d: New test.
* testsuite/ld-powerpc/powerpc.exp: Run them.
gold/
* powerpc.cc (Target_powerpc): Add tprel_opt_ and accessors.
(Target_powerpc::Scan::local): Sanity check tprel high relocs.
(Target_powerpc::Scan::global): Likewise.
(Target_powerpc::Relocate::relocate): Control tprel optimisation
with tprel_opt_ and enable for 32-bit.
|
|
gold version of commit e10a07b32dc1.
* options.h (DEFINE_enum): Add optional_arg__ param, adjust
all uses.
(General_options): Add --power10-stubs and --no-power10-stubs.
* options.cc (General_options::finalize): Handle --power10-stubs.
* powerpc.cc (set_power10_stubs): Don't set when --power10-stubs=no.
(power10_stubs_auto): New.
(struct Plt_stub_ent): Add toc_ and tocoff_. Don't use a bitfield
for indx_.
(struct Branch_stub_ent): Add toc_and tocoff_. Use bitfields for
iter_, notoc_ and save_res_.
(add_plt_call_entry): Set toc_. Adjust resizing conditions for
--power10-stubs=auto.
(add_long_branch_entry): Set toc_.
(add_eh_frame, define_stub_syms): No longer use const_iterators
for plt and long branch stub iteration.
(build_tls_opt_head, build_tls_opt_tail): Change parameters and
return value. Move tests for __tls_get_addr to callers.
(plt_call_size): Handle --power10-stubs=auto.
(branch_stub_size): Likewise.
(Stub_table::do_write): Likewise.
(relocate): Likewise.
|
|
These relocations should have had REL in their names, to reflect the
fact that they are pc-relative. Fix that now by adding _PCREL.
I've added some back-compatibility code to support anyone using
.reloc with the old relocations.
include/
* elf/ppc64.h (elf_ppc64_reloc_type): Rename
R_PPC64_GOT_TLSGD34 to R_PPC64_GOT_TLSGD_PCREL34,
R_PPC64_GOT_TLSLD34 to R_PPC64_GOT_TLSLD_PCREL34,
R_PPC64_GOT_TPREL34 to R_PPC64_GOT_TPREL_PCREL34, and
R_PPC64_GOT_DTPREL34 to R_PPC64_GOT_DTPREL_PCREL34.
bfd/
* reloc.c: Rename
BFD_RELOC_PPC64_GOT_TLSGD34 to BFD_RELOC_PPC64_GOT_TLSGD_PCREL34,
BFD_RELOC_PPC64_GOT_TLSLD34 to BFD_RELOC_PPC64_GOT_TLSLD_PCREL34,
BFD_RELOC_PPC64_GOT_TPREL34 to BFD_RELOC_PPC64_GOT_TPREL_PCREL34,
BFD_RELOC_PPC64_GOT_DTPREL34 to BFD_RELOC_PPC64_GOT_DTPREL_PCREL34.
* elf64-ppc.c: Update throughout for reloc renaming.
(ppc64_elf_reloc_name_lookup): Handle old reloc names.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.
gas/
* config/tc-ppc.c: Update throughout for reloc renaming.
elfcpp/
* powerpc.h: Rename
R_PPC64_GOT_TLSGD34 to R_PPC64_GOT_TLSGD_PCREL34,
R_PPC64_GOT_TLSLD34 to R_PPC64_GOT_TLSLD_PCREL34,
R_PPC64_GOT_TPREL34 to R_PPC64_GOT_TPREL_PCREL34, and
R_PPC64_GOT_DTPREL34 to R_PPC64_GOT_DTPREL_PCREL34.
gold/
* powerpc.cc: Update throughout for reloc renaming.
|
|
PR 25882
bfd/
* elf32-ppc.c (_bfd_elf_ppc_merge_fp_attributes): Don't init FP
attributes from shared libraries, and do not return an error if
they don't match.
gold/
* powerpc.cc (merge_object_attributes): Replace name param with
obj param. Update callers. Don't init FP attributes from shared
libraries, and do not emit an error if they don't match.
|
|
sym->object() could be either a Plugin or Powerpc_relobj. There could
be a situation when Pluginobj would be proccessed in
ppc_object->get_opd_ent(dst_off) as Powerpc_relobj and it leads to the
segmentation fault.
* powerpc.cc (do_gc_mark_symbol): Don't segfault on plugin symbols.
|
|
Now that ISA3.1 is out we can finish with the powerxx silliness.
bfd/
* elf64-ppc.c: Rename powerxx to power10 throughout.
gas/
* config/tc-ppc.c (md_assemble): Update for PPC_OPCODE_POWER10
renaming.
* testsuite/gas/ppc/prefix-align.d: Use -mpower10/-Mpower10 in
place of -mfuture/-Mfuture.
* testsuite/gas/ppc/prefix-pcrel.d: Likewise.
* testsuite/gas/ppc/prefix-reloc.d: Likewise.
gold/
* powerpc.cc: Rename powerxx to power10 throughout.
include/
* elf/ppc64.h: Update comment.
* opcode/ppc.h (PPC_OPCODE_POWER10): Rename from PPC_OPCODE_POWERXX.
ld/
* testsuite/ld-powerpc/callstub-1.d: Use -mpower10/-Mpower10 in
place of -mfuture/-Mfuture.
* testsuite/ld-powerpc/notoc2.d: Likewise.
* testsuite/ld-powerpc/powerpc.exp: Likewise.
* testsuite/ld-powerpc/tlsgd.d: Likewise.
* testsuite/ld-powerpc/tlsie.d: Likewise.
* testsuite/ld-powerpc/tlsld.d: Likewise.
opcodes/
* ppc-dis.c (ppc_opts): Add "power10" entry.
(print_insn_powerpc): Update for PPC_OPCODE_POWER10 renaming.
* ppc-opc.c (POWER10): Rename from POWERXX. Update all uses.
|
|
|
|
This patch corrects the set of dynamic relocations recognised by gold
as supported by glibc, and teaches ld.bfd to report an error similar
to the gold error. Note that ld --noinhibit-exec can be used to
produce an output, supporting older ld with newer glibc if the set of
supported glibc dynamic relocations changes.
bfd/
* elf64-ppc.c (ppc64_glibc_dynamic_reloc): New function.
(ppc64_elf_relocate_section): Error if emitting unsupported
dynamic relocations.
gold/
* powerpc.cc (Target_powerpc::Scan::check_non_pic): Move REL24
to 32-bit supported.
|
|
Gold version of git commit c213164ad2.
elfcpp/
* powerpc.h (R_PPC64_TPREL34, R_PPC64_DTPREL34),
(R_PPC64_GOT_TLSGD34, R_PPC64_GOT_TLSLD34),
(R_PPC64_GOT_TPREL34, R_PPC64_GOT_DTPREL34): Define.
gold/
* powerpc.cc (Target_powerpc::Scan::get_reference_flags): Set
flags for new relocations, and some missing older relocs.
(Target_powerpc::Scan::local): Handle new pcrel tls relocs.
Call set_has_static_tls for tprel relocs.
(Target_powerpc::Scan::global): Likewise.
(Target_powerpc::Relocate::relocate): Handle new pcrel tls relocs.
|
|
Relocations with right shifts were calculating wrong overflow status.
Since the addr34 split-field reloc is implemented as an 18-bit high
part with value shifted right by 16 and a 16-bit low part, most of the
pc-relative relocs were affected.
* powerpc.cc (Powerpc_relocate_functions::rela, rela_ua): Perform
signed right shift for signed overflow check.
|
|
* powerpc.cc (xlate_pcrel_opt): New function.
(Target_powerpc::Relocate::relocate): Optimise PCREL34 and
GOT_PCREL34 sequences marked with PCREL_OPT.
|
|
Note that gold won't remove unused GOT entries, in contrast to ld.bfd
which will.
* powerpc.cc (Powerpc_relobj::make_got_relative): New function.
(relative_value_is_known): New functions.
(Target_powerpc::Relocate::relocate): Edit code using
GOT16_HA, GOT16_LO_DS, and GOT_PCREL34 relocs.
|
|
Also use pc-relative instructions for notoc stubs.
elfcpp/
* powerpc.h (R_PPC64_PCREL_OPT, R_PPC64_D34, R_PPC64_D34_LO),
(R_PPC64_D34_HI30, R_PPC64_D34_HA30, R_PPC64_PCREL34),
(R_PPC64_GOT_PCREL34, R_PPC64_PLT_PCREL34, R_PPC64_PLT_PCREL34_NOTOC),
(R_PPC64_ADDR16_HIGHER34, R_PPC64_ADDR16_HIGHERA34),
(R_PPC64_ADDR16_HIGHEST34, R_PPC64_ADDR16_HIGHESTA34),
(R_PPC64_REL16_HIGHER34, R_PPC64_REL16_HIGHERA34),
(R_PPC64_REL16_HIGHEST34, R_PPC64_REL16_HIGHESTA34),
(R_PPC64_D28, R_PPC64_PCREL28): Define.
gold/
* powerpc.cc (Target_powerpc): Add powerxx_stubs_ and accessor
functions.
(Target_powerpc::maybe_skip_tls_get_addr_call): Handle PLT_PCREL34
and PLT_PCREL34_NOTOC relocs.
(Powerpc_relocate_functions): Add addr34, addr34_hi, addr34_ha,
addr28, addr16_higher34, addr16_highera34, addr16_highest34,
addr16_highest34a functions.
(li_11_0, ori_11_11_0, sldi_11_11_34): Define.
(paddi_12_pc, pld_12_pc, pnop): Define.
(d34, ha34): New inline functions.
(Stub_table::add_plt_call_entry): Handle powerxx_stubs.
(Stub_table::add_eh_frame): Likewise.
(build_powerxx_offset): New function.
(Stub_table::plt_call_size): Handle powerxx_stubs.
(Stub_table::branch_stub_size): Likewise.
(Stub_table::do_write): Likewise.
(Target_powerpc::Scan::get_reference_flags): Handle new relocs.
(Target_powerpc::Scan::reloc_needs_plt_for_ifunc: Likewise.
(Target_powerpc::Scan::local, global, relocate): Likewise.
|
|
When generating notoc call and branch stubs without the benefit of
pc-relative insns, the stubs need to use LR to access the run time PC.
All LR changes must be described in .eh_frame if we're to support
unwinding through asynchronous exceptions. That's what this patch
does.
The patch has gone through way too many iterations. At first I
attempted to add multiple FDEs, one for each stub. That ran into
difficulties with do_plt_fde_location which is only capable of setting
the address of a single FDE per Output_data section, and with removing
any FDEs added on a previous do_relax pass. Removing FDEs (git commit
be897fb774) went overboard in matching the FDE contents. That means
either stashing the contents created for add_eh_frame_for_plt to use
when calling remove_eh_frame_for_plt, or recreating contents on the
fly (*) just to remove FDEs. In fact, FDE content matching is quite
unnecesary. FDEs added by a previous do_relax pass are those with
u_.from_linker.post_map set. So they can easily be recognised just by
looking at that flag. This patch keeps that part of the multiple FDE
changes.
In the end I went for just one FDE per stub group to describe the call
stubs. That's reasonably efficient for the common case of only
needing to describe the __tls_get_addr_opt call stub. We don't expect
to be making many calls using notoc stubs without pc-relative insns.
*) Which has it's own set of problems. The contents must be recreated
using the old stub layout, but .eh_frame size can affect stub
requirements so you need to temporarily keep the old .eh_frame size
when creating new stubs, then reset .eh_frame size before adding new
FDEs.
* ehframe.cc (Fde::operator==): Delete.
(Cie::remove_fde): Delete.
(Eh_frame::remove_ehframe_for_plt): Delete fde_data and fde_length
parameters. Remove all post-map plt FDEs.
* ehframe.h (Fde:post_map): Make const, add variant to compare plt.
(Fde::operator==): Delete.
(Cie::remove_fde): Implement here.
(Cie::last_fde): New accessor.
(Eh_frame::remove_ehframe_for_plt): Update prototype.
* layout.cc (Layout::remove_eh_frame_for_plt): Delete fde_data and
fde_length parameters.
* layout.h (Layout::remove_eh_frame_for_plt): Update prototype.
* powerpc.cc (Stub_table::tls_get_addr_opt_bctrl_): Delete.
(Stub_table::plt_fde_len_, plt_fde_, init_plt_fde): Delete.
(Stub_table::add_plt_call_entry): Don't set tls_get_addr_opt_bctrl_.
(eh_advance): New function.
(stub_sort): New function.
(Stub_table::add_eh_frame): Emit eh_frame for notoc plt calls and
branches as well as __tls_get_addr_opt plt call stub.
(Stub_table::remove_eh_frame): Update to suit.
|
|
Calls from notoc functions via the PLT need different stubs. Even
calls to local functions requiring a valid toc pointer must go via a
stub. This patch provides the support in gold.
elfcpp/
* powerpc.h (R_PPC64_PLTSEQ_NOTOC, R_PPC64_PLTCALL_NOTOC): Define.
gold/
* powerpc.cc (Target_powerpc::maybe_skip_tls_get_addr_call): Handle
notoc calls.
(is_branch_reloc): Template on size. Return true for REL24_NOTOC.
Update all callers.
(max_branch_delta): Likewise.
(Target_powerpc::Branch_info::make_stub): Add a stub for notoc
calls to functions needing a valid toc pointer.
(Target_powerpc::do_relax): Layout stubs again if any need resize.
(add_12_11_12, addi_12_11, addis_12_11, ldx_12_11_12, ori_12_12_0),
(oris_12_12_0, sldi_12_12_32): Define.
(Stub_table::Plt_stub_ent): Add notoc_ and iter_ fields.
(Stub_table::Branch_stub_key, Branch_stub_key_hash): Rename from
Branch_stub_ent and Branch_stub_ent hash. Remove save_res_ from key.
(Stub_table::Branch_stub_ent): New struct.
(class Stub_table): Add need_resize and resizing vars.
(Stub_table::need_resize, branch_size): New accessors.
(Stub_table::set_resizing): New function.
(Stub_table::add_plt_call_entry): Handle notoc calls and resizing
on seeing such or a tocsave stubs after a normal stub using the
same sym.
(Stub_table::add_long_branch_entry): Similarly.
(Stub_table::find_long_branch_entry): Return a Branch_stub_ent*.
(Stub_table::define_stub_syms): Adjust
(Stub_table::build_tls_opt_head, build_tls_opt_tail): New functions.
(build_notoc_offset): New function.
(Stub_table::plt_call_size): Move out of line. Handle notoc calls.
(Stub_table::branch_stub_size): Similarly.
(Stub_table::do_write): Separate loop for ELFv2 stubs, handling
notoc calls. Simplify ELFv1 loop. Output notoc branch stubs.
Use build_tls_opt_head and build_tls_opt_tail.
(Target_powerpc::Scan::get_reference_flags): Handle REL24_NOTOC.
(Target_powerpc::Scan::reloc_needs_plt_for_ifunc): Likewise,
and PLTSEQ_NOTOC and PLTCALL_NOTOC.
(Target_powerpc::Scan::local, global, relocate): Likewise.
|
|
There is a call of relocate() to perform a single relocation. In that
case the "relnum" parameter is -1U and of course it isn't appropriate
to consider any of the PowerPC code sequence optimisations triggered
by a following relocation.
* powerpc.cc (Target_powerpc::Relocate::relocate): Don't look
at next/previous reloc when relnum is -1.
|
|
This fixes a segfault when attempring to output a "linkage table
error". "object" is only non-NULL in the local symbol case.
* powerpc.cc (Stub_table::plt_error): New function.
(Stub_table::do_write): Use it.
(Output_data_glink::do_write): Don't segfault emitting linkage
table error.
|
|
These relocs have been around for quite a while. It's past time gold
supported them.
elfcpp/
* powerpc.h (R_PPC64_REL16_HIGH, R_PPC64_REL16_HIGHA),
(R_PPC64_REL16_HIGHER, R_PPC64_REL16_HIGHERA),
(R_PPC64_REL16_HIGHEST, R_PPC64_REL16_HIGHESTA): Define.
gold/
* powerpc.cc (Target_powerpc::Scan::get_reference_flags): Handle
REL16_HIGH* relocs.
(Target_powerpc::Scan::local): Likewise.
(Target_powerpc::Scan::global): Likewise.
(Target_powerpc::Relocate::relocate): Likewise.
|
|
|
|
elfcpp/
* powerpc.h (Tag_GNU_Power_ABI_FP): Define.
(Tag_GNU_Power_ABI_Vector, Tag_GNU_Power_ABI_Struct_Return): Define.
gold/
* powerpc.cc: Include attributes.h.
(Powerpc_relobj::attributes_section_data_): New variable, with
accessor and associated constructor and destructor support.
(Powerpc_dynobj::attributes_section_data_): Likewise.
(Powerpc_relobj::do_read_symbols): Stash SHT_GNU_ATTRIBUTES section
contents in attributes_section_data_.
(Powerpc_dynobj::do_read_symbols): Likewise.
(Target_powerpc): Add attributes_section_data_, last_fp_, last_ld_,
last_vec_, and last_struct_ vars.
(Target_powerpc::merge_object_attributes): New function.
(Target_powerpc::do_finalize_sections): Iterate over input objects
merging attributes. Create output attributes section.
|
|
In addition to the existing relocs we need two more to mark all
instructions in the call sequence, PLTCALL on the call itself (plus
the toc restore insn for ppc64), and PLTSEQ on others. All
relocations in a particular sequence have the same symbol.
Example ppc64 ELFv2 assembly:
.reloc .,R_PPC64_PLTSEQ,puts
std 2,24(1)
addis 12,2,puts@plt@ha # .reloc .,R_PPC64_PLT16_HA,puts
ld 12,puts@plt@l(12) # .reloc .,R_PPC64_PLT16_LO_DS,puts
.reloc .,R_PPC64_PLTSEQ,puts
mtctr 12
.reloc .,R_PPC64_PLTCALL,puts
bctrl
ld 2,24(1)
Example ppc32 -fPIC assembly:
addis 12,30,puts+32768@plt@ha # .reloc .,R_PPC_PLT16_HA,puts+0x8000
lwz 12,12,puts+32768@plt@l # .reloc .,R_PPC_PLT16_LO,puts+0x8000
.reloc .,R_PPC_PLTSEQ,puts+32768
mtctr 12
.reloc .,R_PPC_PLTCALL,puts+32768
bctrl
Marking sequences like this allows the linker to convert them to nops
and a direct call if the target symbol turns out to be local.
When the call is __tls_get_addr, each relocation shown above is paired
with an R_PPC*_TLSLD or R_PPC*_TLSGD reloc to additionally mark the
sequence for possible TLS optimization. The TLSLD or TLSGD relocs are
emitted first.
include/
* elf/ppc.h (R_PPC_PLTSEQ, R_PPC_PLTCALL): Define.
* elf/ppc64.h (R_PPC64_PLTSEQ, R_PPC64_PLTCALL): Define.
bfd/
* elf32-ppc.c (ppc_elf_howto_raw): Add PLTSEQ and PLTCALL howtos.
(is_plt_seq_reloc): New function.
(ppc_elf_check_relocs): Handle PLTSEQ and PLTCALL relocs.
(ppc_elf_tls_optimize): Handle inline plt call sequence.
(ppc_elf_relax_section): Handle PLTCALL reloc.
(ppc_elf_relocate_section): Nop out inline plt call sequence when
resolving locally.
* elf64-ppc.c (ppc64_elf_howto_raw): Add R_PPC64_PLTSEQ and
R_PPC64_PLTCALL entries. Comment R_PPC64_TOCSAVE.
(has_tls_get_addr_call): Correct comment.
(is_branch_reloc): Add PLTCALL.
(is_plt_seq_reloc): New function.
(ppc64_elf_check_relocs): Handle PLT16_LO_DS reloc. Set
has_tls_reloc for R_PPC64_TLSGD and R_PPC64_TLSLD. Create plt
entry for R_PPC64_PLTCALL.
(ppc64_elf_tls_optimize): Handle inline plt call sequence.
(ppc_type_of_stub): Handle PLTCALL reloc.
(toc_adjusting_stub_needed): Likewise.
(ppc64_elf_relocate_section): Set "can_plt_call" for PLTCALL
reloc insn. Nop out inline plt call sequence when resolving
locally. Handle __tls_get_addr inline plt call optimization.
elfcpp/
* powerpc.h (R_POWERPC_PLTSEQ, R_POWERPC_PLTCALL): Define.
gold/
* powerpc.cc (Target_powerpc::Track_tls::maybe_skip_tls_get_addr_call):
Handle inline plt sequence relocs.
(Stub_table::Plt_stub_key::Plt_stub_key): Likewise.
(Target_powerpc::Scan::reloc_needs_plt_for_ifunc): Likewise.
(Target_powerpc::Relocate::relocate): Likewise.
|
|
Necessary if gcc is to use PLT16 relocs to implement -mlongcall, and
there isn't a good technical reason why local symbols should be
excluded from PLT16 support. Non-ifunc local symbol PLT entries go in
a separate section to other PLT entries. In a fixed position
executable they won't need to be relocated, and in a PIE or shared
library I chose to not implement lazy relocation.
bfd/
* elf64-ppc.c (LOCAL_PLT_ENTRY_SIZE): Define.
(struct ppc_stub_hash_entry): Add symtype field.
(PLT_KEEP): Define.
(struct ppc_link_hash_table): Add pltlocal and relpltlocal.
(create_linkage_sections): Create pltlocal and relpltlocal.
(ppc64_elf_check_relocs): Allow PLT relocs on local symbols.
Set PLT_KEEP.
(ppc64_elf_adjust_dynamic_symbol): Keep PLT entries for inline calls.
(allocate_dynrelocs): Allocate pltlocal and relpltlocal.
(ppc64_elf_size_dynamic_sections): Size pltlocal and relpltlocal.
Keep PLT entries for inline calls against locals.
(ppc_build_one_stub): Use pltlocal as appropriate.
(ppc_size_one_stub): Likewise.
(ppc64_elf_size_stubs): Set symtype.
(build_global_entry_stubs_and_plt): Init pltlocal and write
relpltlocal for globals.
(write_plt_relocs_for_local_syms): Likewise for local syms.
(ppc64_elf_relocate_section): Support PLT for local syms.
* elf32-ppc.c (PLT_KEEP): Define.
(struct ppc_elf_link_hash_table): Add pltlocal and relpltlocal.
(ppc_elf_create_glink): Create pltlocal and relpltlocal.
(ppc_elf_check_relocs): Allow PLT relocs on local symbols.
Set PLT_KEEP. Adjust update_local_sym_info call.
(ppc_elf_adjust_dynamic_symbol): Keep PLT entries for inline calls.
(allocate_dynrelocs): Allocate pltlocal and relpltlocal.
(ppc_elf_size_dynamic_sections): Size pltlocal and relpltlocal.
(ppc_elf_relocate_section): Support PLT16 relocs for local syms.
(write_global_sym_plt): Init pltlocal and write relpltlocal.
(ppc_finish_symbols): Likewise for locals.
ld/
* emulparams/elf32ppc.sh (OTHER_RELRO_SECTIONS_2): Add .branch_lt.
(OTHER_GOT_RELOC_SECTIONS): Add .rela.branch_lt.
* testsuite/ld-powerpc/elfv2so.d: Update for symbol/stub reordering.
* testsuite/ld-powerpc/relbrlt.d: Likewise.
* testsuite/ld-powerpc/relbrlt.s: Likewise.
* testsuite/ld-powerpc/tlsso.r: Likewise.
* testsuite/ld-powerpc/tlstocso.r: Likewise.
gold/
* powerpc.cc (Target_powerpc::lplt_): New variable.
(Target_powerpc::lplt_section): Associated accessor.
(Target_powerpc::plt_off): Handle local non-ifunc symbols.
(Target_powerpc::make_lplt_section): New function.
(Target_powerpc::make_local_plt_entry): New function.
(Powerpc_relobj::do_relocate_sections): Write out lplt.
(Output_data_plt_powerpc::first_plt_entry_offset): Zero for lplt.
(Output_data_plt_powerpc::add_local_entry): New function.
(Output_data_plt_powerpc::do_write): Ignore lplt.
(Target_powerpc::make_iplt_section): Make lplt first.
(Target_powerpc::make_brlt_section): Make .branch_lt relro.
(Target_powerpc::Scan::local): Handle PLT16 relocs.
|
|
The PowerPC64 ELFv2 ABI and the PowerPC SysV ABI support a number of
relocations that can be used to create and access a PLT entry.
However, the relocs are not well defined. The PLT16 family of relocs
talk about "the section offset or address of the procedure linkage
table entry". It's plain that we do need a relative address when PIC
as otherwise we'd have dynamic text relocations, but "section offset"
doesn't specify which section. The most obvious one, ".plt", isn't
that useful because there is no readily available way of addressing
the start of the ".plt" section. Much more useful would be "the
GOT/TOC-pointer relative offset of the procedure linkage table entry",
and I suppose you could argue that is a "section offset" of sorts.
For PowerPC64 it is better to use the same TOC-pointer relative
addressing even when non-PIC, since ".plt" may be located outside the
range of a 32-bit address. However, for ppc32 we do want an absolute
address when non-PIC as a GOT pointer may not be set up. Also, for
ppc32 PIC we have a similar situation to R_PPC_PLTREL24 in that the
GOT pointer is set to a location in the .got2 section and we need to
specify the .got2 offset in the PLT16 reloc addend.
This patch supports PLT16 relocations using these semantics. This is
not an ABI change for ppc32 since the relocations were not previously
supported by GNU ld, but is for ppc64 where some of the PLT16 relocs
were supported. I'm not particularly concerned since the old ppc64
PLT16 reloc semantics made them almost completely useless.
bfd/
* elf32-ppc.c (ppc_elf_check_relocs): Handle PLT16 relocs.
(ppc_elf_relocate_section): Likewise.
* elf64-ppc.c (ppc64_elf_check_relocs): Handle PLT16_LO_DS.
(ppc64_elf_relocate_section): Likewise. Correct PLT16
resolution to plt entry relative to toc pointer.
gold/
* powerpc.cc (Target_powerpc::plt_off): New functions.
(is_plt16_reloc): New function.
(Stub_table::plt_off): Use Target_powerpc::plt_off.
(Stub_table::plt_call_size): Use plt_off.
(Stub_table::do_write): Likewise.
(Target_powerpc::Scan::get_reference_flags): Return RELATIVE_REF
for PLT16 relocations.
(Target_powerpc::Scan::reloc_needs_plt_for_ifunc): Return true
for PLT16 relocations.
(Target_powerpc::Scan::global): Make a PLT entry for PLT16 relocations.
(Target_powerpc::Relocate::relocate): Support PLT16 relocations.
(Powerpc_scan_relocatable_reloc::global_strategy): Return RELOC_SPECIAL
for ppc32 plt16 relocs.
|
|
Relocations referring to discarded sections are now treated as errors
instead of warnings.
Also with this patch, we will now print the section group signature and the
object file with the prevailing definition of that group along with the
name of the symbol that the relocation is referring to. This additional
information should be much more useful to anyone trying to track down
the source of such errors.
To do so, we now map each discarded section to the Kept_section info in
the Layout class, and defer the logic that maps a discarded section to
its counterpart in the kept group. This gives us the information we need
to identify the signature symbol given the discarded section, and the
name of the object file that provided the prevailing (i.e., first)
definition of that group.
gold/
* object.cc (Sized_relobj_file::include_section_group): Store
reference to Kept_section info for discarded comdat sections
regardless of size. Move size checking to map_to_kept_section.
(Sized_relobj_file::include_linkonce_section): Likewise.
(Sized_relobj_file::map_to_kept_section): Add section name parameter.
Insert size checking logic from above functions.
(Sized_relobj_file::find_kept_section_object): New method.
(Sized_relobj_file::get_symbol_name): New method.
* object.h (Sized_relobj_file::map_to_kept_section): Add section_name
parameter. Adjust all callers.
(Sized_relobj_file::find_kept_section_object): New method.
(Sized_relobj_file::get_symbol_name): New method.
(Sized_relobj_file::Kept_comdat_section): Replace object and shndx
fields with sh_size, kept_section, symndx, and is_comdat fields.
(Sized_relobj_file::set_kept_comdat_section): Replace kept_object
and kept_shndx parameters with is_comdat, symndx, sh_size, and
kept_section.
(Sized_relobj_file::get_kept_comdat_section): Likewise.
* target-reloc.h (enum Comdat_behavior): Change CB_WARNING to CB_ERROR.
Adjust all references.
(issue_undefined_symbol_error): New function template.
(relocate_section): Pass section name to map_to_kept_section.
Move discarded section code to new function above.
* aarch64.cc (Target_aarch64::scan_reloc_section_for_stubs): Move
declaration for gsym out one level. Call issue_discarded_error.
* arm.cc (Target_arm::scan_reloc_section_for_stubs): Likewise.
* powerpc.cc (Relocate_comdat_behavior): Change CB_WARNING to CB_ERROR.
|
|
Better security beats better placement for code optimization.
* powerpc.cc (Target_powerpc::make_brlt_section): Make .branch_lt relro.
|
|
During a -r (or --emit-relocs) link, if two sections had the same name but
different section types, gold would put relocations for both sections into
the same relocation section even though the data sections remained separate.
For .eh_frame sections, when one section is PROGBITS and another is
X86_64_UNWIND, we really should be using the UNWIND section type and
combining the sections anyway. For other sections, we should be
creating one relocation section for each output data section.
gold/
PR gold/23016
* incremental.cc (can_incremental_update): Check for unwind section
type.
* layout.h (Layout::layout): Add sh_type parameter.
* layout.cc (Layout::layout): Likewise.
(Layout::layout_reloc): Create new output reloc section if data
section does not already have one.
(Layout::layout_eh_frame): Check for unwind section type.
(Layout::make_eh_frame_section): Use unwind section type for .eh_frame
and .eh_frame_hdr.
* object.h (Sized_relobj_file::Shdr_write): New typedef.
(Sized_relobj_file::layout_section): Add sh_type parameter.
(Sized_relobj_file::Deferred_layout::Deferred_layout): Add sh_type
parameter.
* object.cc (Sized_relobj_file::check_eh_frame_flags): Check for
unwind section type.
(Sized_relobj_file::layout_section): Add sh_type parameter; pass it
to Layout::layout.
(Sized_relobj_file::do_layout): Make local copy of sh_type.
Force .eh_frame sections to unwind section type.
Pass sh_type to layout_section.
(Sized_relobj_file<size, big_endian>::do_layout_deferred_sections):
Pass sh_type to layout_section.
* output.cc (Output_section::Output_section): Initialize reloc_section_.
* output.h (Output_section::reloc_section): New method.
(Output_section::set_reloc_section): New method.
(Output_section::reloc_section_): New data member.
* target.h (Target::unwind_section_type): New method.
(Target::Target_info::unwind_section_type): New data member.
* aarch64.cc (aarch64_info): Add unwind_section_type.
* arm.cc (arm_info, arm_nacl_info): Likewise.
* i386.cc (i386_info, i386_nacl_info, iamcu_info): Likewise.
* mips.cc (mips_info, mips_nacl_info): Likewise.
* powerpc.cc (powerpc_info): Likewise.
* s390.cc (s390_info): Likewise.
* sparc.cc (sparc_info): Likewise.
* tilegx.cc (tilegx_info): Likewise.
* x86_64.cc (x86_64_info, x86_64_nacl_info): Likewise.
* testsuite/Makefile.am (pr23016_1, pr23016_2): New test cases.
* testsuite/Makefile.in: Regenerate.
* testsuite/testfile.cc: Add unwind_section_type.
* testsuite/pr23016_1.sh: New test script.
* testsuite/pr23016_1a.s: New source file.
* testsuite/pr23016_1b.s: New source file.
* testsuite/pr23016_2.sh: New test script.
* testsuite/pr23016_2a.s: New source file.
* testsuite/pr23016_2b.s: New source file.
|
|
This reverts most of commit 1be5d8d3bb.
Left in place are addition of --no-plt-align to some ppc32 ld tests
and the ld.texinfo --no-plt-thread-safe fix.
|