On x32, a pc-relative reference to an undef weak symbol (value 0)
with a negative addend (typically -4) generates a spurious overflow
error because Symbol_value::value() returns a 32-bit negative number
as an unsigned number, which gets zero-extended before subtracting
the PC value. This patch fixes the problem by special-casing the
negative addend, and adding it to the value after widening it to
64 bits. Symbol_value::value() does not need the addend if it's
negative, since it is only important when processing section
symbols for merge sections, where a positive addend provides the
input section offset of the merged constant.
gold/
* x86_64.cc (X86_64_relocate_functions::pcrela32_check): Fix x32
overflow checking when symbol value + addend < 0.
In order to get around the optimizer and newer compiler warnings
about shift counts, the overflow checking code had resorted to
some messy shifting, and with the never-before-seen instantiations
of the template functions, we were still running afoul of the
compiler checks.
This patch replaces those messy shift sequences with a simple
class template that provides the min and max limits for any
bit size up to 64, with a specialization for 64 that prevents
the compiler from complaining.
gold/
PR gold/19577
* reloc.h (Limits): New class.
(Bits::has_overflow32): Use min/max values from Limits.
(Bits::has_unsigned_overflow32): Likewise.
(Bits::has_signed_unsigned_overflow32): Likewise.
(Bits::has_overflow): Likewise.
(Bits::has_unsigned_overflow): Likewise.
(Bits::has_signed_unsigned_overflow64): Likewise.
The problem here is that x32 is really using 64-bit addressing,
while pretending to be 32-bit. Even though the object file format
is 32-bit, we need to do the overflow checking with 64-bit
arithmetic (because that's what the hardware will be using).
This patch overrides the pcrela32_check functions in reloc.h
with target-specific versions that do 64-bit checking.
I've also updated the test case to use -Tdata instead of adding
a huge .space directive, to reduce the size of the .o files.
gold/
PR gold/19567
* reloc.h (Relocate_functions::Overflow_check): Add comments.
* x86_64.cc (X86_64_relocate_functions): New class.
(Target_x86_64::Relocate::relocate): Use the new class.
* testsuite/Makefile.am (x86_64_overflow_pc32): Add -Tdata option.
(x32_overflow_pc32): New test case.
* testsuite/Makefile.in: Regenerate.
* testsuite/x32_overflow_pc32.sh: New script.
* testsuite/x86_64_overflow_pc32.s: Remove .space directive.
This is needed by s390 split-stack support, to distinguish call
and load-address relocations.
gold/ChangeLog:
* i386.cc (Target_i386::is_call_to_non_split): Add view and view_size
parameters.
* reloc.cc (Sized_relobj_file::split_stack_adjust_reltype): Pass view
and view_size to is_call_to_non_split.
* target.cc (Target::is_call_to_non_split): Add view and view_size
parameters.
* target.h (class Target): Likewise.
* icf.cc (get_rel_addend): New function.
(get_section_contents): Move merge section addend computation to a
new function. Ignore negative values for SHT_REL and SHT_RELA addends.
Fix bug to not read past the length of the section.
Fix bug related to addend computation for MERGE sections.
This tightens the condition under which ld optimizes PIC entry code
to non-PIC.
bfd/
* elf64-ppc.c (ppc64_elf_relocate_section): Further restrict
ELFv2 entry optimization.
gold/
* powerpc.cc (relocate): Further restrict ELFv2 entry optimization.
The stub generated during relaxation uses absolute addressing mode for
shared libraries, which is not correct. Use pc-relative addressing
instead.
gold/ChangeLog:
2016-01-15 Han Shen <shenhan@google.com>
PR gold/19472 - DSOs need pc-relative stubs.
* aarch64.cc (Reloc_stub::stub_type_for_reloc): Return
PC-relative stub type for DSOs and pie executables.
gold/
PR gold/19353
* aarch64.cc (Target_aarch64::relocate_tls): Don't insist that
we have a TLS segment for GD-to-IE optimization.
* i386.cc (Target_i386::tls_gd_to_ie): Remove tls_segment parameter.
Adjust all calls.
(Target_i386::tls_desc_gd_to_ie): Likewise.
(Target_i386::relocate_tls): Don't insist that we have a TLS segment
for TLSDESC GD-to-IE optimizations.
* x86_64.cc (Target_x86_64::tls_gd_to_ie): Remove tls_segment parameter.
Adjust all calls.
(Target_x86_64::tls_desc_gd_to_ie): Likewise.
(Target_x86_64::relocate_tls): Don't insist that we have a TLS segment
for TLSDESC GD-to-IE optimizations.
For MIPS-64, the r_info field in the relocation format is
replaced by several individual fields, including r_sym and
r_type. To enable support for this format, I've refactored
target-independent code to remove almost all uses of the r_info
field. (I've left alone a couple of routines used only for
incremental linking, which I can update if/when the MIPS target
adds support for incremental linking.)
For routines that are already templated on a Classify_reloc class
(namely, gc_process_relocs, relocate_section, and
relocate_relocs), I've extended the Classify_reloc interface to
include sh_type (which no longer needs to be a separate template
parameter) as well as get_r_sym() and get_r_type() methods for
extracting the r_sym and r_type fields. For
scan_relocatable_relocs, I've extended the
Default_scan_relocatable_relocs class by converting it to a class
template with Classify_reloc as a template parameter. For the
remaining routines that need to access r_sym, I've added a
virtual Target::get_r_sym() method with an override for the MIPS
target.
In elfcpp, I've added Mips64_rel, etc., accessor classes and
corresponding internal data structures. The MIPS target uses
these new classes within its own Mips_classify_reloc class.
The Mips64_ accessor classes also expose the r_ssym, r_type2,
and r_type3 fields from the relocation.
These changes should be functionally the same for all but the
MIPS target.
elfcpp/
* elfcpp.h (Mips64_rel, Mips64_rel_write): New classes.
(Mips64_rela, Mips64_rela_write): New classes.
* elfcpp_internal.h (Mips64_rel_data, Mips64_rela_data): New structs.
gold/
* gc.h (get_embedded_addend_size): Remove sh_type parameter.
(gc_process_relocs): Remove sh_type template parameter.
Use Classify_reloc to access r_sym, r_type, and r_addend fields.
* object.h (Sized_relobj_file::split_stack_adjust): Add target
parameter.
(Sized_relobj_file::split_stack_adjust_reltype): Likewise.
* reloc-types.h (Reloc_types::copy_reloc_addend): (SHT_REL and SHT_RELA
specializations) Remove.
* reloc.cc (Emit_relocs_strategy): Rename and move to target-reloc.h.
(Sized_relobj_file::emit_relocs_scan): Call Target::emit_relocs_scan().
(Sized_relobj_file::emit_relocs_scan_reltype): Remove.
(Sized_relobj_file::split_stack_adjust): Add target parameter.
Adjust all callers.
(Sized_relobj_file::split_stack_adjust_reltype): Likewise. Call
Target::get_r_sym() to get r_sym field from relocations.
(Track_relocs::next_symndx): Call Target::get_r_sym().
* target-reloc.h (scan_relocs): Remove sh_type template parameter;
add Classify_reloc template parameter. Use for accessing r_sym and
r_type.
(relocate_section): Likewise.
(Default_classify_reloc): New class (renamed and moved from reloc.cc).
(Default_scan_relocatable_relocs): Remove sh_type template parameter.
(Default_scan_relocatable_relocs::Reltype): New typedef.
(Default_scan_relocatable_relocs::reloc_size): New const.
(Default_scan_relocatable_relocs::sh_type): New const.
(Default_scan_relocatable_relocs::get_r_sym): New method.
(Default_scan_relocatable_relocs::get_r_type): New method.
(Default_emit_relocs_strategy): New class.
(scan_relocatable_relocs): Replace sh_type template parameter with
Scan_relocatable_relocs class. Use it to access r_sym and r_type
fields.
(relocate_relocs): Replace sh_type template parameter with
Classify_reloc class. Use it to access r_sym and r_type fields.
* target.h (Target::is_call_to_non_split): Replace r_type parameter
with pointer to relocation. Adjust all callers.
(Target::do_is_call_to_non_split): Likewise.
(Target::emit_relocs_scan): New virtual method.
(Sized_target::get_r_sym): New virtual method.
* target.cc (Target::do_is_call_to_non_split): Replace r_type parameter
with pointer to relocation.
* aarch64.cc (Target_aarch64::emit_relocs_scan): New method.
(Target_aarch64::Relocatable_size_for_reloc): Remove.
(Target_aarch64::gc_process_relocs): Use Default_classify_reloc.
(Target_aarch64::scan_relocs): Likewise.
(Target_aarch64::relocate_section): Likewise.
(Target_aarch64::Relocatable_size_for_reloc::get_size_for_reloc):
Remove.
(Target_aarch64::scan_relocatable_relocs): Use Default_classify_reloc.
(Target_aarch64::relocate_relocs): Use Default_classify_reloc.
* arm.cc (Target_arm::Arm_scan_relocatable_relocs): Remove sh_type
template parameter.
(Target_arm::emit_relocs_scan): New method.
(Target_arm::Relocatable_size_for_reloc): Replace with...
(Target_arm::Classify_reloc): ...this.
(Target_arm::gc_process_relocs): Use Classify_reloc.
(Target_arm::scan_relocs): Likewise.
(Target_arm::relocate_section): Likewise.
(Target_arm::scan_relocatable_relocs): Likewise.
(Target_arm::relocate_relocs): Likewise.
* i386.cc (Target_i386::emit_relocs_scan): New method.
(Target_i386::Relocatable_size_for_reloc): Replace with...
(Target_i386::Classify_reloc): ...this.
(Target_i386::gc_process_relocs): Use Classify_reloc.
(Target_i386::scan_relocs): Likewise.
(Target_i386::relocate_section): Likewise.
(Target_i386::scan_relocatable_relocs): Likewise.
(Target_i386::relocate_relocs): Likewise.
* mips.cc (Mips_scan_relocatable_relocs): Remove sh_type template
parameter.
(Mips_reloc_types): New class template.
(Mips_classify_reloc): New class template.
(Target_mips::Reltype): New typedef.
(Target_mips::Relatype): New typedef.
(Target_mips::emit_relocs_scan): New method.
(Target_mips::get_r_sym): New method.
(Target_mips::Relocatable_size_for_reloc): Replace with
Mips_classify_reloc.
(Target_mips::copy_reloc): Use Mips_classify_reloc.
(Target_mips::gc_process_relocs): Likewise.
(Target_mips::scan_relocs): Likewise.
(Target_mips::relocate_section): Likewise.
(Target_mips::scan_relocatable_relocs): Likewise.
(Target_mips::relocate_relocs): Likewise.
(mips_get_size_for_reloc): New function, factored out from
Relocatable_size_for_reloc::get_size_for_reloc.
(Target_mips::Scan::local): Use Mips_classify_reloc.
(Target_mips::Scan::global): Likewise.
(Target_mips::Relocate::relocate): Likewise.
* powerpc.cc (Target_powerpc::emit_relocs_scan): New method.
(Target_powerpc::Relocatable_size_for_reloc): Remove.
(Target_powerpc::gc_process_relocs): Use Default_classify_reloc.
(Target_powerpc::scan_relocs): Likewise.
(Target_powerpc::relocate_section): Likewise.
(Powerpc_scan_relocatable_reloc): Convert to class template.
(Powerpc_scan_relocatable_reloc::Reltype): New typedef.
(Powerpc_scan_relocatable_reloc::reloc_size): New const.
(Powerpc_scan_relocatable_reloc::sh_type): New const.
(Powerpc_scan_relocatable_reloc::get_r_sym): New method.
(Powerpc_scan_relocatable_reloc::get_r_type): New method.
(Target_powerpc::scan_relocatable_relocs): Use
Powerpc_scan_relocatable_reloc.
(Target_powerpc::relocate_relocs): Use Default_classify_reloc.
* s390.cc (Target_s390::emit_relocs_scan): New method.
(Target_s390::Relocatable_size_for_reloc): Remove.
(Target_s390::gc_process_relocs): Use Default_classify_reloc.
(Target_s390::scan_relocs): Likewise.
(Target_s390::relocate_section): Likewise.
(Target_s390::Relocatable_size_for_reloc::get_size_for_reloc):
Remove.
(Target_s390::scan_relocatable_relocs): Use Default_classify_reloc.
(Target_s390::relocate_relocs): Use Default_classify_reloc.
* sparc.cc (Target_sparc::emit_relocs_scan): New method.
(Target_sparc::Relocatable_size_for_reloc): Remove.
(Target_sparc::gc_process_relocs): Use Default_classify_reloc.
(Target_sparc::scan_relocs): Likewise.
(Target_sparc::relocate_section): Likewise.
(Target_sparc::Relocatable_size_for_reloc::get_size_for_reloc):
Remove.
(Target_sparc::scan_relocatable_relocs): Use Default_classify_reloc.
(Target_sparc::relocate_relocs): Use Default_classify_reloc.
* tilegx.cc (Target_tilegx::emit_relocs_scan): New method.
(Target_tilegx::Relocatable_size_for_reloc): Remove.
(Target_tilegx::gc_process_relocs): Use Default_classify_reloc.
(Target_tilegx::scan_relocs): Likewise.
(Target_tilegx::relocate_section): Likewise.
(Target_tilegx::Relocatable_size_for_reloc::get_size_for_reloc):
Remove.
(Target_tilegx::scan_relocatable_relocs): Use Default_classify_reloc.
(Target_tilegx::relocate_relocs): Use Default_classify_reloc.
* x86_64.cc (Target_x86_64::emit_relocs_scan): New method.
(Target_x86_64::Relocatable_size_for_reloc): Remove.
(Target_x86_64::gc_process_relocs): Use Default_classify_reloc.
(Target_x86_64::scan_relocs): Likewise.
(Target_x86_64::relocate_section): Likewise.
(Target_x86_64::Relocatable_size_for_reloc::get_size_for_reloc):
Remove.
(Target_x86_64::scan_relocatable_relocs): Use Default_classify_reloc.
(Target_x86_64::relocate_relocs): Use Default_classify_reloc.
* testsuite/testfile.cc (Target_test::emit_relocs_scan): New method.
gold/
PR gold/18780
* arm.cc (Target_arm::do_make_data_plt): Choose PLT generator based
on value of --long-plt flag.
(Output_data_plt_arm_standard::do_get_plt_entry_size): Moved to
Output_data_plt_arm_short.
(Output_data_plt_arm_standard::do_fill_plt_entry): Likewise.
(Output_data_plt_arm_standard::plt_entry): Likewise.
(Output_data_plt_arm_standard::do_fill_first_plt_entry): Fix
variable reference.
(Output_data_plt_arm_short): New class.
(Output_data_plt_arm_short::do_fill_plt_entry): Error out on too large
PLT offsets instead of asserting.
(Output_data_plt_arm_long): New class.
* options.h (General_options): Define --long-plt flag.
gold/
* object.cc (Sized_relobj_file::Sized_relobj_file): Initialize
output_views_.
* object.h (Object::get_output_view): New function.
(Object::do_get_output_view): New function.
(Sized_relobj_file::do_get_output_view): New function.
(Sized_relobj_file::output_views_): New data member.
* reloc.cc: (Sized_relobj_file::do_relocate): Store pointer to
output views in class object.
(Sized_relobj_file::do_get_output_view): New function.
In an fixed position executable, the entry code does not need to be
PIC and can thus lose a dependency on r12.
* powerpc.cc (Target_powerpc::Relocate::relocate): Edit ELFv2
entry code.
(Target_powerpc::relocate_relocs): Edit relocs to suit.
Some linker code editing needs to change multiple insns. In some
cases multiple relocations are involved and it is not sufficient to
make the changes independently as relocations are processed, because
doing so might lead to a partial edit. So in order to safely edit we
need all the relocations available in relocate(). Also, to emit
edited relocs corresponding to the edited code sequence we need some
way to pass information from relocate() to relocate_relocs(),
particularly if the edit depends on insns. We can't modify input
relocs in relocate() as they are mmapped PROT_READ, nor it is
particularly clean to write relocs to the output at that stage. So
add a Relocatable_relocs* field to relinfo to mark edited relocs.
Given that relocate is passed the raw reloc pointer, it makes sense to
remove the rel/rela parameter and r_type too. However, that means the
mips relocate() needs to know whether SHT_REL or SHT_RELA relocs are
being processed. So add a rel_type for mips, which also has the
benefit of removing relocate() overloading there.
This patch adds the infrastructure without making use of it.
Note that relinfo->rr will be NULL if not outputting relocations.
* object.h (struct Relocate_info): Add "rr".
* reloc.h (Relocatable_relocs::set_strategy): New accessor.
* reloc.cc (Sized_relobj_file::do_relocate_sections): Init
relinfo.rr for relocate_section and relocate_relocs.
* powerpc.cc (relocate): Add rel_type and preloc parameters.
Delete rela and r_type params, instead recalculate these from
preloc.
(relocate_relocs): Delete Relocatable_relocs* param, instead
use relinfo->rr.
* aarch64.cc: Likewise.
* arm.cc: Likewise.
* i386.cc: Likewise.
* mips.cc: Likewise.
* s390.cc: Likewise.
* sparc.cc: Likewise.
* target.h: Likewise.
* tilegx.cc: Likewise.
* x86_64.cc: Likewise.
* testsuite/testfile.cc: Likewise.
* target-reloc.h (relocate_section): Adjust to suit.
(apply_relocation, relocate_relocs): Likewise.
gold/
* object.cc (Sized_relobj::do_for_all_local_got_entries): Use
Local_got_entry_key for searching in local_got_offsets_.
* object.h (class Local_got_entry_key): New class.
(Relobj::local_has_got_offset): New overloaded method.
(Relobj::local_got_offset): Likewise.
(Relobj::set_local_got_offset): Likewise.
(Relobj::do_local_has_got_offset): Add addend argument.
(Relobj::do_local_got_offset): Likewise.
(Relobj::do_set_local_got_offset): Likewise.
(Sized_relobj::do_local_has_got_offset): Add addend argument, and use
Local_got_entry_key for searching through local_got_offsets_.
(Sized_relobj::do_local_got_offset): Likewise.
(Sized_relobj::do_set_local_got_offset): Likewise.
(Sized_relobj::Local_got_offsets): Change type of the key from
unsigned int to Local_got_entry_key, and add hash and equal_to.
* output.cc (Got_entry::write): Take addend into account for
calculating value of the local symbol for GOT.
(Output_data_got::add_local): New definition of overloaded method.
(Output_data_got::add_local_with_rel): Likewise.
(Output_data_got::add_local_pair_with_rel): Likewise.
* output.h (Output_data_got::add_local): New declaration of overloaded
method.
Gold does not support all the emulations that Gnu ld does, and supports
only one spelling per target. The -m option is used only in the rare case
where there are no ELF input files, and we produce an empty output file.
In those cases, users are expected to supply a -m option naming one of
the supported emulations. In the many cases where a build script provides
an unnecessary -m option naming an emulation that gold does not support,
we will simply ignore the option, as we did before the reverted patch.
gold/
PR gold/19119
PR gold/19172
PR gold/19197
Revert commit 6457197210:
2015-10-16 H.J. Lu <hongjiu.lu@intel.com>
* options.h (General_options): Remove "obsolete" from -m.
* parameters.cc (set_parameters_target): Check if input target
is compatible with output emulation set by "-m emulation".
With --no-apply-dynamic-relocs on aarch64 targets, gold will not apply
link-time values for absolute relocations that become dynamic relocations.
This provides a workaround for broken Android dynamic linkers that use
the link-time value as an extra addend to the relocation.
gold/
PR gold/19163
* aarch64.cc (Target_aarch64::Relocate::relocate): Don't apply
certain relocations if --no-apply-dynamic-relocs is set.
* options.h (--apply-dynamic-relocs): New aarch64-specific option.
The GOT entry size is target-dependent. This patch adds a got_entry_size
function to Sized_target class so that a target can provide a value
different from default.
PR gold/19184
* incremental.cc (Got_plt_view_info): Add got_entry_size.
(Local_got_offset_visitor::visit): Replace got_entry_size_
with info_.got_entry_size.
(Local_got_offset_visitor::got_entry_size_): Removed.
(Global_got_offset_visitor::visit): Replace got_entry_size_
with info_.got_entry_size.
(Global_got_offset_visitor::got_entry_size_): Removed.
(Output_section_incremental_inputs::write_got_plt): Initialize
view_info.got_entry_size.
* target.h (Sized_target::got_entry_size): New virtual function.
* x86_64.cc (Target_x86_64::got_entry_size): New function.