This patch updates gold to treat the R_386_GOT32X relocation proposed in
https://groups.google.com/forum/#!topic/ia32-abi/GbJJskkid4I
the same as R_386_GOT32. FIXME: Gold should perform the transformations
as suggested.
elfcpp/
* i386.h (R_386_GOT32X): New.
gold/
* i386.cc (Target_i386::Scan::get_reference_flags(): Treat
R_386_GOT32X the same as R_386_GOT32.
(Target_i386::Scan::local): Likewise.
(Target_i386::Scan::possible_function_pointer_reloc): Likewise.
(Target_i386::Scan::global): Likewise.
(Target_i386::Relocate::relocate): Likewise.
(Target_i386::Relocatable_size_for_reloc::get_size_for_reloc):
Likewise.
There are two cases to support, one with an SIB-form (6-byte) LEA,
the other with a 5-byte LEA and a NOP after the call __tls_get_addr.
Gold did not yet support the second case. This patch adds that
support.
gold/
PR gold/18106
* i386.cc (Target_i386::Relocate::tls_gd_to_ie): Fix support for
non-SIB form of lea, with nop after the call.
to access a global as it expects a GOTPCREL relocation. This is really not
necessary as the linker could use a copy relocation to get around it. This
patch enables copy relocations with pie.
Context:
This is useful because currently the GCC compiler with option -fpie makes
every extern global access go through the GOT. That is because the compiler
cannot tell if a global will end up being defined in the executable or not
and is conservative. This ends up hurting performance when the binary is linked
as mostly static where most of the globals do end up being defined in the
executable. By allowing copy relocs with fPIE, the compiler need not generate
a GOTPCREL(GOT access) for any global access. It can safely assume that all
globals will be defined in the executable and generate a PC-relative access
instead. Gold can then create a copy reloc for only the undefined globals.
gold/
* symtab.h (may_need_copy_reloc): Remove check for position independent
code.
* x86_64.cc (Target_x86_64<size>::Scan::global): Add check for no
position independence before pc absolute may_need_copy_reloc call.
Add check for executable output befor pc relative may_need_copy_reloc
call.
* i386.cc: Ditto.
* arm.cc: Ditto.
* sparc.cc: Ditto.
* tilegx.cc: Ditto.
* powerpc.cc: Add check for no position independence before
may_need_copy_reloc calls.
* testsuite/pie_copyrelocs_test.cc: New file.
* testsuite/pie_copyrelocs_shared_test.cc: New file.
* Makefile.am (pie_copyrelocs_test): New test.
* Makefile.in: Regenerate.
is no PLT.
gold/
PR gold/16900
* i386.cc (Output_data_got_plt_i386): New class.
(Output_data_plt_i386::Output_data_plt_i386): Change type of got_plt
parameter. Change all callers.
(Output_data_plt_i386::layout_): Remove.
(Output_data_plt_i386::got_plt_): Change type.
(Target_i386::got_plt_): Change type. Change all references.
(Target_i386::got_section): Create instance of new class.
(Output_data_got_plt_i386::do_write): New function.
* x86_64.cc (Output_data_got_plt_x86_64): New class.
(Output_data_plt_x86_64::Output_data_plt_x86_64): Change type of got_plt
parameter. Change all callers.
(Output_data_plt_x86_64::layout_): Remove.
(Output_data_plt_x86_64::got_plt_): Change type.
(Target_x86_64::got_plt_): Change type. Change all references.
(Target_x86_64::got_section): Create instance of new class.
(Output_data_got_plt_x86_64::do_write): New function.
(Output_data_plt_x86_64::do_write): Don't write reserved words in GOT.
(Target_x86_64<size>::init_got_plt_for_update): Create instance of new
class.
against symbols in discarded sections. Pass is_discarded
param.
* arm.cc, * i386.cc, * sparc.cc, * x86_64.cc (Target_*::Scan::local):
Add is_discarded param.
* powerpc (Target_powerpc::Scan::local): Likewise. Use
is_discarded to flag opd entry as discarded. Don't emit dyn
relocs on such entries.
(Target_powerpc::Scan::global): Similarly detect and handle
such opd entries.
(Powerpc_relobj): Replace opd_ent_shndx_ and opd_ent_off_ with
opd_ent_. Update all uses.
(Powerpc_relobj::get_opd_discard, set_opd_discard): New functions.
(Target_powerpc::relocate_section): Zero out discarded opd
entry relocs.
* configure: Regenerate.
gold/
* nacl.cc: New file.
* nacl.h: New file.
* Makefile.am (CCFILES, HFILES): Add them.
* Makefile.in: Regenerate.
* i386.cc (Output_data_plt_i386_nacl): New class.
(Output_data_plt_i386_nacl_exec): New class.
(Output_data_plt_i386_nacl_dyn): New class.
(Target_i386_nacl): New class.
(Target_selector_i386_nacl): New class.
(target_selector_i386): Use it instead of Target_selector_i386.
* x86_64.cc (Output_data_plt_x86_64_nacl): New class.
(Target_x86_64_nacl): New class.
(Target_selector_x86_64_nacl): New class.
(target_selector_x86_64, target_selector_x32): Use it instead of
Target_selector_x86_64.
* arm.cc (Output_data_plt_arm_nacl): New class.
(Target_arm_nacl): New class.
(Target_selector_arm_nacl): New class.
(target_selector_arm, target_selector_armbe): Use it instead of
Target_selector_arm.
* target-select.cc (select_target): Take new Input_file* and off_t
arguments, pass them on to recognize method of selector.
* object.cc (make_elf_sized_object): Update caller.
* parameters.cc (parameters_force_valid_target): Likewise.
* incremental.cc (make_sized_incremental_binary): Likewise.
* target-select.h: Update decl.
(Target_selector::recognize): Take new Input_file* argument,
pass it on to do_recognize.
(Target_selector::do_recognize): Take new Input_file* argument.
* freebsd.h (Target_selector_freebsd::do_recognize): Likewise.
* powerpc.cc (Target_selector_powerpc::do_recognize): Likewise.
* sparc.cc (Target_selector_sparc::do_recognize): Likewise.
* testsuite/testfile.cc (Target_selector::do_recognize): Likewise.
* target.h (Target::Target_info): New members isolate_execinstr
and rosegment_gap.
(Target::isolate_execinstr, Target::rosegment_gap): New methods.
* arm.cc (Target_arm::arm_info): Update initializer.
* i386.cc (Target_i386::i386_info): Likewise.
* powerpc.cc (Target_powerpc::powerpc_info): Likewise.
* sparc.cc (Target_sparc::sparc_info): Likewise.
* x86_64.cc (Target_x86_64::x86_64_info): Likewise.
* testsuite/testfile.cc (Target_test::test_target_info): Likewise.
* layout.cc (Layout::attach_allocated_section_to_segment):
Take new const Target* argument. If target->isolate_execinstr(), act
like --rosegment.
(Layout::find_first_load_seg): Take new const Target* argument;
if target->isolate_execinstr(), reject PF_X segments.
(Layout::relaxation_loop_body): Update caller.
(Layout::set_segment_offsets): If target->isolate_execinstr(),
reset file offset to zero when we hit LOAD_SEG, and then do a second
loop over the segments before LOAD_SEG to reassign offsets after
addresses have been determined. Handle target->rosegment_gap().
(Layout::attach_section_to_segment): Take new const Target* argument;
pass it to attach_allocated_section_to_segment.
(Layout::make_output_section): Update caller.
(Layout::attach_sections_to_segments): Take new const Target* argument;
pass it to attach_section_to_segment.
* gold.cc (queue_middle_tasks): Update caller.
* layout.h (Layout): Update method decls with new arguments.
* arm.cc (Target_arm::Target_arm): Take optional argument for the
Target_info pointer to use.
(Target_arm::do_make_data_plt): New virtual method.
(Target_arm::make_data_plt): New method that calls it.
(Target_arm::make_plt_entry): Use it.
(Output_data_plt_arm::Output_data_plt_arm): Take additional argument
for the section alignment.
(Output_data_plt_arm::do_first_plt_entry_offset): New abstract virtual
method.
(Output_data_plt_arm::first_plt_entry_offset): Call it.
(Output_data_plt_arm::do_get_plt_entry_size): New abstract virtual
method.
(Output_data_plt_arm::get_plt_entry_size): Call it.
(Output_data_plt_arm::do_fill_plt_entry): New abstract virtual method.
(Output_data_plt_arm::fill_plt_entry): New method that calls it.
(Output_data_plt_arm::do_fill_first_plt_entry): New abstract virtual
method.
(Output_data_plt_arm::fill_first_plt_entry): New method that calls it.
(Output_data_plt_arm::set_final_data_size): Use get_plt_entry_size
method instead of sizeof(plt_entry).
(Output_data_plt_arm::add_entry): Likewise.
Use first_plt_entry_offset method instead of sizeof(first_plt_entry).
(Target_arm::first_plt_entry_offset): Call method on this->plt_ rather
than static method.
(Target_arm::plt_entry_size): Likewise.
(Output_data_plt_arm::first_plt_entry, Output_data_plt_arm::plt_entry):
Move to ...
(Output_data_plt_arm_standard): ... here, new class.
(Output_data_plt_arm::do_write): Move guts of PLT filling to...
(Output_data_plt_arm_standard::do_fill_first_plt_entry): ... here ...
(Output_data_plt_arm_standard::do_fill_plt_entry): ... and here.
* x86_64.cc (Output_data_plt_x86_64::Output_data_plt_x86_64):
Take additional argument for the PLT entry size.
(Output_data_plt_x86_64::get_tlsdesc_plt_offset):
Use get_plt_entry_size method rather than plt_entry_size variable.
(Output_data_plt_x86_64::reserve_slot): Likewise.
(Output_data_plt_x86_64::do_adjust_output_section): Likewise.
(Output_data_plt_x86_64::add_entry): Likewise.
(Output_data_plt_x86_64::add_local_ifunc_entry): Likewise.
(Output_data_plt_x86_64::address_for_global): Likewise.
(Output_data_plt_x86_64::address_for_local): Likewise.
(Output_data_plt_x86_64::set_final_data_size): Likewise.
(Output_data_plt_x86_64::first_plt_entry_offset): Likewise.
Make method non-static.
(Output_data_plt_x86_64::do_get_plt_entry_size): New abstract virtual
method.
(Output_data_plt_x86_64::get_plt_entry_size): Just call that.
(Output_data_plt_x86_64::do_add_eh_frame): New abstract virtual method.
(Output_data_plt_x86_64::add_eh_frame): New method to call it.
(Output_data_plt_x86_64::do_fill_first_plt_entry): New abstract
virtual method.
(Output_data_plt_x86_64::fill_first_plt_entry): New method to call it.
(Output_data_plt_x86_64::do_fill_plt_entry): New abstract
virtual method.
(Output_data_plt_x86_64::fill_plt_entry): New method to call it.
(Output_data_plt_x86_64::do_fill_tlsdesc_entry): New abstract
virtual method.
(Output_data_plt_x86_64::fill_tlsdesc_entry): New method to call it.
(Output_data_plt_x86_64::plt_entry_size)
(Output_data_plt_x86_64::first_plt_entry)
(Output_data_plt_x86_64::plt_entry)
(Output_data_plt_x86_64::tlsdesc_plt_entry)
(Output_data_plt_x86_64::plt_eh_frame_fde_size)
(Output_data_plt_x86_64::plt_eh_frame_fde): Move to ...
(Output_data_plt_x86_64_standard): ... here, new class.
(Target_x86_64::Target_x86_64): Take optional argument for the
Target_info pointer to use.
(Target_x86_64::do_make_data_plt): New virtual method.
(Target_x86_64::make_data_plt): New method to call it.
(Target_x86_64::init_got_plt_for_update): Use that.
Call this->plt_->add_eh_frame method here.
(Output_data_plt_x86_64::init): Don't do add_eh_frame_for_plt here.
(Target_x86_64::first_plt_entry_offset): Call method on this->plt_
rather than static method.
(Target_x86_64::plt_entry_size): Likewise.
(Output_data_plt_x86_64::do_write): Use get_plt_entry_size method
rather than plt_entry_size variable. Move guts of PLT filling to...
(Output_data_plt_x86_64_standard::do_fill_first_plt_entry): ... here ...
(Output_data_plt_x86_64_standard::do_fill_plt_entry): ... and here ...
(Output_data_plt_x86_64_standard::do_fill_tlsdesc_entry): ... and here.
* i386.cc (Output_data_plt_i386::Output_data_plt_i386): Take
additional argument for the section alignment.
Don't do add_eh_frame_for_plt here.
(Output_data_plt_i386::first_plt_entry_offset): Make the method
non-static. Use get_plt_entry_size method rather than plt_entry_size
variable.
(Output_data_plt_i386::do_get_plt_entry_size): New abstract virtual
method.
(Output_data_plt_i386::get_plt_entry_size): Call it.
(Output_data_plt_i386::do_add_eh_frame): New abstract virtual method.
(Output_data_plt_i386::add_eh_frame): New method to call it.
(Output_data_plt_i386::do_fill_first_plt_entry): New abstract virtual
method.
(Output_data_plt_i386::fill_first_plt_entry): New method to call it.
(Output_data_plt_i386::do_fill_plt_entry): New abstract virtual
method.
(Output_data_plt_i386::fill_plt_entry): New method to call it.
(Output_data_plt_i386::set_final_data_size): Use get_plt_entry_size
method instead of plt_entry_size.
(Output_data_plt_i386::plt_entry_size)
(Output_data_plt_i386::plt_eh_frame_fde_size)
(Output_data_plt_i386::plt_eh_frame_fde): Move to ...
(Output_data_plt_i386_standard): ... here, new class.
(Output_data_plt_i386_exec): New class.
(Output_data_plt_i386::exec_first_plt_entry): Move to ...
(Output_data_plt_i386_exec::first_plt_entry): ... here.
(Output_data_plt_i386::exec_plt_entry): Move to ...
(Output_data_plt_i386_exec::plt_entry): ... here.
(Output_data_plt_i386_dyn): New class.
(Output_data_plt_i386::first_plt_entry): Move to ...
(Output_data_plt_i386_dyn::first_plt_entry): ... here.
(Output_data_plt_i386::dyn_plt_entry): Move to ...
(Output_data_plt_i386_dyn::plt_entry): ... here.
(Target_i386::Target_i386): Take optional argument for the Target_info
pointer to use.
(Target_i386::do_make_data_plt): New virtual method.
(Target_i386::make_data_plt): New method to call it.
(Target_i386::make_plt_section): Use that.
Call this->plt_->add_eh_frame method here.
(Output_data_plt_i386::add_entry): Use get_plt_entry_size method
rather than plt_entry_size variable.
(Output_data_plt_i386::add_local_ifunc_entry): Likewise.
(Output_data_plt_i386::address_for_local): Likewise.
(Output_data_plt_i386::do_write): Likewise.
Move guts of PLT filling to...
(Output_data_plt_i386_exec::do_fill_first_plt_entry): ... here ...
(Output_data_plt_i386_exec::do_fill_plt_entry): ... and here ...
(Output_data_plt_i386_dyn::do_fill_first_plt_entry): ... and here ...
(Output_data_plt_i386_dyn::do_fill_plt_entry): ... and here.
Change-Id: Id24b95600489835ff5e860a39c147203d4380c2b
(Output_data_plt_i386::Output_data_plt_i386): Initialize layout_.
(Output_data_plt_i386::do_write): Write address of .dynamic
section to first entry in .got.plt section.
* x86_64.cc (class Output_data_plt_x86_64): Add layout_ field.
(Output_data_plt_x86_64::Output_data_plt_x86_64) [both versions]:
Initialize layout_.
(Output_data_plt_x86_64::do_write): Write address of .dynamic
section to first entry in .got.plt section.
* layout.h (Layout::dynamic_section): New function.
* i386.cc (Target_i386::Scan::global): For a GOT reloc, use a
GLOB_DAT relocation rather than a RELATIVE relocation for a
protected symbol when creating a shared library.
* x86_64.cc (Target_x86_64::Scan::global): Likewise.
* testsuite/protected_1.cc (f2, get_f2_addr): New functions.
* testsuite/protected_main_1.cc (main): Test that protected
function has same address.
* target-reloc.h (issue_undefined_symbol_error): New inline
function, broken out of relocate_section.
(relocate_section): Call issue_undefined_symbol_error.
* i386.cc (Target_i386::Relocate::relocate_tls): Don't crash if
there is no TLS segment if we are about to issue an undefined
symbol error.
* x86_64.cc (Target_x86_64::relocate_tls): Likewise.
* resolve.cc (Symbol_table::should_override): Add fromtype
parameter. Change all callers. Give error when linking together
TLS and non-TLS symbol.
(Symbol_table::should_override_with_special): Add fromtype
parameter. Change all callers.
* i386.cc (Target_i386::Relocate::relocate_tls): Don't crash if
there is no TLS segment if we have reported some errors.
* x86_64.cc (Target_x86_64::relocate_tls): Likewise.
* target.h (Target::plt_address_for_global): New function.
(Target::plt_address_for_local): New function.
(Target::plt_section_for_global): Remove.
(Target::plt_section_for_local): Remove.
(Target::do_plt_address_for_global): New virtual function.
(Target::do_plt_address_for_local): New virtual function.
(Target::do_plt_section_for_global): Remove.
(Target::do_plt_section_for_local): Remove.
(Target::register_global_plt_entry): Add Symbol_table and Layout
parameters.
* output.cc (Output_data_got::Got_entry::write): Use
plt_address_for_global and plt_address_for_local.
* layout.cc (Layout::add_target_dynamic_tags): Use size and
address of output section.
* i386.cc (class Output_data_plt_i386): Add irelative_rel_,
got_irelative_, and irelative_count_ fields. Update
declarations.
(Output_data_plt_i386::has_irelative_section): New function.
(Output_data_plt_i386::entry_count): Add irelative_count_.
(Output_data_plt_i386::set_final_data_size): Likewise.
(class Target_i386): Add got_irelative_ and rel_irelative_
fields. Update declarations.
(Target_i386::Target_i386): Initialize new fields.
(Target_i386::do_plt_address_for_global): New function replacing
do_plt_section_for_global.
(Target_i386::do_plt_address_for_local): New function replacing
do_plt_section_for_local.
(Target_i386::got_section): Create got_irelative_.
(Target_i386::rel_irelative_section): New function.
(Output_data_plt_i386::Output_data_plt_i386): Initialize new
fields. Don't define __rel_iplt_{start,end}.
(Output_data_plt_i386::add_entry): Add symtab and layout
parameters. Change all callers. Use different PLT and GOT for
IFUNC symbols.
(Output_data_plt_i386::add_local_ifunc_entry): Add symtab and
layout parameters. Change all callers. Use different PLT and
GOT.
(Output_data_plt_i386::rel_tls_desc): Fix formatting.
(Output_data_plt_i386::rel_irelative): New function.
(Output_data_plt_i386::address_for_global): New function.
(Output_data_plt_i386::address_for_local): New function.
(Output_data_plt_i386::do_write): Write out IRELATIVE area. Use
IRELATIVE GOT when changing IFUNC GOT entries.
(Target_i386::Scan::global): Use IRELATIVE GOT for IRELATIVE
reloc.
(Target_i386::do_finalize_sections): Create the __rel_iplt symbols
if we didn't create an IRELATIVE GOT.
(Target_i386::Relocate::relocate): Use plt_address_for_global and
plt_address_for_local.
(Target_i386::do_dynsym_value): Use plt_address_for_global.
* x86_64.cc (class Output_data_plt_x86_64): Add irelative_rel_,
got_irelative_, and irelative_count_ fields. Update
declarations.
(Output_data_plt_x86_64::Output_data_plt_x86_64) [both versions]:
Initialize new fields. Remove symtab parameter. Change all
callers.
(Output_data_plt_x86_64::get_tlsdesc_plt_offset): Add
irelative_count_.
(Output_data_plt_x86_64::has_irelative_section): New function.
(Output_data_plt_x86_64::entry_count): Add irelative_count_.
(class Target_x86_64): Add got_irelative_ and rel_irelative_
fields. Update declarations.
(Target_x86_64::Target_x86_64): Initialize new fields.
(Target_x86_64::do_plt_address_for_global): New function replacing
do_plt_section_for_global.
(Target_x86_64::do_plt_address_for_local): New function replacing
do_plt_section_for_local.
(Target_x86_64::got_section): Create got_irelative_.
(Target_x86_64::rela_irelative_section): New function.
(Output_data_plt_x86_64::init): Remove symtab parameter. Change
all callers. Don't create __rel_iplt_{start,end}.
(Output_data_plt_x86_64::add_entry): Add symtab and layout
parameters. Change all callers. Use different PLT and GOT for
IFUNC symbols.
(Output_data_plt_x86_64::add_local_ifunc_entry): Add symtab and
layout parameters. Change all callers. Use different PLT and
GOT.
(Output_data_plt_x86_64::add_relocation): Add symtab and layout
parameters. Change all callers. Use different PLT and GOT for
IFUNC symbols.
(Output_data_plt_x86_64::rela_tlsdesc): Fix formatting.
(Output_data_plt_x86_64::rela_irelative): New function.
(Output_data_plt_x86_64::address_for_global): New function.
(Output_data_plt_x86_64::address_for_local): New function.
(Output_data_plt_x86_64::set_final_data_size): Likewise.
(Output_data_plt_x86_64::do_write): Write out IRELATIVE area.
(Target_x86_64::init_got_plt_for_update): Create got_irelative_.
(Target_x86_64::register_global_plt_entry): Add symtab and layout
parameters.
(Target_x86_64::Scan::global): Use IRELATIVE GOT for IRELATIVE
reloc.
(Target_x86_64::do_finalize_sections): Create the __rela_iplt
symbols if we didn't create an IRELATIVE GOT.
(Target_x86_64::Relocate::relocate): Use plt_address_for_global and
plt_address_for_local.
(Target_x86_64::do_dynsym_value): Use plt_address_for_global.
* testsuite/ifuncvar1.c: New test file.
* testsuite/ifuncvar2.c: New test file.
* testsuite/ifuncvar3.c: New test file.
* testsuite/Makefile.am (check_PROGRAMS): Add ifuncvar.
(ifuncvar1_pic.o, ifuncvar2_pic.o, ifuncvar.so): New targets.
(ifuncvar_SOURCES, ifuncvar_DEPENDENCIES): New variables.
(ifuncvar_LDFLAGS, ifuncvar_LDADD): New variables.
* testsuite/Makefile.in: Rebuild.
* ehframe.cc (Eh_frame_hdr::get_fde_pc): Handle DW_EH_PE_datarel.
Assert if we see DW_EH_PE_indirect.
* target.h (Target::ehframe_datarel_base): New function.
(Target::do_ehframe_datarel_base): New target function.
* i386.cc (Target_i386::do_ehframe_datarel_base): New function.
* x86_64.cc (Target_x86_64::do_ehframe_datarel_base): New
function.
* options.h (class General_options): Add
--ld-generated-unwind-info.
* ehframe.cc (Fde::write): Add address parameter. Change all
callers. If associated with PLT, fill in address and size.
(Cie::set_output_offset): Only add merge mapping if there is an
object.
(Cie::write): Add address parameter. Change all callers.
(Eh_frame::add_ehframe_for_plt): New function.
* ehframe.h (class Fde): Update declarations. Move shndx_ and
input_offset_ fields into union u_, with new plt field.
(Fde::Fde): Adjust for new union field.
(Fde::Fde) [Output_data version]: New constructor.
(Fde::add_mapping): Only add merge mapping if there is an object.
(class Cie): Update declarations.
(class Eh_frame): Declare add_ehframe_for_plt.
* layout.cc (Layout::layout_eh_frame): Break out code into
make_eh_frame_section, and call it.
(Layout::make_eh_frame_section): New function.
(Layout::add_eh_frame_for_plt): New function.
* layout.h (class Layout): Update declarations.
* merge.cc (Merge_map::add_mapping): Add assertion.
* i386.cc: Include "dwarf.h".
(class Output_data_plt_i386): Make first_plt_entry,
dyn_first_plt_entry, exec_plt_entry, and dyn_plt_entry const. Add
plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie,
and plt_eh_frame_fde.
(Output_data_plt_i386::Output_data_plt_i386): Align to 16-byte
boundary. Call add_eh_frame_for_plt if appropriate.
* x86_64.cc: Include "dwarf.h".
(class Output_data_plt_x86_64): Align to 16-byte boundary. Make
first_plt_entry, plt_entry and tlsdesc_plt_entry const. Add
plt_eh_frame_cie_size, plt_eh_frame_fde_size, plt_eh_frame_cie,
and plt_eh_frame_fde.
(Output_data_plt_x86_64::init): Call add_eh_frame_for_plt if
appropriate.
* target-select.cc (Target_selector::Target_selector): Add
emulation parameter. Change all callers.
(select_target_by_bfd_name): Rename from select_target_by_name.
Change all callers.
(select_target_by_emulation): New function.
(supported_emulation_names): New function.
* target-select.h (class Target_selector): Add emulation_ field.
Update declarations.
(Target_selector::recognize_by_bfd_name): Rename from
recognize_by_name. Change all callers.
(Target_selector::supported_bfd_names): Rename from
supported_names. Change all callers.
(Target_selector::recognize_by_emulation): New function.
(Target_selector::supported_emulations): New function.
(Target_selector::emulation): New function.
(Target_selector::do_recognize_by_bfd_name): Rename from
do_recognize_by_name. Change all callers.
(Target_selector::do_supported_bfd_names): Rename from
do_supported_names. Change all callers.
(Target_selector::do_recognize_by_emulation): New function.
(Target_selector::do_supported_emulations): New function.
(select_target_by_bfd_name): Change name in declaration.
(select_target_by_emulation): Declare.
(supported_emulation_names): Declare.
* parameters.cc (parameters_force_valid_target): Try to find
target based on emulation from -m option.
* options.h (class General_options): Change doc string for -m.
* options.cc (help): Print emulations.
(General_options::parse_V): Likewise.
* freebsd.h (Target_selector_freebsd::Target_selector_freebsd):
Add emulation parameter. Change all callers.
info; adjust display of GOT entries.
* incremental.cc (Sized_incremental_binary::setup_readers): Allocate
vector of input objects; remove file_status_.
(Sized_incremental_binary::do_reserve_layout): Remove file_status_.
(Sized_incremental_binary::do_process_got_plt): Adjust calls to
got_plt reader; call target hooks to reserve GOT entries.
(Output_section_incremental_inputs::set_final_data_size): Adjust size
of input file info header and GOT info entry.
(Output_section_incremental_inputs::write_info_blocks): Write dynamic
relocation info.
(Got_plt_view_info::got_descriptor): Remove.
(Got_plt_view_info::sym_index): New data member.
(Got_plt_view_info::input_index): New data member.
(Local_got_offset_visitor::visit): Write input file index.
(Global_got_offset_visitor::visit): Write 0 for input file index.
(Global_symbol_visitor_got_plt::operator()): Replace got_descriptor
with sym_index and input_index.
(Output_section_incremental_inputs::write_got_plt): Adjust size of
incremental info GOT entry; replace got_descriptor with input_index.
(Sized_relobj_incr::Sized_relobj_incr): Adjust initializers; record
map from input file index to object.
(Sized_relobj_incr::do_layout): Replace direct data member reference
with accessor function.
(Sized_relobj_incr::do_for_all_local_got_entries): Move to base class.
* incremental.h (Incremental_input_entry_reader::get_symbol_offset):
Adjust size of input file info header.
(Incremental_input_entry_reader::get_first_dyn_reloc): New function.
(Incremental_input_entry_reader::get_dyn_reloc_count): New function.
(Incremental_input_entry_reader::get_input_section): Adjust size of
input file info header.
(Incremental_got_plt_reader::Incremental_got_plt_reader): Adjust size
of incremental info GOT entry.
(Incremental_got_plt_reader::get_got_desc): Remove.
(Incremental_got_plt_reader::get_got_symndx): New function.
(Incremental_got_plt_reader::get_got_input_index): New function.
(Sized_incremental_binary::Sized_incremental_binary): Remove
file_status_; add input_objects_.
(Sized_incremental_binary::~Sized_incremental_binary): Remove.
(Sized_incremental_binary::set_file_is_unchanged): Remove.
(Sized_incremental_binary::file_is_unchanged): Remove.
(Sized_incremental_binary::set_input_object): New function.
(Sized_incremental_binary::input_object): New function.
(Sized_incremental_binary::file_status_): Remove.
(Sized_incremental_binary::input_objects_): New data member.
(Sized_relobj_incr): Rename Sized_incr_relobj to this; adjust all
references.
(Sized_relobj_incr::invalid_address): Move to base class.
(Sized_relobj_incr::is_output_section_offset_invalid): Move to base
class.
(Sized_relobj_incr::do_output_section_offset): Likewise.
(Sized_relobj_incr::do_for_all_local_got_entries): Likewise.
(Sized_relobj_incr::section_offsets_): Likewise.
* object.cc (Sized_relobj::do_for_all_local_got_entries): New
function.
(Sized_relobj_file::Sized_relobj_file): Remove local_got_offsets_.
(Sized_relobj_file::layout_section): Replace refs to section_offsets_
with accessor function.
(Sized_relobj_file::do_layout): Likewise.
(Sized_relobj_file::do_layout_deferred_sections): Likewise.
(Sized_relobj_file::do_for_all_local_got_entries): Move to base class.
(Sized_relobj_file::compute_final_local_value): Replace refs to
section_offsets_ with accessor function.
(Sized_relobj_file::do_finalize_local_symbols): Likewise.
* object.h (Relobj::Relobj): Initialize new data members.
(Relobj::add_dyn_reloc): New function.
(Relobj::first_dyn_reloc): New function.
(Relobj::dyn_reloc_count): New function.
(Relobj::first_dyn_reloc_): New data member.
(Relobj::dyn_reloc_count_): New data member.
(Sized_relobj): Rename Sized_relobj_base to this; adjust all
references.
(Sized_relobj::Address): New typedef.
(Sized_relobj::invalid_address): Move here from child class.
(Sized_relobj::Sized_relobj): Initialize new data members.
(Sized_relobj::sized_relobj): New function.
(Sized_relobj::is_output_section_offset_invalid): Move here from
child class.
(Sized_relobj::get_output_section_offset): Likewise.
(Sized_relobj::local_has_got_offset): Likewise.
(Sized_relobj::local_got_offset): Likewise.
(Sized_relobj::set_local_got_offset): Likewise.
(Sized_relobj::do_for_all_local_got_entries): Likewise.
(Sized_relobj::clear_got_offsets): New function.
(Sized_relobj::section_offsets): Move here from child class.
(Sized_relobj::do_output_section_offset): Likewise.
(Sized_relobj::do_set_section_offset): Likewise.
(Sized_relobj::Local_got_offsets): Likewise.
(Sized_relobj::local_got_offsets_): Likewise.
(Sized_relobj::section_offsets_): Likewise.
(Sized_relobj_file): Rename Sized_relobj to this; adjust all
references.
(Sized_relobj_file::is_output_section_offset_invalid): Move to base
class.
(Sized_relobj_file::sized_relobj): New function
(Sized_relobj_file::local_has_got_offset): Move to base class.
(Sized_relobj_file::local_got_offset): Likewise.
(Sized_relobj_file::set_local_got_offset): Likewise.
(Sized_relobj_file::get_output_section_offset): Likewise.
(Sized_relobj_file::do_for_all_local_got_entries): Likewise.
(Sized_relobj_file::do_output_section_offset): Likewise.
(Sized_relobj_file::do_set_section_offset): Likewise.
(Sized_relobj_file::Local_got_offsets): Likewise.
(Sized_relobj_file::local_got_offsets_): Likewise.
(Sized_relobj_file::section_offsets_): Likewise.
* output.cc (Output_reloc::Output_reloc): Adjust type of relobj
(all constructors).
(set_needs_dynsym_index): Convert relobj to derived class pointer.
(Output_reloc::get_symbol_index): Likewise.
(Output_reloc::local_section_offset): Likewise.
(Output_reloc::get_address): Likewise.
(Output_reloc::symbol_value): Likewise.
(Output_data_got::reserve_slot): Move to class definition.
(Output_data_got::reserve_local): New function.
(Output_data_got::reserve_slot_for_global): Remove.
(Output_data_got::reserve_global): New function.
* output.h (Output_reloc::Output_reloc): Adjust type of relobj
(all constructors, two instantiations).
(Output_reloc::get_relobj): New function (two instantiations).
(Output_reloc::u1_.relobj, Output_reloc::u2_.relobj): Adjust type.
(Output_data_reloc_base::add): Convert relobj to derived class pointer.
(Output_data_reloc::add_global): Adjust type of relobj.
(Output_data_reloc::add_global_relative): Likewise.
(Output_data_reloc::add_symbolless_global_addend): Likewise.
(Output_data_reloc::add_local): Likewise.
(Output_data_reloc::add_local_relative): Likewise.
(Output_data_reloc::add_symbolless_local_addend): Likewise.
(Output_data_reloc::add_local_section): Likewise.
(Output_data_reloc::add_output_section): Likewise.
(Output_data_reloc::add_absolute): Likewise.
(Output_data_reloc::add_target_specific): Likewise.
(Output_data_got::reserve_slot): Move definition here.
(Output_data_got::reserve_local): New function.
(Output_data_got::reserve_global): New function.
* reloc.cc (Sized_relobj_file::do_read_relocs): Replace refs to
section_offsets_ with accessor function.
(Sized_relobj_file::write_sections): Likewise.
(Sized_relobj_file::do_relocate_sections): Likewise.
* target.h (Sized_target::reserve_local_got_entry): New function.
(Sized_target::reserve_global_got_entry): New function.
* x86_64.cc (Target_x86_64::reserve_local_got_entry): New function.
(Target_x86_64::reserve_global_got_entry): New function.
(Target_x86_64::init_got_plt_for_update): Create rela_dyn section.
* symtab.h (Symbol::NON_PIC_REF): Remove.
(Symbol::RELATIVE_REF, Symbol::TLS_REF): New Reference_flags.
(Symbol::FUNCTION_CALL): Renumber. Reword comment.
(Symbol::needs_dynamic_reloc): Don't check NON_PIC_REF.
(Symbol::use_plt_offset): Take a flags argument and pass it
directly to needs_dynamic_reloc. Restrict check for undefined
weak symbols to function calls.
* arm.cc (Target_arm::Scan::get_reference_flags): New function.
(Target_arm::Scan::global): Use it.
(Target_arm::Scan::scan_reloc_for_stub): Likewise.
(Target_arm::Relocate::relocate): Likewise.
(Target_arm::Relocate::should_apply_static_reloc): Replace flags
parameter with an r_type parameter. Use get_reference_flags
to get the flags.
(Target_arm::Relocate::relocate): Update accordingly.
* i386.cc (Target_i386::Scan::get_reference_flags): New function.
(Target_i386::Scan::reloc_needs_plt_for_ifunc): Use it.
(Target_i386::Scan::global): Likewise.
(Target_i386::Relocate::relocate): Likewise.
(Target_i386::Relocate::should_apply_static_reloc): Replace flags
parameter with an r_type parameter. Use get_reference_flags
to get the flags.
(Target_i386::Relocate::relocate): Update accordingly.
* powerpc.cc (Target_powerpc::Scan::get_reference_flags): New function.
(Target_powerpc::Scan::global): Use it.
(Target_powerpc::Scan::scan_reloc_for_stub): Likewise.
(Target_powerpc::Relocate::relocate): Likewise.
* sparc.cc (Target_sparc::Scan::get_reference_flags): New function.
(Target_sparc::Scan::global): Use it.
(Target_sparc::Scan::scan_reloc_for_stub): Likewise.
(Target_sparc::Relocate::relocate): Likewise.
* x86_64.cc (Target_x86_64::Scan::get_reference_flags): New function.
(Target_x86_64::Scan::reloc_needs_plt_for_ifunc): Use it.
(Target_x86_64::Scan::global): Likewise.
(Target_x86_64::Relocate::relocate): Likewise.
* target.h (Target::can_icf_inline_merge_sections): New virtual
function.
* x86_64.cc (Target__x86_64::can_icf_inline_merge_sections): New
virtual function.
* i386.cc (Target_i386::can_icf_inline_merge_sections): New
virtual function.
* icf.cc (get_section_contents): Inline merge sections only when
target allows it.
* i386.cc (class Output_data_plt_i386): Update declarations.
Define Global_ifunc and Local_ifunc types. Add global_ifuncs_ and
local_ifuncs_ fields.
(Target_i386::do_plt_section_for_global): New function.
(Target_i386::do_plt_section_for_local): New function.
(Output_data_plt_i386::Output_data_plt_i386): Add symtab
parameter; change all callers. Initialize global_ifuncs_ and
local_ifuncs_. If doing a static link define __rel_iplt_start and
__rel_iplt_end.
(Output_data_plt_i386::add_entry): Handle IFUNC symbols.
(Output_data_plt_i386::add_local_ifunc_entry): New function.
(Output_data_plt_i386::do_write): Fix GOT entries for IFUNC
symbols.
(Target_i386::make_plt_section): New function, broken out of
make_plt_entry. Set sh_info field of .rel.plt to point to .plt.
(Target_i386::make_plt_entry): Call make_plt_section.
(Target_i386::make_local_ifunc_plt_entry): New function.
(Target_i386::Scan::reloc_needs_iplt_for_ifunc): New function.
(Target_i386::Scan::local): Handle IFUNC symbols. Add
R_386_IRELATIVE to switch.
(Target_i386::Scan::global): Likewise.
(Target_i386::Relocate::relocate): Likewise.
(Target_i386::Relocatable_size_for_reloc): Add R_386_IRELATIVE to
switch.
* x86_64.cc (class Output_data_plt_x86_64): Update declarations.
(Target_x86_64::do_plt_section_for_global): New function.
(Target_x86_64::do_plt_section_for_local): New function.
(Output_data_plt_x86_64::Output_data_plt_x86_64): Add symtab
parameter; change all callers. If doing a static link define
__rela_iplt_start and __rela_iplt_end.
(Output_data_plt_x86_64::add_entry): Handle IFUNC symbols.
(Output_data_plt_x86_64::add_local_ifunc_entry): New function.
(Target_x86_64::make_plt_section): Set sh_info field of .rel.plt
to point to .plt.
(Target_x86_64::make_local_ifunc_plt_entry): New function.
(Target_x86_64::Scan::check_non_pic): Add R_X86_64_IRELATIVE to
switch.
(Target_x86_64::Scan::reloc_needs_iplt_for_ifunc): New function.
(Target_x86_64::Scan::local): Handle IFUNC symbols. Add
R_X86_64_IRELATIVE to switch.
(Target_x86_64::Scan::global): Likewise.
(Target_x86_64::Relocate::relocate): Likewise.
(Target_x86_64::Relocatable_size_for_reloc): Add R_X86_64_IRELATIVE to
switch.
* target.h (class Target): Add plt_section_for_global and
plt_section_for_local functions. Add do_plt_section_for_global
and do_plt_section_for_local virtual functions.
* symtab.h (Symbol::needs_plt_entry): Handle IFUNC symbol. Add
clarifying comments.
(Symbol::use_plt_offset): Handle IFUNC symbol.
* object.cc (Sized_relobj::Sized_relobj): Initialize
local_plt_offsets_.
(Sized_relobj::local_has_plt_offset): New function.
(Sized_relobj::local_plt_offset): New function.
(Sized_relobj::set_local_plt_offset): New function.
(Sized_relobj::do_count): Handle IFUNC symbol.
* object.h (class Symbol_value): Add is_ifunc_symbol_ field. Take
a bit away from input_shndx_ field. Add set_is_func_symbol and
is_ifunc_symbol functions.
(class Sized_relobj): Update declarations. Remove Tls_got_entry
and Local_tls_got_offsets. Define Local_plt_offsets. Add
local_plt_offsets_ field.
(Sized_relobj::clear_local_symbols): Clear local_plt_offsets_.
* output.h (class Output_section_data): Add non-const
output_section function.
(class Output_data_got): Update declarations.
(class Output_data_got::Got_entry): Add use_plt_offset_ field.
Add use_plt_offset parameter to global and local constructors.
Change all callers. Change local_sym_index_ field to 31 bits.
Change GSYM_CODE and CONSTANT_CODE accordingly.
* output.cc (Output_data_reloc_base::do_adjust_output_section): If
doing a static link don't set sh_link field.
(Output_data_got::Got_entry::write): Use PLT offset if
appropriate.
(Output_data_got::add_global_plt): New function.
(Output_data_got::add_local_plt): New function.
* target-reloc.h (relocate_section): Handle IFUNC symbol.
* defstd.cc (in_section): Remove entries for __rel_iplt_start,
__rel_iplt_end, __rela_iplt_start, and __rela_iplt_end.
* configure.ac: Set IFUNC automake conditional for glibc >= 2.11.
* testsuite/Makefile.am: Add a bunch of IFUNC tests, all within
IFUNC conditional.
* testsuite/ifunc-sel.h: New file.
* testsuite/ifuncmain1.c: New file.
* testsuite/ifuncmain1vis.c: New file.
* testsuite/ifuncmod1.c: New file.
* testsuite/ifuncdep2.c: New file.
* testsuite/ifuncmain2.c: New file.
* testsuite/ifuncmain3.c: New file.
* testsuite/ifuncmod3.c: New file.
* testsuite/ifuncmain4.c: New file.
* testsuite/ifuncmain5.c: New file.
* testsuite/ifuncmod5.c: New file.
* testsuite/ifuncmain6pie.c: New file.
* testsuite/ifuncmod6.c: New file.
* testsuite/ifuncmain7.c: New file.
* configure, testsuite/Makefile.in: Rebuild.
* elfcpp.h (enum SHT): Add SHT_GNU_INCREMENTAL_GOT_PLT.
gold/ChangeLog:
* arm.cc (Target_arm::got_size): Add const.
(Target_arm::got_entry_count): New function.
(Target_arm::plt_entry_count): New function.
(Target_arm::first_plt_entry_offset): New function.
(Target_arm::plt_entry_size): New function.
(Output_data_plt_arm::entry_count): New function.
(Output_data_plt_arm::first_plt_entry_offset): New function.
(Output_data_plt_arm::get_plt_entry_size): New function.
* i386.cc (Target_i386::got_size): Add const.
(Target_i386::got_entry_count): New function.
(Target_i386::plt_entry_count): New function.
(Target_i386::first_plt_entry_offset): New function.
(Target_i386::plt_entry_size): New function.
(Output_data_plt_i386::entry_count): New function.
(Output_data_plt_i386::first_plt_entry_offset): New function.
(Output_data_plt_i386::get_plt_entry_size): New function.
* incremental-dump.cc (dump_incremental_inputs): Adjust call to
find_incremental_inputs_sections. Dump incremental_got_plt section.
* incremental.cc: Include target.h.
(Sized_incremental_binary::do_find_incremental_inputs_sections): Add
parameter. Adjust all callers. Find incremental_got_plt section.
(Incremental_inputs::create_data_sections): Create incremental_got_plt
section.
(Output_section_incremental_inputs::set_final_data_size): Calculate
size of incremental_got_plt section.
(Output_section_incremental_inputs::do_write): Write the
incremental_got_plt section.
(Got_plt_view_info): New struct.
(Local_got_offset_visitor): New class.
(Global_got_offset_visitor): New class.
(Global_symbol_visitor_got_plt): New class.
(Output_section_incremental_inputs::write_got_plt): New function.
* incremental.h (Incremental_binary::find_incremental_inputs_sections):
Add parameter. Adjust all callers.
(Incremental_binary::do_find_incremental_inputs_sections): Likewise.
(Incremental_inputs::got_plt_section): New function.
(Incremental_inputs::got_plt_section_): New data member.
(Incremental_got_plt_reader): New class.
* layout.cc (Layout::create_incremental_info_sections): Add the
incremental_got_plt section.
* object.h (Got_offset_list::get_list): New function.
(Got offset_list::for_all_got_offsets): New function.
(Sized_relobj::local_got_offset_list): New function.
* powerpc.cc (Target_powerpc::got_size): Add const.
(Target_powerpc::got_entry_count): New function.
(Target_powerpc::plt_entry_count): New function.
(Target_powerpc::first_plt_entry_offset): New function.
(Target_powerpc::plt_entry_size): New function.
(Output_data_plt_powerpc::entry_count): New function.
(Output_data_plt_powerpc::first_plt_entry_offset): New function.
(Output_data_plt_powerpc::get_plt_entry_size): New function.
* sparc.cc (Target_sparc::got_size): Add const.
(Target_sparc::got_entry_count): New function.
(Target_sparc::plt_entry_count): New function.
(Target_sparc::first_plt_entry_offset): New function.
(Target_sparc::plt_entry_size): New function.
(Output_data_plt_sparc::entry_count): New function.
(Output_data_plt_sparc::first_plt_entry_offset): New function.
(Output_data_plt_sparc::get_plt_entry_size): New function.
* symtab.h (Symbol::got_offset_list): New function.
(Symbol_table::for_all_symbols): New function.
* target.h (Sized_target::got_entry_count): New function.
(Sized_target::plt_entry_count): New function.
(Sized_target::plt_entry_size): New function.
* x86_64.cc (Target_x86_64::got_size): Add const.
(Target_x86_64::got_entry_count): New function.
(Target_x86_64::plt_entry_count): New function.
(Target_x86_64::first_plt_entry_offset): New function.
(Target_x86_64::plt_entry_size): New function.
(Output_data_plt_x86_64::entry_count): New function.
(Output_data_plt_x86_64::first_plt_entry_offset): New function.
(Output_data_plt_x86_64::get_plt_entry_size): New function.
(Target_i386::Target_i386):: Initialize got_tlsdesc_.
(Target_i386::got_tlsdesc_section): New function.
(Target_i386::got_section): Create space for GOT entries for
TLSDESC relocations.
(Target_i386::Scan::local): Use TLSDESC GOT for unoptimized
R_386_TLS_GOTDESC.
(Target_i386::Scan::global): Likewise.
(Target_i386::Relocate::relocate_tls): Adjust GOT offset when
using TLSDESC GOT.
* x86_64.cc (class Target_x86_64): Add got_tlsdesc_ field.
(Target_x86_64::Target_x86_64):: Initialize got_tlsdesc_.
(Target_x86_64::got_tlsdesc_section): New function.
(Target_x86_64::got_section): Create space for GOT entries for
TLSDESC relocations.
(Target_x86_64::Scan::local): Use TLSDESC GOT for unoptimized
R_386_TLS_GOTDESC.
(Target_x86_64::Scan::global): Likewise.
(Target_x86_64::Relocate::relocate_tls): Adjust GOT offset when
using TLSDESC GOT.
paramter to the call to gold::gc_process_relocs.
* i386.cc (Target_i386<big_endian>::gc_process_relocs): Add template
paramter to the call to gold::gc_process_relocs.
* x86_64.cc (Target_x86_64<big_endian>::gc_process_relocs): Add template
parameter to the call to gold::gc_process_relocs.
* powerpc.cc (Target_powerpc<big_endian>::gc_process_relocs): Add
template parameter to the call to gold::gc_process_relocs.
* sparc.cc (Target_sparc<big_endian>::gc_process_relocs): Add template
paramter to the call to gold::gc_process_relocs.
* gc.h (get_embedded_addend_size): New function.
(gc_process_relocs): Save the size of the reloc for use by ICF.
* icf.cc (get_section_contents): Get the addend from the text section
for SHT_REL relocation sections.
* icf.h (Icf::Reloc_addend_size_info): New typedef.
(Icf::Reloc_info): Add new member reloc_addend_size_info.
* int_encoding.h (read_from_pointer): New overloaded function.
* testsuite/Makefile.am (icf_sht_rel_addend_test): New test.
* testsuite/icf_sht_rel_addend_test.sh: New file.
* testsuite/icf_sht_rel_addend_test_1.cc: New file.
* testsuite/icf_sht_rel_addend_test_2.cc: New file.
target to ask whether a reference to a symbol requires a stack
split.
* target.h (Target::is_call_to_non_split): New function.
(Target::do_is_call_to_non_split): Declare virtual function.
* target.cc: Include "symtab.h".
(Target::do_is_call_to_non_split): New function.
* i386.cc (Target_i386::do_is_call_to_non_split): New function.