Asking for ppc32 plt call stubs to be aligned at 32 byte boundaries
didn't quite work. For ld.bfd they were spaced 32 bytes apart, but
only started on a 16 byte boundary. ld.gold also didn't get it right.
Finding that bug made me check over the ppc64 plt stub alignment,
where I found that negative values for alignment (meaning align to
minimize boundary crossing) were not accepted. Since no one has
complained about that, I guess I could have removed the feature from
ld.bfd documentation, but I've opted instead to correct the code.
I've also added an optional alignment paramenter for ppc32
--plt-align, for some consistency with gold and ppc64 ld.bfd.
bfd/
* elf32-ppc.c (ppc_elf_create_glink): Correct alignment of .glink.
* elf64-ppc.c (ppc64_elf_size_stubs): Handle negative plt_stub_align.
(ppc64_elf_build_stubs): Likewise.
gold/
* powerpc.cc (param_plt_align): New function supplying default
--plt-align values. Use it..
(Stub_table::plt_call_align): ..here, and..
(Output_data_glink::global_entry_align): ..here.
(Stub_table::stub_align): Correct 32-bit minimum alignment.
ld/
* emultempl/ppc32elf.em: Support optional --plt-align arg.
* emultempl/ppc64elf.em: Support negative --plt-align arg.
This is in preparation for the next patch adding Spectre variant 2
mitigation for PowerPC and PowerPC64. Besides tidying code involved
in stub output (to reduce the number of places where bctr is output),
the patch adds some user visible features:
1) PowerPC64 ELFv2 global entry stubs now are aligned under the
control of --plt-align, with a default alignment of 32 bytes.
2) PowerPC64 __glink_PLTresolve is no longer padded out with nops.
3) PowerPC32 PLT stubs are aligned under the control of --plt-align,
with the default alignment being 16 bytes as before.
4) The PowerPC32 branch/nop table emitted before __glink_PLTresolve
is now smaller in many cases. It was sized incorrectly when the
__tls_get_addr_opt stub was used, and unnecessarily included space
for local ifuncs.
bfd/
* elf32-ppc.c (GLINK_ENTRY_SIZE): Add parameters, handle
__tls_get_addr_opt, and alignment sizing.
(TLS_GET_ADDR_GLINK_SIZE): Delete.
(is_nonpic_glink_stub): Don't use GLINK_ENTRY_SIZE.
(ppc_elf_get_synthetic_symtab): Recognize stubs spaced at 4, 6,
or 8 insns.
(ppc_elf_link_hash_table_create): Init new ppc_elf_params field.
(allocate_dynrelocs): Use new GLINK_ENTRY_SIZE.
(ppc_elf_size_dynamic_sections): Likewise. Size branch table
by PLT reloc count.
(write_glink_stub): Handle __tls_get_addr_opt stub.
Pad out to size given by GLINK_ENTRY_SIZE.
(ppc_elf_relocate_section): Adjust write_glink_stub call.
(ppc_elf_finish_dynamic_symbol): Likewise.
(ppc_elf_finish_dynamic_sections): Write PLTresolve without using
insn array since so many need rewriting.
* elf32-ppc.h (struct ppc_elf_params): Add plt_stub_align.
* elf64-ppc.c (GLINK_PLTRESOLVE_SIZE): Rename from
GLINK_CALL_STUB_SIZE. Add htab param and evaluate to size without
nops. Adjust all uses.
(ppc64_elf_get_synthetic_symtab): Don't use GLINK_CALL_STUB_SIZE
in glink_vma calculation.
(struct ppc_link_hash_table): Add global_entry section pointer.
(create_linkage_sections): Create separate section for global
entry stubs.
(PPC_LO, PPC_HI, PPC_HA): Move earlier.
(size_global_entry_stubs): Handle sizing for aligned stubs.
(ppc64_elf_size_dynamic_sections): Handle global_entry alloc,
and don't stash end of glink branch table in rawsize.
(ppc_build_one_stub): Rewrite stub size calculations.
(build_global_entry_stubs): Use new section.
(ppc64_elf_build_stubs): Don't pad __glink_PLTresolve with nops.
Build lazy link stubs out to end of section. Build global entry
stubs in new section.
gold/
* options.h (plt_align): Support for PowerPC32 too.
* powerpc.cc (Stub_table::stub_align): Heed --plt-align for 32-bit.
(Stub_table::plt_call_size, branch_stub_size): Tidy.
(Stub_table::plt_call_align): Implement using stub_align.
(Output_data_glink::global_entry_align): New function.
(Output_data_glink::global_entry_off): New function.
(Output_data_glink::global_entry_address): Use global_entry_off.
(Output_data_glink::pltresolve_size): New function, replacing
pltresolve_size_ constant. Update all uses.
(Output_data_glink::add_global_entry): Align offset.
(Output_data_glink::set_final_data_size): Use global_entry_align.
(Stub_table::do_write): Don't pad __glink_PLTrelsolve with nops.
Tidy stub output. Use global_entry_off.
ld/
* emultempl/ppc32elf.em (params): Init new field.
(enum ppc32_opt): New enum to define OPTION_* values. Add
OPTION_PLT_ALIGN and OPTION_NO_PLT_ALIGN.
(PARSE_AND_LIST_LONGOPTS): Handle new options.
(PARSE_AND_LIST_ARGS_CASES): Likewise.
(PARSE_AND_LIST_OPTIONS): Likewise. Break up help output.
* emultempl/ppc64elf.em (ppc_add_stub_section): Init alignment
correctly for negative --plt-stub-align.
* testsuite/ld-powerpc/elfv2exe.d,
* testsuite/ld-powerpc/elfv2so.d,
* testsuite/ld-powerpc/relbrlt.d,
* testsuite/ld-powerpc/relbrlt.s,
* testsuite/ld-powerpc/tlsexe.d,
* testsuite/ld-powerpc/tlsexe.r,
* testsuite/ld-powerpc/tlsexe32.d,
* testsuite/ld-powerpc/tlsexe32.g,
* testsuite/ld-powerpc/tlsexe32.r,
* testsuite/ld-powerpc/tlsexetoc.d,
* testsuite/ld-powerpc/tlsexetoc.r,
* testsuite/ld-powerpc/tlsopt5_32.d,
* testsuite/ld-powerpc/tlsso.d,
* testsuite/ld-powerpc/tlstocso.d: Update for changed stub order.
PR 22042 complained that garbage text was being printed in the help
for the -fuse-ld option; this was caused by passing an empty string
to the gettext() function, which sometimes returns garbage when passed
an empty string. The quick fix was to replace "" with NULL as the helparg,
but that changed the parsing of the option, as gold uses the helparg to
determine whether an option takes an argument. This patch adds a
non-empty helparg string to fix both problems.
gold/
PR gold/22694
* options.h (-fuse-ld): Add correct helparg.
We never need to resolve_forwards() a symbol found by hash table lookup
such as target->tls_get_addr_opt() but we do potentially need to do so
for random symbols seen on relocs. So these calls were in the wrong
order, resulting in missing stubs and an assertion failure.
PR 22602
* powerpc.cc (Target_powerpc::Branch_info::mark_pltcall): Resolve
forwards before replacing __tls_get_addr.
(Target_powerpc::Branch_info::make_stub): Likewise.
Gold plugins may wish to further process an input file added by a plugin. For
example, the plugin may need to assign a unique segment for sections in a
plugin-generated input file. This patch adds a plugin callback that the linker
will call when reading symbols from a new input file added after the
all_symbols_read event (i.e. an input file added by a plugin).
2017-12-11 Stephen Crane <sjc@immunant.com>
* plugin-api.h: Add new plugin hook to allow processing of input
files added by a plugin.
(ld_plugin_new_input_handler): New function hook type.
(ld_plugin_register_new_input): New interface.
(LDPT_REGISTER_NEW_INPUT_HOOK): New enum val.
(tv_register_new_input): New member.
* plugin.cc (Plugin::load): Include hooks for register_new_input
in transfer vector.
(Plugin::new_input): New function.
(register_new_input): New function.
(Plugin_manager::claim_file): Call Plugin::new_input if in
replacement phase.
* plugin.h (Plugin::set_new_input_handler): New function.
* testsuite/plugin_new_section_layout.c: New plugin to test
new_input plugin API.
* testsuite/plugin_final_layout.sh: Add new input test.
* testsuite/Makefile.am (plugin_layout_new_file): New test case.
* testsuite/Makefile.in: Regenerate.
This is a partial fix for the gold testsuite failures documented in
PR 21090. The use of -fpie triggers some mov-to-lea optimizations that
are not compatible with incremental linking, so those optimizations need
to be disabled. We also diagnose the attempt to use -pie with incremental
linking, and force -no-pie for the incremental tests in case the build has
been configured to have GCC pass -pie all the time.
We still have a problem where compiling with -fpie results in some GOT
entries even when linking with -no-pie. This combination still causes test
failures because we are not updating the GOT entries in an incremental update
link.
gold/
PR gold/21090
* incremental.cc (Sized_relobj_incr::do_relocate): Fix comment.
* options.cc (General_options::finalize): Disallow -pie with
incremental linking.
* x86_64.cc (Target_x86_64::Scan::local): Don't do mov-to-lea
or callq-to-direct optimizations for incremental links.
(Target_x86_64::Scan::global): Likewise.
(Target_x86_64::Relocate::relocate): Likewise.
* testsuite/Makefile.am (incremental_test): Force -no-pie.
(incremental_test_2): Likewise.
(incremental_test_3): Likewise.
(incremental_test_4): Likewise.
(incremental_test_5): Likewise.
(incremental_test_6): Likewise.
(incremental_copy_test): Likewise.
(incremental_common_test_1): Likewise.
(incremental_comdat_test_1): Likewise.
* testsuite/Makefile.in: Regenerate.
With the new compiler, we're running out of patch space for the .eh_frame
section. To workaround that issue, we compile the before and after versions
both with no unwind tables.
gold/
PR gold/22309
* testsuite/Makefile.am (two_file_test_1_v1_ndebug.o): Compile with
no EH information.
(two_file_test_1_ndebug.o): Likewise.
* testsuite/Makefile.in: Regenerate.
* testsuite/two_file_test_1.cc: Touch to force recompilation with new
flags.
* testsuite/two_file_test_1_v1.cc: Likewise.
The problem is that while the command line isn't trivially empty,
it contains no input files. As gold tries to configure the number
of threads to use based on the number of input files, this causes
the assertion failure above. Fix this problem by making the logic
in gold.cc more robust and also adding a better error message
about --start-lib to options.cc.
gold/
PR gold/22406
* gold.cc (queue_initial_tasks) Check for number of real input files.
* options.cc (Command_line::process) Check for unterminated --start-lib
options.
* testsuite/Makefile.am: Add new test script.
* testsuite/Makefile.in: Regenerate.
* testsuite/check_empty_command_lines.sh: New test script.
If a shared library contains an undefined symbol and LTO adds
a new reference to that same undefined symbol, the reference in the new
object added by the plugin would not trigger a rescan of the archive
containing the symbol.
2017-11-17 Stephen Crane <sjc@immunant.com>
gold/
PR gold/22448
* symtab.cc (Symbol_table::add_from_object): Only rescan for
undefined symbols in regular, not dynamic, objects.
The addresses of erratum stubs can be changed by relaxation passes, and
need to be updated.
gold/
PR gold/20765
* aarch64.cc (Aarch64_relobj::update_erratum_address): New method.
(AArch64_relobj::scan_errata): Update addresses in stub table after
relaxation pass.
I checked over the results of applying --fix-cortex-a53-843419 to
a very large program (gitit) with two stub tables and thousands
of erratum fixes. I noticed that all the erratum_stubs were being
created but about 1/3 of them were being skipped over by
fix_errata_and_relocate_erratum_stubs(). By skipped over I mean
no branch relocation or adrp -> adr transformation was applied to
the erratum address, leaving the erratum_stub unreachable, and
with a branch with a 0 immediate.
The root cause of the skipped over erratum_stubs is
Erratum_stub::invalidate_erratum_stub() that is used to set
relobj_ to NULL when an erratum_stub has been processed.
Unfortunately relobj_ is used in operator<() so altering relobj
makes the results from erratum_stubs_.lower_bound() as used in
find_erratum_stubs_for_input_section() unreliable.
2017-11-30 Peter Smith <peter.smith@linaro.org>
Cary Coutant <ccoutant@gmail.com>
gold/
PR gold/20765
* aarch64.cc (Erratum_stub::invalidate_erratum_stub): Use erratum_insn_
instead of relobj_ to invalidate the stub.
(Erratum_stub::is_invalidated_erratum_stub): Likewise.
The fix for PR21868 (an internal error when --fix-cortex-a53-843419
is applied) has a small mistake in it. When the stub_owner section
needs an erratum fix an incorrect address for the stubs for the section
is given to relocate_erratum_stub. If we are lucky we will get a segfault;
if we aren't, an incorrect patch or data corruption is possible.
The error is visible in PR21868, but the side-effects aren't fatal.
gold/
PR gold/22233
* aarch64.cc (AArch64_relobj::fix_errata_and_relocate_erratum_stubs):
Fix calculation of stub address.
bfd/
* po/Make-in (datadir): Define as @datadir@.
(localedir): Define as @localedir@.
(gnulocaledir, gettextsrcdir): Use @datarootdir@.
binutils/
* po/Make-in (datadir): Define as @datadir@.
(localedir): Define as @localedir@.
(gnulocaledir, gettextsrcdir): Use @datarootdir@.
gas/
* po/Make-in (datadir): Define as @datadir@.
(localedir): Define as @localedir@.
(gnulocaledir, gettextsrcdir): Use @datarootdir@.
gold/
* po/Make-in (datadir): Define as @datadir@.
(localedir): Define as @localedir@.
(gnulocaledir, gettextsrcdir): Use @datarootdir@.
gprof/
* po/Make-in (datadir): Define as @datadir@.
(localedir): Define as @localedir@.
(gnulocaledir, gettextsrcdir): Use @datarootdir@.
ld/
* po/Make-in (datadir): Define as @datadir@.
(localedir): Define as @localedir@.
(gnulocaledir, gettextsrcdir): Use @datarootdir@.
opcodes/
* po/Make-in (datadir): Define as @datadir@.
(localedir): Define as @localedir@.
(gnulocaledir, gettextsrcdir): Use @datarootdir@.
LLVM is experimenting with placing .eh_frame sections in the COMDAT group
with the function's text. This triggers an internal error in gold because
we don't expect to see but one .eh_frame section in an object, and we use
a single data member in class Sized_relobj_file to keep track of that section.
This patch removes that data member, and instead checks the output section
and the input section offset to identify an optimized .eh_frame section.
gold/
* object.h (class Sized_relobj_file): Remove discarded_eh_frame_shndx_.
* object.cc (Sized_relobj_file::Sized_relobj_file): Likewise.
(Sized_relobj_file::layout_eh_frame_section): Likewise.
(Sized_relobj_file::do_count_local_symbols): Check for optimized
.eh_frame section by other means.
(Sized_relobj_file::compute_final_local_value_internal): Likewise.
This patch fixes the build with GCC 4.2:
gold/testsuite/pr22266_a.c:13:2: error: no newline at end of file
* testsuite/pr22266_a.c: Add a newline at end of file.
The fix for PR 19291 broke some other cases where -r is used with scripts,
as reported in PR 22266. The original fix for PR 22266 ended up breaking
many cases for REL targets, where the addends are stored in the section data,
and are not being adjusted properly.
The problem was basically that in a relocatable output file (ET_REL),
symbol values are supposed to be relative to the start address of their
section. Usually in a relocatable file, all sections start at 0, so the
failure to get this right is often irrelevant, but with a linker script,
we occasionally see an output section whose starting address is not 0,
and gold would occasionally write a symbol with its relocated value instead
of its section-relative value.
This patch reverts the recent fix for PR 22266 as well as my original fix
for PR 19291. The original fix moved the symbol value adjustment to
write_local_symbols, but neglected to undo a few places where the adjustment
was also being applied, resulting in an occasional double adjustment. The
more recent fix removed those other adjustments, but then failed to
re-account for the adjustment when rewriting the relocations on REL targets.
With the old attempts reverted, we now apply the symbol value adjustment to
the one case that had been missed (non-section symbols in merge sections).
But now we also need to account for the adjustment when rewriting the addends
for RELA relocations.
gold/
PR gold/19291
PR gold/22266
* object.cc (Sized_relobj_file::compute_final_local_value_internal):
Revert changes from 2017-11-08 patch. Adjust symbol value in
relocatable links for non-section symbols.
(Sized_relobj_file::compute_final_local_value): Revert changes from
2017-11-08 patch.
(Sized_relobj_file::do_finalize_local_symbols): Likewise.
(Sized_relobj_file::write_local_symbols): Revert changes from
2015-11-25 patch.
* object.h (Sized_relobj_file::compute_final_local_value_internal):
Revert changes from 2017-11-08 patch.
* powerpc.cc (Target_powerpc::relocate_relocs): Adjust addend for
relocatable links.
* target-reloc.h (relocate_relocs): Adjust addend for relocatable links.
* testsuite/pr22266_a.c (hello): New function.
* testsuite/pr22266_main.c (main): Add test for merge sections.
* testsuite/pr22266_script.t: Add rule for .rodata.
Since special symbol must be defined in a regular object, definition
from a dynamic object should be ignored. If special symbol has the
hidden or internal visibility, reference from a dynamic object should
also be ignored. Also __start and __stop symbols in a dynamic object
shouldn't be preempted.
PR gold/22291
* layout.cc (Layout::define_section_symbols): Use STV_PROTECTED
for __start and __stop symbols.
* symtab.cc (Symbol_table::define_special_symbol): Add an
argument, visibility. Ignore definition and reference from
a dynamic object, depending on visibility.
(Symbol_table::do_define_in_output_data): Pass visibility to
define_special_symbol.
(Symbol_table::do_define_in_output_segment): Likewise.
(Symbol_table::do_define_as_constant): Likewise.
(Symbol_table::add_undefined_symbol_from_command_line): Pass
STV_DEFAULT to define_special_symbol.
* symtab.h (Symbol_table::define_special_symbol): Add an
argument, visibility.
The fix committed for PR gold/19291 ended up breaking other cases. The
commit added adjustment code to write_local_symbols, but in many cases
compute_final_local_value_internal had already subtracted the output
section's address. To fix this, all other adjustments are now removed, so
only the one in write_local_symbols is left.
gold/
PR gold/22266
* object.cc (Sized_relobj_file::compute_final_local_value_internal):
Drop relocatable parameter and stop adjusting output value based on
it.
(Sized_relobj_file::compute_final_local_value): Stop passing
relocatable to compute_final_local_value_internal.
(Sized_relobj_file::do_finalize_local_symbols): Ditto.
* object.h (Sized_relobj_file::compute_final_local_value_internal):
Drop relocatable parameter.
2017-11-08 Kyle Butt <iteratee@google.com>
* object.cc (do_find_special_sections): Fix a thinko with memmem return
values and check for != NULL rather than == 0.
binutils has lacked proper pluralization of output messages for a long
time, for example, readelf will display information about a section
that "contains 1 entries" or "There are 1 section headers". Fixing
this properly requires us to use ngettext, because other languages
have different rules to English.
This patch defines macros for ngettext and friends to handle builds
with --disable-nls, and tidies the existing nls support. I've
redefined gettext rather than just defining "_" as dgettext in bfd and
opcodes in case someone wants to use gettext there (which might
conceivably happen with generated code).
bfd/
* sysdep.h: Formatting, comment fixes.
(gettext, ngettext): Redefine when ENABLE_NLS.
(ngettext, dngettext, dcngettext): Define when !ENABLE_NLS.
(_): Define using gettext.
(textdomain, bindtextdomain): Use safer "do nothing".
* hosts/alphavms.h (textdomain, bindtextdomain): Likewise.
(ngettext, dngettext, dcngettext): Define when !ENABLE_NLS.
opcodes/
* opintl.h: Formatting, comment fixes.
(gettext, ngettext): Redefine when ENABLE_NLS.
(ngettext, dngettext, dcngettext): Define when !ENABLE_NLS.
(_): Define using gettext.
(textdomain, bindtextdomain): Use safer "do nothing".
binutils/
* sysdep.h (textdomain, bindtextdomain): Use safer "do nothing".
(ngettext, dngettext, dcngettext): Define when !ENABLE_NLS.
gas/
* asintl.h (textdomain, bindtextdomain): Use safer "do nothing".
(ngettext, dngettext, dcngettext): Define when !ENABLE_NLS.
gold/
* system.h (textdomain, bindtextdomain): Use safer "do nothing".
(ngettext, dngettext, dcngettext): Define when !ENABLE_NLS.
ld/
* ld.h (textdomain, bindtextdomain): Use safer "do nothing".
(ngettext, dngettext, dcngettext): Define when !ENABLE_NLS.
Some targets prefix global symbols with "_".
bfd/
* archive.c (_bfd_compute_and_write_armap): Match "__gnu_lto_slim"
optionally prefixed with "_".
* linker.c (_bfd_generic_link_add_one_symbol): Likewise.
binutils/
* nm.c (filter_symbols): Match "__gnu_lto_slim" optionally prefixed
with "_".
gold/
* symtab.cc (Symbol_table::add_from_relobj): Match "__gnu_lto_slim"
optionally prefixed with "_".
ld/
* testsuite/ld-plugin/lto-3r.d: Match "__gnu_lto_v" optionally
prefixed with "_".
* testsuite/ld-plugin/lto-5r.d: Likewise.
2017-10-04 Sriraman Tallam <tmsriram@google.com>
* options.h (-z,text_unlikely_segment): New option.
* layout.cc (Layout::layout): Create new output section
for .text.unlikely sections with the new option.
(Layout::segment_precedes): Check for the new option
when segment flags match.
* testsuite/text_unlikely_segment.cc: New test source.
* testsuite/text_unlikely_segment.sh: New test script.
* testsuite/Makefile.am (text_unlikely_segment): New test.
* testsuite/Makefile.in: Regenerate.
gold/
* arm.cc (Stub::do_fixed_endian_write):Far call stubs support for arm
in the be8 mode.
* testsuite/Makefile.am: New test cases.
* testsuite/Makefile.in: Regenerate.
* testsuite/arm_farcall_arm_arm_be8.sh: New script for arm to arm far
call stubs.
* testsuite/arm_farcall_thumb_thumb_be8.sh: New script for thumb to
thumb far call stubs.
Fixes a thinko. Given code that puts variables into the TOC (a bad
idea, but some see the TOC as a small data section) this bug could
result in an attempt to optimize a sequence that should not be
optimized.
* powerpc.cc (Target_powerpc::Scan::local): Correct dst_off
calculation for TOC16 relocs.
(Target_powerpc::Scan::global): Likewise.
GNU-stack notes added in 2004, aarch64 port added in 2012, so no old object
files with missing GNU-stack notes that we need to worry about.
gold/
* aarch64.cc (Target_aarch64::aarch64_info): Set
is_default_stack_executable to false.
gcc doesn't emit stack notes for ELFv1, since ELFv1 never needs an
executable stack. Note that ELFv1 is usually big-endian and ELFv2
little-endian, but the ABI is really orthogonal to endiannes.
* powerpc.cc (Target_powerpc<64,*>::powerpc_info): Set
is_default_stack_executable false.
2017-09-20 Teresa Johnson <tejohnson@google.com>
* plugin.cc (is_visible_from_outside): Check for export dynamic symbol
option and list.
* testsuite/Makefile.am (plugin_test_12): New test.
* testsuite/Makefile.in: Regenerate.
* testsuite/export_dynamic_plugin.cc: New test source.
* testsuite/plugin_test_12.sh: New test script.
ppc32, like many targets, defines the address of a function as the PLT
call stub code for functions referenced but not defined in a non-PIC
executable. ppc32 gold, unlike other targets, inherits the ppc64
multiple stub capability for dealing with very large binaries where
one set of stubs can't be reached from all code locations. This means
there can be multiple choices of address for a function, which might
cause function pointer comparison failures. So for ppc32, make
non-branch references always use the first stub group.
(PowerPC64 ELFv1 is always PIC so doesn't need to define the address
of an external function as the PLT stub. PowerPC64 ELFv2 needs a
special set of global entry stubs to serve as the address of external
functions, so it too is not affected by this bug.)
* powerpc.cc (Target_powerpc::Branch_info::make_stub): Put
stubs for ppc32 non-branch relocs in first stub table.
(Target_powerpc::Relocate::relocate): Resolve similarly.
The trouble with stubs per output section is that ppc32 uses a plt
stub as the address of a global function. This needs to be unique,
otherwise we'll get multiple addresses for a function.
Obviously this is only a partial solution, since ppc32 will get
multiple stubs when code is larger than 33M. A proper fix will
involve selecting a unique stub to use for non-branch relocs.
* options.h (stub-group-multi): Default to true. Add
--no-stub-group-multi.
In the TLS GD/LD to LE optimization, ld replaces a sequence like
addi 3,2,x@got@tlsgd R_PPC64_GOT_TLSGD16 x
bl __tls_get_addr(x@tlsgd) R_PPC64_TLSGD x
R_PPC64_REL24 __tls_get_addr
nop
with
addis 3,13,x@tprel@ha R_PPC64_TPREL16_HA x
addi 3,3,x@tprel@l R_PPC64_TPREL16_LO x
nop
When the tprel offset is small, this can be further optimized to
nop
addi 3,13,x@tprel
nop
bfd/
* elf64-ppc.c (struct ppc_link_hash_table): Add do_tls_opt.
(ppc64_elf_tls_optimize): Set it.
(ppc64_elf_relocate_section): Nop addis on TPREL16_HA, and convert
insn on TPREL16_LO and TPREL16_LO_DS relocs to use r13 when
addis would add zero.
* elf32-ppc.c (struct ppc_elf_link_hash_table): Add do_tls_opt.
(ppc_elf_tls_optimize): Set it.
(ppc_elf_relocate_section): Nop addis on TPREL16_HA, and convert
insn on TPREL16_LO relocs to use r2 when addis would add zero.
gold/
* powerpc.cc (Target_powerpc::Relocate::relocate): Nop addis on
TPREL16_HA, and convert insn on TPREL16_LO and TPREL16_LO_DS
relocs to use r2/r13 when addis would add zero.
ld/
* testsuite/ld-powerpc/tls.s: Add calls with tls markers.
* testsuite/ld-powerpc/tls32.s: Likewise.
* testsuite/ld-powerpc/powerpc.exp: Run tls marker tests.
* testsuite/ld-powerpc/tls.d: Adjust for TPREL16_HA/LO optimization.
* testsuite/ld-powerpc/tlsexe.d: Likewise.
* testsuite/ld-powerpc/tlsexetoc.d: Likewise.
* testsuite/ld-powerpc/tlsld.d: Likewise.
* testsuite/ld-powerpc/tlsmark.d: Likewise.
* testsuite/ld-powerpc/tlsopt4.d: Likewise.
* testsuite/ld-powerpc/tlstoc.d: Likewise.
This implements the special __tls_get_addr_opt call stub for powerpc
gold that returns __thread variable addresses without actually making
a call to __tls_get_addr in most cases. Shared libraries that are
loaded at program load time (ie. dlopen is not used) have a known
layout for their __thread variables, and thus DTPMOD64/DPTREL64 pairs
describing those variables can be set up by ld.so for the
__tls_get_addr_opt call stub fast exit.
Ref https://sourceware.org/ml/libc-alpha/2015-03/msg00626.html
I really, really wish I'd used a differently versioned __tls_get_addr
symbol than the base symbol to indicate glibc support for the
optimized call, rather than having glibc export __tls_get_addr_opt. A
lot of the messing around here, flipping symbols from __tls_get_addr
to __tls_get_addr_opt, is caused by that decision. About the only
benefit is that a user can see at a glance that their disassembled
code is calling __tls_get_addr via the fancy call stub.. Anyway, we
need references to __tls_get_addr to seem like they were to
__tls_get_addr_opt, and in cases like the tsan interceptor, a
definition of __tls_get_addr to seem like one of __tls_get_addr_opt
as well. That's the reason for Symbol::clear_in_reg and
Symbol_table::clone, and why symbols are substituted in Scan::global
and other places dealing with dynamic linking.
elfcpp/
* elfcpp.h (DT_PPC_OPT): Define.
* powerpc.h (PPC_OPT_TLS): Define.
gold/
* options.h (tls_get_addr_optimize): New option.
* symtab.h (Symbol::clear_in_reg, clone): New functions.
(Sized_symbol::clone): New function.
(Symbol_table::clone): New function.
* resolve.cc (Symbol::clone, Sized_symbol::clone): New functions.
* powerpc.cc (Target_powerpc::has_tls_get_addr_opt_,
tls_get_addr_, tls_get_addr_opt_): New vars.
(Target_powerpc::tls_get_addr_opt, tls_get_addr,
is_tls_get_addr_opt, replace_tls_get_addr,
set_has_tls_get_addr_opt, stk_linker): New functions.
(Target_powerpc::Track_tls::maybe_skip_tls_get_addr_call): Add
target param. Update callers. Compare symbols rather than names.
(Target_powerpc::do_define_standard_symbols): Init tls_get_addr_
and tls_get_addr_opt_.
(Target_powerpc::Branch_info::mark_pltcall): Translate tls_get_addr
sym to tls_get_addr_opt.
(Target_powerpc::Branch_info::make_stub): Likewise.
(Stub_table::define_stub_syms): Likewise.
(Target_powerpc::Scan::global): Likewise.
(Target_powerpc::Relocate::relocate): Likewise.
(add_3_12_2, add_3_12_13, bctrl, beqlr, cmpdi_11_0, cmpwi_11_0,
ld_11_1, ld_11_3, ld_12_3, lwz_11_3, lwz_12_3, mr_0_3, mr_3_0,
mtlr_11, std_11_1): New constants.
(Stub_table::eh_frame_added_): Delete.
(Stub_table::tls_get_addr_opt_bctrl_, plt_fde_len_, plt_fde_): New vars.
(Stub_table::init_plt_fde): New functions.
(Stub_table::add_eh_frame, replace_eh_frame): Move definition out
of line. Init and use plt_fde_.
(Stub_table::plt_call_size): Return size for tls_get_addr stub.
Extract alignment code to..
(Stub_table::plt_call_align): ..this new function. Adjust all callers.
(Stub_table::add_plt_call_entry): Set has_tls_get_addr_opt and
tls_get_addr_opt_bctrl, and align after that.
(Stub_table::do_write): Write out tls_get_addr stub.
(Target_powerpc::do_finalize_sections): Emit DT_PPC_OPT
PPC_OPT_TLS/PPC64_OPT_TLS bit.
(Target_powerpc::Relocate::relocate): Don't check for or modify
nop following bl for tls_get_addr stub.
On 64-bit targets there is a 32-bit hole in symbol->u_, and another
due to symbol flags exceeding 32 bits. By splitting the union,
the total size of the class reduces by one 64-bit word.
* symtab.h (Symbol): Split u_ into u1_ and u2_. Adjust accessors
to suit. Move plt_offset_ before got_offsets_.
* symtab.cc (Symbol::init_fields): Adjust for union change.
(Symbol::init_base_output_data): Likewise.
(Symbol::init_base_output_segment): Likewise.
(Symbol::allocate_base_common): Likewise.
(Symbol::output_section): Likewise.
(Symbol::set_output_section): Likewise.
(Symbol::set_output_segment): Likewise.
* resolve.cc (Symbol::override_base): Likewise.
(Symbol::override_base_with_special): Likewise.
gold/ChangeLog:
PR gold/21868
* aarch64.cc (AArch64_relobj::try_fix_erratum_843419_optimized):
Add extra view offset argument to function.
(AArch64_relobj::fix_errata_and_relocate_erratum_stubs): Add
extra view offset set to the output offset when the view has
is_input_output_view set, since it has not already been
included. Pass this to try_fix_erratum_843419_optimized.
If a custom linker script with an unexpected relative layout of .got
and .got.plt sections was used, gold might produce a wrong offset
when applying R_AARCH64_TLSDESC_* relocations.
This patch fixes the issue by calculating "got_tlsdesc_offset"
in a more direct way.
gold/
* aarch64.cc (Target_aarch64::Relocate::relocate_tls):
Make got_tlsdesc_offset signed and fix its calculation.
* testsuite/Makefile.am (aarch64_tlsdesc): New test.
* testsuite/Makefile.in: Regenerate.
* testsuite/aarch64_tlsdesc.s: New test source file.
* testsuite/aarch64_tlsdesc.sh: New test script.
* testsuite/aarch64_tlsdesc.t: New test linker script.
This patch provides a flag for PowerPC64 ELFv2 use in class Symbol,
and modifies Sized_target::resolve to return whether the symbol has
been resolved. If not, normal processing continues. I use this for
PowerPC64 ELFv2 to keep track of whether a symbol has any definition
with non-zero localentry, in order to disable --plt-localentry for
that symbol.
PR 21847
* powerpc.cc (Target_powerpc::is_elfv2_localentry0): Test
non_zero_localentry.
(Target_powerpc::resolve): New function.
(powerpc_info): Set has_resolve for 64-bit.
* target.h (Sized_target::resolve): Return bool.
* resolve.cc (Symbol_table::resolve): Continue with normal
processing when target resolve returns false.
* symtab.h (Symbol::non_zero_localentry, set_non_zero_localentry):
New accessors.
(Symbol::non_zero_localentry_): New flag bit.
* symtab.cc (Symbol::init_fields): Init non_zero_localentry_.
There is a very small but non-zero probability that a stub group
contains stubs on one relax pass, but does not on the next. In that
case we would get an FDE covering a zero length address range.
(Actually, it's even worse. Alignment padding for stubs can mean the
address for the non-existent stubs is past the end of the original
section to which stubs are attached, and due to the way
do_plt_fde_location calculates the length we can get a negative
length.) Fixing this properly requires removing the FDE.
Also, I have been implementing the __tls_get_addr_opt support for
gold, and that stub needs something other than the default FDE. The
necessary FDE will depend on the offset to the __tls_get_addr_opt
stub, which of course can change during relaxation. That means at the
very least, rewriting the FDE on each pass, possibly changing the FDE
size. I think that is better done by completely recreating PLT
eh_frame FDEs.
* ehframe.cc (Fde::operator==): New.
(Cie::remove_fde, Eh_frame::remove_ehframe_for_plt): New.
* ehframe.h (Fde::operator==): Declare.
(Cie::remove_fde, Eh_frame::remove_ehframe_for_plt): Likewise.
* layout.cc (Layout::remove_eh_frame_for_plt): New.
* layout.h (Layout::remove_eh_frame_for_plt): Declare.
* powerpc.cc (Target_powerpc::do_relax): Remove old eh_frame FDEs.
(Stub_table::add_eh_frame): Delete eh_frame_added_ condition.
Don't add eh_frame for empty stub section.
(Stub_table::remove_eh_frame): New.
This adds a --no-tls-optimize option for people who want to keep
__tls_get_addr calls in an executable rather than optimizing such code
sequences to IE/LE.
Also tidy some formatting errors, rename a variable to better reflect
its use, and tweak two functions that create pairs of GOT entries to
first check whether the GOT entry already exists before potentially
inserting the header via reserve(2). Without the check it is possible
to waste one GOT entry.
* options.h (no_tls_optimize): New powerpc option.
* powerpc.cc (Target_powerpc::abiversion, set_abiversion): Formatting.
(Target_powerpc::stk_toc): Formatting, fix comment.
(Target_powerpc::Track_tls::tls_get_addr_state): Rename from
tls_get_addr.
(Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie):
Return TLSOPT_NONE when !tls_optimize.
(Target_powerpc::add_global_pair_with_rel): Check
for existing reloc before reserving.
(Target_powerpc::add_local_tls_pair): Likewise.
This makes ld warn about --plt-localentry if a version of glibc
without the necessary ld.so checks is detected, and revises the
documentation.
bfd/
* elf64-ppc.c (ppc64_elf_tls_setup): Warn on --plt-localentry
without ld.so checks.
gold/
* powerpc.cc (Target_powerpc::scan_relocs): Warn on --plt-localentry
without ld.so checks.
ld/
* ld.texinfo (plt-localentry): Revise.
The big comment in ppc64_elf_tls_setup says why. I've also added some
code to the bfd linker that catches the -lpthread -lc symbol
differences and disable generation of optimized call stubs even when
--plt-localentry is activated. Gold doesn't yet have that.
PR 21847
bfd/
* elf64-ppc.c (struct ppc_link_hash_entry): Add non_zero_localentry.
(ppc64_elf_merge_symbol): Set non_zero_localentry.
(is_elfv2_localentry0): Test non_zero_localentry.
(ppc64_elf_tls_setup): Default to --no-plt-localentry.
gold/
* powerpc.cc (Target_powerpc::scan_relocs): Default to
--no-plt-localentry.
ld/
* ld.texinfo (plt-localentry): Document.
The 64-bit ELF compression header has a reserved field. It should be
cleared to avoid random bits in it.
elfcpp/
PR gold/21857
* elfcpp.h (Chdr_write): Add put_ch_reserved.
(Chdr_write<64, true>::put_ch_reserved): New.
(Chdr_write<64, false>::put_ch_reserved): Likewise.
gold/
PR gold/21857
* compressed_output.cc (Output_compressed_section::set_final_data_size):
Call put_ch_reserved to clear the reserved field for 64-bit ELF.
GCC 4.2 fails to compile "(uint64_t) 0x800080008000" with
error: integer constant is too large for ‘long’ type
This patch adds "llu" suffix to 0x800080008000 for GCC 4.2.
* mips.cc (Mips_relocate_functions): Add "llu" suffix to
0x800080008000.
My PPC64_OPT_LOCALENTRY patch of June 1, git commit f378ab099d, and
the later gold change, git commit 7ee7ff7015, added an insn in
__glink_PLTresolve which needs a corresponding adjustment in the
eh_frame info for asynchronous exceptions to unwind correctly.
It would have been OK for both ABIs to use +5 for the advance before
restore of LR, since we can put the DW_CFA_restore_extended on any
insn after the actual restore and before the r12/r0 copy is clobbered,
but it's slightly better to delay as much as possible. There are
then more addresses where fewer CFA program insns are executed.
bfd/
* elf64-ppc.c (ppc64_elf_size_stubs): Correct advance to
restore of LR.
gold/
* powerpc.cc (glink_eh_frame_fde_64v2): Correct advance to
restore of LR.
(glink_eh_frame_fde_64v1): Advance to restore of LR at latest
possible insn.
The problem is caused by the fact that gold is relocating the stubs
for an entire output section when it processes the relocations for a
particular input section that happened to be designated as the stub
table "owner". The Relocate_task for that input section may or may not
run before the Relocate_task for another input section that contains
the code that needs the erratum fix, but doesn't "own" the stub
table. If it runs before (or might even race with) that other task, it
ends up with a copy of the unrelocated original instruction.
In other words - when calling fix_errata() from
do_relocate_sections(), gold is going through the list of errata stubs
that are associated only with that object. This routine updates the
stored original instruction and replaces it in the output view with a
branch to the stub. Later, as gold is going through the object file's
input sections, it then checks for stub tables "owned" by each input
section, and writes out all the stubs from that stub table, regardless
of what object file each stub is associated with.
Fixed by relocating the erratum stub only after the corresponding
errata spot is fixed. That is to have fix_errata() call
Stub_table::relocate_erratum_stub() for each stub.
gold/ChangeLog
2017-07-06 Han Shen <shenhan@google.com>
PR gold/21491
* aarch64.cc (Erratum_stub::invalidate_erratum_stub): New method.
(Erratum_stub::is_invalidated_erratum_stub): New method.
(Stub_table::relocate_reloc_stub): Renamed from "relocate_stub".
(Stub_table::relocate_reloc_stubs): Renamed from "relocate_stubs".
(Stub_table::relocate_erratum_stub): New method.
(AArch64_relobj::fix_errata_and_relocate_erratum_stubs): Renamed from
"fix_errata".
(Target_aarch64::relocate_reloc_stub): Renamed from "relocate_stub".
elfcpp/
* elfcpp.h (DT_PPC64_OPT): Define.
* powerpc.h (PPC64_OPT_TLS, PPC64_OPT_MULTI_TOC,
PPC64_OPT_LOCALENTRY): Define.
gold/
* options.h (General_options): Add plt_localentry.
* powerpc.cc (Target_powerpc::st_other): New function.
(Target_powerpc::plt_localentry0_, plt_localentry0_init_,
has_localentry0_): New vars.
(Target_powerpc::plt_localentry0, set_has_localentry0,
is_elfv2_localentry0): New functions.
(Target_powerpc::Branch_info::mark_pltcall): Don't set tocsave or
return true for localentry:0 calls.
(Stub_table::Plt_stub_ent::localentry0_): New var.
(Stub_table::add_plt_call_entry): Set localentry0_ and has_localentry0_.
Don't set r2save_ for localentry:0 calls.
(Output_data_glink::do_write): Save r2 in __glink_PLTresolve for elfv2.
(Target_powerpc::scan_relocs): Default plt_localentry0_.
(Target_powerpc::do_finalize_sections): Set DT_PPC64_OPT.
(Target_powerpc::Relocate::relocate): Don't require nop following
calls for localentry:0 plt calls, and don't change nop.
This adds support to gold for the tocsave relocs already supported by
ld.bfd. R_PPC64_TOCSAVE relocs are part of a scheme to move r2 saves
to the prologue of a function rather than in each plt call stub. We
don't want a compiler to always emit the r2 save, as this would be
wasted if the calls turned out to be local. See the tocsave*.s in
ld/testsuite/ld-powerpc/.
* powerpc.cc (Target_powerpc::tocsave_loc_): New var.
(Target_powerpc::mark_pltcall, add_tocsave, tocsave_loc): New functions.
(Target_powerpc::Branch_info::tocsave_): New var.
(Target_powerpc::Branch_info::mark_pltcall): New function.
(Target_powerpc::Branch_info::make_stub): Pass tocsave_ to
add_plt_call_entry.
(Stub_table::Plt_stub_ent): Make public. Add r2save_.
(Stub_table::add_plt_call_entry): Add bool tocsave_ param. Set
r2save_.
(Stub_table::find_plt_call_entry): Return Plt_stub_ent*. Adjust
use throughout.
(Stub_table::do_write): Conditionally output r2 save in plt stubs.
(Target_powerpc::Scan::local): Handle R_PPC64_TOCSAVE.
(Target_powerpc::Scan::global): Likewise.
(Target_powerpc::Relocate::relocate): Skip r2 save in plt call stub
with tocsave reloc. Replace header tocsave nop with r2 save.
* symtab.h (struct Symbol_location_hash): Make public.
I was lazy when adding indx_ to Plt_stub_ent. The field isn't part of
the key, so ought to be part of the mapped type. Make it so.
* powerpc.cc (Plt_stub_key): Rename from Plt_stub_ent. Remove indx_.
(Plt_stub_key_hash): Rename from Plt_stub_ent_hash.
(struct Plt_stub_ent): New.
(Plt_stub_entries): Map from Plt_stub_key to Plt_stub_ent. Adjust
use throughout file.
* aarch64.cc (scan_reloc_for_stub): Use plt_address_for_global to
calculate the symbol value.
(scan_reloc_section_for_stubs): Allow stubs to be created for
section symbols.
(maybe_apply_stub): Handle creating stubs for weak symbols to
match the code in scan_reloc_for_stub.
If two objects are compiled with -fPIC or -fPIE and call the same
function, two different PLT entries are created, one for each object,
but the same stub symbol name is used for both.
* powerpc.cc (Stub_table::define_stub_syms): Always include object's
uniq_ value.
TLS relaxation may change erratum 843419 sequences that those offending ADRP
instructions actually transformed into other instructions in which case there
is erratum 843419 risk anymore that we should avoid installing unnecessary
branch-to-stub.
gold/
* aarch64.cc (Insn_utilities::is_mrs_tpidr_el0): New method.
(AArch64_relobj<size, big_endian>::try_fix_erratum_843419_optimized):
Return ture for some TLS relaxed sequences.
* aarch64.cc (maybe_apply_stub): Add debug logging for looking
up stubs to undefined symbols and early return rather than
fail to look them up.
(scan_reloc_for_stub): Add debug logging for no stub creation
for undefined symbols.
gold/
PR gold/21444
* gold.cc (Target_sparc::Relocate::relocate_tls): Local
variables are final for position-independent executables. This
has to be consistent with Target_sparc::Scan::local otherwise
they will disagree as to whether local-exec is used.
gold/ChangeLog
PR gold/21430
* aarch64.cc
(AArch64_relobj::convert_input_section_to_relaxed_section):
Set the section offset to -1ULL.
(Target_aarch64::relocate_section): Adjust the view in case
of a relaxed input section.
* testsuite/Makefile.am (pr21430): New test.
* testsuite/Makefile.in: Regenerate
* testsuite/pr21430.s: New test source file.
* testsuite/pr21430.sh: New test script.
gold/
* mips.cc (Mips_got_entry::hash()): Shift addend to reduce
possibility of collisions.
(Mips_got_entry::equals): Fix case for GOT_TLS_LDM
entries.
gold/
* mips.cc (Mips_relobj::merge_processor_specific_data_): New data
member.
(Mips_relobj::merge_processor_specific_data): New method.
(Mips_relobj::do_read_symbols): Set merge_processor_specific_data_
to false, only if the input file is a binary or if object has no
contents except the section name string table and an empty symbol
table with the undefined symbol.
(Target_mips::do_finalize_sections): Refactor. Skip empty object files
for merging processor-specific data.
gold/
* mips.cc (Target_mips::Relocate::calculated_value_): New data
member.
(Target_mips::Relocate::calculate_only_): Likewise.
(Target_mips::Relocate::relocate): Handle multiple consecutive
relocations with the same offset.
gold/
* mips.cc (symbol_refs_local): Return false if a symbol
is from a dynamic object.
(Target_mips::got_section): Make _GLOBAL_OFFSET_TABLE_ STV_HIDDEN.
(Target_mips::set_gp): Refactor. Make _gp STT_NOTYPE and
STB_LOCAL.
(Target_mips::do_finalize_sections): Set _gp after all the checks
for creating .got are done.
(Target_mips::Scan::global): Remove unused code.
2017-02-15 Vladimir Radosavljevic <Vladimir.Radosavljevic@imgtec.com>
PR gold/21111
* mips.cc (Mips_relocate_functions::relhigher): New method.
(Mips_relocate_functions::relhighest): Likewise.
(mips_get_size_for_reloc): Add support for relocs: R_MIPS_HIGHER and
R_MIPS_HIGHEST.
(Target_mips::Scan::local): Add support for relocs: R_MIPS_HIGHER,
R_MIPS_HIGHEST, R_MICROMIPS_HIGHER and R_MICROMIPS_HIGHEST.
(Target_mips::Scan::global): Likewise.
(Target_mips::Scan::get_reference_flags): Likewise.
(Target_mips::Relocate::relocate): Call static methods for resolving
HIGHER and HIGHEST relocations.
gold/
* x86_64.cc (Target_x86_64::do_can_check_for_function_pointers):
Return true even when building pie binaries.
(Target_x86_64::possible_function_pointer_reloc): Check opcode
for R_X86_64_PC32 relocations.
(Target_x86_64::local_reloc_may_be_function_pointer): Pass
extra arguments to local_reloc_may_be_function_pointer.
(Target_x86_64::global_reloc_may_be_function_pointer): Likewise.
* gc.h (gc_process_relocs): Add check for STT_FUNC.
* testsuite/Makefile.am (icf_safe_pie_test): New test case.
* testsuite/Makefile.in: Regenerate.
* testsuite/icf_safe_pie_test.sh: New shell script.
gold/
* mips.cc (Mips_output_data_plt::rel_plt): Remove const from return
type.
(Target_mips::make_plt_entry): Make the sh_info field of .rel.plt
point to .plt.
gold/
PR gold/21054
* mips.cc (Mips_got_info::record_global_got_symbol): Don't add symbol
to the dynamic symbol table if it is forced to local visibility.
(Target_mips::do_finalize_sections): Don't add __RLD_MAP symbol to the
dynamic symbol table if it is forced to local visibility.