binutils-gdb/gold/powerpc.cc

6892 lines
203 KiB
C++
Raw Normal View History

// powerpc.cc -- powerpc target support for gold.
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
// Copyright 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
// Written by David S. Miller <davem@davemloft.net>
// and David Edelsohn <edelsohn@gnu.org>
// This file is part of gold.
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.
#include "gold.h"
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
#include <algorithm>
#include "elfcpp.h"
#include "parameters.h"
#include "reloc.h"
#include "powerpc.h"
#include "object.h"
#include "symtab.h"
#include "layout.h"
#include "output.h"
#include "copy-relocs.h"
#include "target.h"
#include "target-reloc.h"
#include "target-select.h"
#include "tls.h"
#include "errors.h"
#include "gc.h"
namespace
{
using namespace gold;
template<int size, bool big_endian>
class Output_data_plt_powerpc;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
template<int size, bool big_endian>
class Output_data_brlt_powerpc;
template<int size, bool big_endian>
class Output_data_got_powerpc;
template<int size, bool big_endian>
class Output_data_glink;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
template<int size, bool big_endian>
class Stub_table;
template<int size, bool big_endian>
class Powerpc_relobj : public Sized_relobj_file<size, big_endian>
{
public:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
typedef Unordered_set<Section_id, Section_id_hash> Section_refs;
typedef Unordered_map<Address, Section_refs> Access_from;
Powerpc_relobj(const std::string& name, Input_file* input_file, off_t offset,
const typename elfcpp::Ehdr<size, big_endian>& ehdr)
: Sized_relobj_file<size, big_endian>(name, input_file, offset, ehdr),
special_(0), opd_valid_(false), opd_ent_(), access_from_map_()
{ }
~Powerpc_relobj()
{ }
// The .got2 section shndx.
unsigned int
got2_shndx() const
{
if (size == 32)
return this->special_;
else
return 0;
}
// The .opd section shndx.
unsigned int
opd_shndx() const
{
if (size == 32)
return 0;
else
return this->special_;
}
// Init OPD entry arrays.
void
init_opd(size_t opd_size)
{
size_t count = this->opd_ent_ndx(opd_size);
this->opd_ent_.resize(count);
}
// Return section and offset of function entry for .opd + R_OFF.
unsigned int
get_opd_ent(Address r_off, Address* value = NULL) const
{
size_t ndx = this->opd_ent_ndx(r_off);
gold_assert(ndx < this->opd_ent_.size());
gold_assert(this->opd_ent_[ndx].shndx != 0);
if (value != NULL)
*value = this->opd_ent_[ndx].off;
return this->opd_ent_[ndx].shndx;
}
// Set section and offset of function entry for .opd + R_OFF.
void
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
set_opd_ent(Address r_off, unsigned int shndx, Address value)
{
size_t ndx = this->opd_ent_ndx(r_off);
gold_assert(ndx < this->opd_ent_.size());
this->opd_ent_[ndx].shndx = shndx;
this->opd_ent_[ndx].off = value;
}
// Return discard flag for .opd + R_OFF.
bool
get_opd_discard(Address r_off) const
{
size_t ndx = this->opd_ent_ndx(r_off);
gold_assert(ndx < this->opd_ent_.size());
return this->opd_ent_[ndx].discard;
}
// Set discard flag for .opd + R_OFF.
void
set_opd_discard(Address r_off)
{
size_t ndx = this->opd_ent_ndx(r_off);
gold_assert(ndx < this->opd_ent_.size());
this->opd_ent_[ndx].discard = true;
}
Access_from*
access_from_map()
{ return &this->access_from_map_; }
// Add a reference from SRC_OBJ, SRC_INDX to this object's .opd
// section at DST_OFF.
void
add_reference(Object* src_obj,
unsigned int src_indx,
typename elfcpp::Elf_types<size>::Elf_Addr dst_off)
{
Section_id src_id(src_obj, src_indx);
this->access_from_map_[dst_off].insert(src_id);
}
// Add a reference to the code section specified by the .opd entry
// at DST_OFF
void
add_gc_mark(typename elfcpp::Elf_types<size>::Elf_Addr dst_off)
{
size_t ndx = this->opd_ent_ndx(dst_off);
if (ndx >= this->opd_ent_.size())
this->opd_ent_.resize(ndx + 1);
this->opd_ent_[ndx].gc_mark = true;
}
void
process_gc_mark(Symbol_table* symtab)
{
for (size_t i = 0; i < this->opd_ent_.size(); i++)
if (this->opd_ent_[i].gc_mark)
{
unsigned int shndx = this->opd_ent_[i].shndx;
symtab->gc()->worklist().push(Section_id(this, shndx));
}
}
bool
opd_valid() const
{ return this->opd_valid_; }
void
set_opd_valid()
{ this->opd_valid_ = true; }
// Examine .rela.opd to build info about function entry points.
void
scan_opd_relocs(size_t reloc_count,
const unsigned char* prelocs,
const unsigned char* plocal_syms);
// Perform the Sized_relobj_file method, then set up opd info from
// .opd relocs.
void
do_read_relocs(Read_relocs_data*);
bool
do_find_special_sections(Read_symbols_data* sd);
// Adjust this local symbol value. Return false if the symbol
// should be discarded from the output file.
bool
do_adjust_local_symbol(Symbol_value<size>* lv) const
{
if (size == 64 && this->opd_shndx() != 0)
{
bool is_ordinary;
if (lv->input_shndx(&is_ordinary) != this->opd_shndx())
return true;
if (this->get_opd_discard(lv->input_value()))
return false;
}
return true;
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// Return offset in output GOT section that this object will use
// as a TOC pointer. Won't be just a constant with multi-toc support.
Address
toc_base_offset() const
{ return 0x8000; }
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
void
set_has_14bit_branch(unsigned int shndx)
{
if (shndx >= this->has14_.size())
this->has14_.resize(shndx + 1);
this->has14_[shndx] = true;
}
bool
has_14bit_branch(unsigned int shndx) const
{ return shndx < this->has14_.size() && this->has14_[shndx]; }
void
set_stub_table(unsigned int shndx, Stub_table<size, big_endian>* stub_table)
{
if (shndx >= this->stub_table_.size())
this->stub_table_.resize(shndx + 1);
this->stub_table_[shndx] = stub_table;
}
Stub_table<size, big_endian>*
stub_table(unsigned int shndx)
{
if (shndx < this->stub_table_.size())
return this->stub_table_[shndx];
return NULL;
}
private:
struct Opd_ent
{
unsigned int shndx;
bool discard : 1;
bool gc_mark : 1;
Address off;
};
// Return index into opd_ent_ array for .opd entry at OFF.
// .opd entries are 24 bytes long, but they can be spaced 16 bytes
// apart when the language doesn't use the last 8-byte word, the
// environment pointer. Thus dividing the entry section offset by
// 16 will give an index into opd_ent_ that works for either layout
// of .opd. (It leaves some elements of the vector unused when .opd
// entries are spaced 24 bytes apart, but we don't know the spacing
// until relocations are processed, and in any case it is possible
// for an object to have some entries spaced 16 bytes apart and
// others 24 bytes apart.)
size_t
opd_ent_ndx(size_t off) const
{ return off >> 4;}
// For 32-bit the .got2 section shdnx, for 64-bit the .opd section shndx.
unsigned int special_;
// Set at the start of gc_process_relocs, when we know opd_ent_
// vector is valid. The flag could be made atomic and set in
// do_read_relocs with memory_order_release and then tested with
// memory_order_acquire, potentially resulting in fewer entries in
// access_from_map_.
bool opd_valid_;
// The first 8-byte word of an OPD entry gives the address of the
// entry point of the function. Relocatable object files have a
// relocation on this word. The following vector records the
// section and offset specified by these relocations.
std::vector<Opd_ent> opd_ent_;
// References made to this object's .opd section when running
// gc_process_relocs for another object, before the opd_ent_ vector
// is valid for this object.
Access_from access_from_map_;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// Whether input section has a 14-bit branch reloc.
std::vector<bool> has14_;
// The stub table to use for a given input section.
std::vector<Stub_table<size, big_endian>*> stub_table_;
};
template<int size, bool big_endian>
class Target_powerpc : public Sized_target<size, big_endian>
{
public:
typedef
Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian> Reloc_section;
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
typedef typename elfcpp::Elf_types<size>::Elf_Swxword Signed_address;
static const Address invalid_address = static_cast<Address>(0) - 1;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// Offset of tp and dtp pointers from start of TLS block.
static const Address tp_offset = 0x7000;
static const Address dtp_offset = 0x8000;
Target_powerpc()
: Sized_target<size, big_endian>(&powerpc_info),
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
got_(NULL), plt_(NULL), iplt_(NULL), brlt_section_(NULL),
glink_(NULL), rela_dyn_(NULL), copy_relocs_(elfcpp::R_POWERPC_COPY),
dynbss_(NULL), tlsld_got_offset_(-1U),
stub_tables_(), branch_lookup_table_(), branch_info_(),
plt_thread_safe_(false)
{
}
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
// Process the relocations to determine unreferenced sections for
2009-01-20 Sriraman Tallam <tmsriram@google.com> * Makefile.am (CCFILES): Add gc.cc. (HFILES): Add gc.h. * Makefile.in: Regenerate. * gold.cc (Gc_runner): New class. (queue_initial_tasks): Call garbage collection related tasks when corresponding options are invoked. (queue_middle_gc_tasks): New function. (queue_middle_tasks): Reorder tasks to allow relocs to be read and processed early before laying out sections during garbage collection. * gold.h (queue_middle_gc_tasks): New function. (is_prefix_of): Move from "layout.cc". * i386.cc (Target_i386::gc_process_relocs): New function. * layout.cc (is_prefix_of): Remove. Move to "gold.h" * main.cc (main): Create object of class "Garbage_collection". * object.cc (Relobj::copy_symbols_data): New function. (Relobj::is_section_name_included): New function. (Sized_relobj::do_layout): Allow this function to be called twice during garbage collection and defer layout of section during the first call. * object.h (Relobj::get_symbols_data): New function. (Relobj::is_section_name_included): New function. (Relobj::copy_symbols_data): New function. (Relobj::set_symbols_data): New function. (Relobj::get_relocs_data): New function. (Relobj::set_relocs_data): New function. (Relobj::is_output_section_offset_invalid): New pure virtual function. (Relobj::gc_process_relocs): New function. (Relobj::do_gc_process_relocs): New pure virtual function. (Relobj::sd_): New data member. (Sized_relobj::is_output_section_offset_invalid): New function. (Sized_relobj::do_gc_process_relocs): New function. * options.h (General_options::gc_sections): Modify to not be a no-op. (General_options::print_gc_sections): New option. * plugin.cc (Plugin_finish::run): Remove function call to Plugin_manager::layout_deferred_objects. Move it to "gold.cc". * powerpc.cc (Target_powerpc::gc_process_relocs): New function. * reloc.cc (Read_relocs::run): Add task to process relocs and determine unreferenced sections when doing garbage collection. (Gc_process_relocs): New class. (Sized_relobj::do_gc_process_relocs): New function. (Sized_relobj::do_scan_relocs): Don't try to scan the relocs for sections that are garbage collected. * reloc.h (Gc_process_relocs): New class. * sparc.cc (Target_sparc::gc_process_relocs): New function. * symtab.cc (Symbol::should_add_dynsym_entry): Do not add entries for symbols whose corresponding sections are garbage collected. (Symbol_table::Symbol_table): Add new parameter for the garbage collection object. (Symbol_table::gc_mark_undef_symbols): New function. (Symbol_table::gc_mark_symbol_for_shlib): New function. (Symbol_table::gc_mark_dyn_syms): New function. (Symbol_table::resolve): Do not treat symbols seen in dynamic objects as garbage. (Symbol_table::add_from_object): Likewise. (Symbol_table::add_from_relobj): When building shared objects, do not treat externally visible symbols as garbage. (Symbol_table::sized_finalize_symbol): Do not check dynamic symbol table information for static and relocatable links. * symtab.h (Symbol_table::set_gc): New function. (Symbol_table::gc): New function. (Symbol_table::gc_mark_undef_symbols): New function. (Symbol_table::gc_mark_symbol_for_shlib): New function. (Symbol_table::gc_mark_dyn_syms): New function. (Symbol_table::gc_): New data member. * target.h (Sized_target::gc_process_relocs): New pure virtual function. * x86_64.cc (Target_x86_64::gc_process_relocs): New function. * testsuite/testfile.cc (Target_test::gc_process_relocs): New function.
2009-01-28 03:25:33 +01:00
// garbage collection.
void
gc_process_relocs(Symbol_table* symtab,
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
Layout* layout,
Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
bool needs_special_offset_handling,
size_t local_symbol_count,
const unsigned char* plocal_symbols);
2009-01-20 Sriraman Tallam <tmsriram@google.com> * Makefile.am (CCFILES): Add gc.cc. (HFILES): Add gc.h. * Makefile.in: Regenerate. * gold.cc (Gc_runner): New class. (queue_initial_tasks): Call garbage collection related tasks when corresponding options are invoked. (queue_middle_gc_tasks): New function. (queue_middle_tasks): Reorder tasks to allow relocs to be read and processed early before laying out sections during garbage collection. * gold.h (queue_middle_gc_tasks): New function. (is_prefix_of): Move from "layout.cc". * i386.cc (Target_i386::gc_process_relocs): New function. * layout.cc (is_prefix_of): Remove. Move to "gold.h" * main.cc (main): Create object of class "Garbage_collection". * object.cc (Relobj::copy_symbols_data): New function. (Relobj::is_section_name_included): New function. (Sized_relobj::do_layout): Allow this function to be called twice during garbage collection and defer layout of section during the first call. * object.h (Relobj::get_symbols_data): New function. (Relobj::is_section_name_included): New function. (Relobj::copy_symbols_data): New function. (Relobj::set_symbols_data): New function. (Relobj::get_relocs_data): New function. (Relobj::set_relocs_data): New function. (Relobj::is_output_section_offset_invalid): New pure virtual function. (Relobj::gc_process_relocs): New function. (Relobj::do_gc_process_relocs): New pure virtual function. (Relobj::sd_): New data member. (Sized_relobj::is_output_section_offset_invalid): New function. (Sized_relobj::do_gc_process_relocs): New function. * options.h (General_options::gc_sections): Modify to not be a no-op. (General_options::print_gc_sections): New option. * plugin.cc (Plugin_finish::run): Remove function call to Plugin_manager::layout_deferred_objects. Move it to "gold.cc". * powerpc.cc (Target_powerpc::gc_process_relocs): New function. * reloc.cc (Read_relocs::run): Add task to process relocs and determine unreferenced sections when doing garbage collection. (Gc_process_relocs): New class. (Sized_relobj::do_gc_process_relocs): New function. (Sized_relobj::do_scan_relocs): Don't try to scan the relocs for sections that are garbage collected. * reloc.h (Gc_process_relocs): New class. * sparc.cc (Target_sparc::gc_process_relocs): New function. * symtab.cc (Symbol::should_add_dynsym_entry): Do not add entries for symbols whose corresponding sections are garbage collected. (Symbol_table::Symbol_table): Add new parameter for the garbage collection object. (Symbol_table::gc_mark_undef_symbols): New function. (Symbol_table::gc_mark_symbol_for_shlib): New function. (Symbol_table::gc_mark_dyn_syms): New function. (Symbol_table::resolve): Do not treat symbols seen in dynamic objects as garbage. (Symbol_table::add_from_object): Likewise. (Symbol_table::add_from_relobj): When building shared objects, do not treat externally visible symbols as garbage. (Symbol_table::sized_finalize_symbol): Do not check dynamic symbol table information for static and relocatable links. * symtab.h (Symbol_table::set_gc): New function. (Symbol_table::gc): New function. (Symbol_table::gc_mark_undef_symbols): New function. (Symbol_table::gc_mark_symbol_for_shlib): New function. (Symbol_table::gc_mark_dyn_syms): New function. (Symbol_table::gc_): New data member. * target.h (Sized_target::gc_process_relocs): New pure virtual function. * x86_64.cc (Target_x86_64::gc_process_relocs): New function. * testsuite/testfile.cc (Target_test::gc_process_relocs): New function.
2009-01-28 03:25:33 +01:00
// Scan the relocations to look for symbol adjustments.
void
scan_relocs(Symbol_table* symtab,
Layout* layout,
* incremental-dump.cc (dump_incremental_inputs): Print dynamic reloc 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.
2011-05-24 23:41:10 +02:00
Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
bool needs_special_offset_handling,
size_t local_symbol_count,
const unsigned char* plocal_symbols);
// Map input .toc section to output .got section.
const char*
do_output_section_name(const Relobj*, const char* name, size_t* plen) const
{
if (size == 64 && strcmp(name, ".toc") == 0)
{
*plen = 4;
return ".got";
}
return NULL;
}
// Provide linker defined save/restore functions.
void
define_save_restore_funcs(Layout*, Symbol_table*);
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// No stubs unless a final link.
bool
do_may_relax() const
{ return !parameters->options().relocatable(); }
bool
do_relax(int, const Input_objects*, Symbol_table*, Layout*, const Task*);
// Stash info about branches, for stub generation.
void
push_branch(Powerpc_relobj<size, big_endian>* ppc_object,
unsigned int data_shndx, Address r_offset,
unsigned int r_type, unsigned int r_sym, Address addend)
{
Branch_info info(ppc_object, data_shndx, r_offset, r_type, r_sym, addend);
this->branch_info_.push_back(info);
if (r_type == elfcpp::R_POWERPC_REL14
|| r_type == elfcpp::R_POWERPC_REL14_BRTAKEN
|| r_type == elfcpp::R_POWERPC_REL14_BRNTAKEN)
ppc_object->set_has_14bit_branch(data_shndx);
}
Stub_table<size, big_endian>*
new_stub_table();
void
do_define_standard_symbols(Symbol_table*, Layout*);
// Finalize the sections.
void
do_finalize_sections(Layout*, const Input_objects*, Symbol_table*);
// Return the value to use for a dynamic which requires special
// treatment.
uint64_t
do_dynsym_value(const Symbol*) const;
// Return the PLT address to use for a local symbol.
uint64_t
do_plt_address_for_local(const Relobj*, unsigned int) const;
// Return the PLT address to use for a global symbol.
uint64_t
do_plt_address_for_global(const Symbol*) const;
// Return the offset to use for the GOT_INDX'th got entry which is
// for a local tls symbol specified by OBJECT, SYMNDX.
int64_t
do_tls_offset_for_local(const Relobj* object,
unsigned int symndx,
unsigned int got_indx) const;
// Return the offset to use for the GOT_INDX'th got entry which is
// for global tls symbol GSYM.
int64_t
do_tls_offset_for_global(Symbol* gsym, unsigned int got_indx) const;
// Relocate a section.
void
relocate_section(const Relocate_info<size, big_endian>*,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
bool needs_special_offset_handling,
unsigned char* view,
Address view_address,
* options.h (class General_options): Define split_stack_adjust_size parameter. * object.h (class Object): Add uses_split_stack_ and has_no_split_stack_ fields. Add uses_split_stack and has_no_split_stack accessor functions. Declare handle_split_stack_section. (class Reloc_symbol_changes): Define. (class Sized_relobj): Define Function_offsets. Declare split_stack_adjust, split_stack_adjust_reltype, and find_functions. * object.cc (Object::handle_split_stack_section): New function. (Sized_relobj::do_layout): Call handle_split_stack_section. * dynobj.cc (Sized_dynobj::do_layout): Call handle_split_stack_section. * reloc.cc (Sized_relobj::relocate_sections): Call split_stack_adjust for executable sections in split_stack objects. Pass reloc_map to relocate_section. (Sized_relobj::split_stack_adjust): New function. (Sized_relobj::split_stack_adjust_reltype): New function. (Sized_relobj::find_functions): New function. * target-reloc.h: Include "object.h". (relocate_section): Add reloc_symbol_changes parameter. Change all callers. * target.h (class Target): Add calls_non_split method. Declare do_calls_non_split virtual method. Declare match_view and set_view_to_nop. * target.cc: Include "elfcpp.h". (Target::do_calls_non_split): New function. (Target::match_view): New function. (Target::set_view_to_nop): New function. * gold.cc (queue_middle_tasks): Give an error if mixing split-stack and non-split-stack objects with -r. * i386.cc (Target_i386::relocate_section): Add reloc_symbol_changes parameter. (Target_i386::do_calls_non_split): New function. * x86_64.cc (Target_x86_64::relocate_section): Add reloc_symbol_changes parameter. (Target_x86_64::do_calls_non_split): New function. * arm.cc (Target_arm::relocate_section): Add reloc_symbol_changes parameter. * powerpc.cc (Target_powerpc::relocate_section): Add reloc_symbol_changes parameter. * sparc.cc (Target_sparc::relocate_section): Add reloc_symbol_changes parameter. * configure.ac: Call AM_CONDITIONAL for the default target. * configure: Rebuild. * testsuite/Makefile.am (TEST_AS): New variable. (check_SCRIPTS): Add split_i386.sh and split_x86_64.sh. (check_DATA): Add split_i386 and split_x86_64 files. (SPLIT_DEFSYMS): Define. (split_i386_[1234n].o): New targets. (split_i386_[124]): New targets. (split_i386_[1234r].stdout): New targets. (split_x86_64_[1234n].o): New targets. (split_x86_64_[124]): New targets. (split_x86_64_[1234r].stdout): New targets. (MOSTLYCLEANFILES): Add new executables. * testsuite/split_i386.sh: New file. * testsuite/split_x86_64.sh: New file. * testsuite/split_i386_1.s: New file. * testsuite/split_i386_2.s: New file. * testsuite/split_i386_3.s: New file. * testsuite/split_i386_4.s: New file. * testsuite/split_i386_n.s: New file. * testsuite/split_x86_64_1.s: New file. * testsuite/split_x86_64_2.s: New file. * testsuite/split_x86_64_3.s: New file. * testsuite/split_x86_64_4.s: New file. * testsuite/split_x86_64_n.s: New file. * testsuite/testfile.cc (Target_test): Update relocation_section function. * testsuite/Makefile.in: Rebuild.
2009-10-07 00:58:27 +02:00
section_size_type view_size,
const Reloc_symbol_changes*);
// Scan the relocs during a relocatable link.
void
scan_relocatable_relocs(Symbol_table* symtab,
Layout* layout,
* incremental-dump.cc (dump_incremental_inputs): Print dynamic reloc 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.
2011-05-24 23:41:10 +02:00
Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
bool needs_special_offset_handling,
size_t local_symbol_count,
const unsigned char* plocal_symbols,
Relocatable_relocs*);
// Emit relocations for a section.
void
relocate_relocs(const Relocate_info<size, big_endian>*,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
typename elfcpp::Elf_types<size>::Elf_Off
offset_in_output_section,
const Relocatable_relocs*,
unsigned char*,
Address view_address,
section_size_type,
unsigned char* reloc_view,
section_size_type reloc_view_size);
// Return whether SYM is defined by the ABI.
bool
do_is_defined_by_abi(const Symbol* sym) const
{
return strcmp(sym->name(), "__tls_get_addr") == 0;
}
// Return the size of the GOT section.
section_size_type
elfcpp/ChangeLog: * 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.
2010-08-13 00:15:00 +02:00
got_size() const
{
gold_assert(this->got_ != NULL);
return this->got_->data_size();
}
// Get the PLT section.
const Output_data_plt_powerpc<size, big_endian>*
plt_section() const
{
gold_assert(this->plt_ != NULL);
return this->plt_;
}
// Get the IPLT section.
const Output_data_plt_powerpc<size, big_endian>*
iplt_section() const
{
gold_assert(this->iplt_ != NULL);
return this->iplt_;
}
// Get the .glink section.
const Output_data_glink<size, big_endian>*
glink_section() const
{
gold_assert(this->glink_ != NULL);
return this->glink_;
}
// Get the GOT section.
const Output_data_got_powerpc<size, big_endian>*
got_section() const
{
gold_assert(this->got_ != NULL);
return this->got_;
}
// Get the GOT section, creating it if necessary.
Output_data_got_powerpc<size, big_endian>*
got_section(Symbol_table*, Layout*);
Object*
do_make_elf_object(const std::string&, Input_file*, off_t,
const elfcpp::Ehdr<size, big_endian>&);
elfcpp/ChangeLog: * 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.
2010-08-13 00:15:00 +02:00
// Return the number of entries in the GOT.
unsigned int
got_entry_count() const
{
if (this->got_ == NULL)
return 0;
return this->got_size() / (size / 8);
}
// Return the number of entries in the PLT.
unsigned int
plt_entry_count() const;
// Return the offset of the first non-reserved PLT entry.
unsigned int
first_plt_entry_offset() const;
// Return the size of each PLT entry.
unsigned int
plt_entry_size() const;
// Add any special sections for this symbol to the gc work list.
// For powerpc64, this adds the code section of a function
// descriptor.
void
do_gc_mark_symbol(Symbol_table* symtab, Symbol* sym) const;
// Handle target specific gc actions when adding a gc reference from
// SRC_OBJ, SRC_SHNDX to a location specified by DST_OBJ, DST_SHNDX
// and DST_OFF. For powerpc64, this adds a referenc to the code
// section of a function descriptor.
void
do_gc_add_reference(Symbol_table* symtab,
Object* src_obj,
unsigned int src_shndx,
Object* dst_obj,
unsigned int dst_shndx,
Address dst_off) const;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
typedef std::vector<Stub_table<size, big_endian>*> Stub_tables;
const Stub_tables&
stub_tables() const
{ return this->stub_tables_; }
const Output_data_brlt_powerpc<size, big_endian>*
brlt_section() const
{ return this->brlt_section_; }
void
add_branch_lookup_table(Address to)
{
unsigned int off = this->branch_lookup_table_.size() * (size / 8);
this->branch_lookup_table_.insert(std::make_pair(to, off));
}
Address
find_branch_lookup_table(Address to)
{
typename Branch_lookup_table::const_iterator p
= this->branch_lookup_table_.find(to);
return p == this->branch_lookup_table_.end() ? invalid_address : p->second;
}
void
write_branch_lookup_table(unsigned char *oview)
{
for (typename Branch_lookup_table::const_iterator p
= this->branch_lookup_table_.begin();
p != this->branch_lookup_table_.end();
++p)
{
elfcpp::Swap<32, big_endian>::writeval(oview + p->second, p->first);
}
}
bool
plt_thread_safe() const
{ return this->plt_thread_safe_; }
private:
// The class which scans relocations.
class Scan
{
public:
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
Scan()
: issued_non_pic_error_(false)
{ }
gold/ * 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.
2010-11-11 11:43:30 +01:00
static inline int
get_reference_flags(unsigned int r_type);
inline void
local(Symbol_table* symtab, Layout* layout, Target_powerpc* target,
* incremental-dump.cc (dump_incremental_inputs): Print dynamic reloc 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.
2011-05-24 23:41:10 +02:00
Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
Output_section* output_section,
const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
const elfcpp::Sym<size, big_endian>& lsym,
bool is_discarded);
inline void
global(Symbol_table* symtab, Layout* layout, Target_powerpc* target,
* incremental-dump.cc (dump_incremental_inputs): Print dynamic reloc 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.
2011-05-24 23:41:10 +02:00
Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
Output_section* output_section,
const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
Symbol* gsym);
2010-02-12 Sriraman Tallam <tmsriram@google.com> * arm.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. * sparc.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. * powerpc.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. * i386.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. * x86_64.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. (Scan::possible_function_pointer_reloc): New function. (Target_x86_64::can_check_for_function_pointers): New function. * gc.h (gc_process_relocs): Scan relocation types to determine if function pointers were taken for targets that support it. * icf.cc (Icf::find_identical_sections): Include functions for folding in safe ICF whose pointer is not taken. * icf.h (Secn_fptr_taken_set): New typedef. (fptr_section_id_): New member. (section_has_function_pointers): New function. (set_section_has_function_pointers): New function. (check_section_for_function_pointers): New function. * options.h: Fix comment for safe ICF option. * target.h (can_check_for_function_pointers): New function. * testsuite/Makefile.am: Add icf_safe_so_test test case. Modify icf_safe_test for X86-64. * testsuite/Makefile.in: Regenerate. * testsuite/icf_safe_so_test.cc: New file. * testsuite/icf_safe_so_test.sh: New file. * testsuite/icf_safe_test.cc (kept_func_3): New function. (main): Change to take pointer to function kept_func_3. * testsuite/icf_safe_test.sh (arch_specific_safe_fold): Check if safe folding is done correctly for X86-64.
2010-02-13 03:04:21 +01:00
inline bool
local_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
Target_powerpc* ,
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
Sized_relobj_file<size, big_endian>* ,
2010-02-12 Sriraman Tallam <tmsriram@google.com> * arm.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. * sparc.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. * powerpc.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. * i386.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. * x86_64.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. (Scan::possible_function_pointer_reloc): New function. (Target_x86_64::can_check_for_function_pointers): New function. * gc.h (gc_process_relocs): Scan relocation types to determine if function pointers were taken for targets that support it. * icf.cc (Icf::find_identical_sections): Include functions for folding in safe ICF whose pointer is not taken. * icf.h (Secn_fptr_taken_set): New typedef. (fptr_section_id_): New member. (section_has_function_pointers): New function. (set_section_has_function_pointers): New function. (check_section_for_function_pointers): New function. * options.h: Fix comment for safe ICF option. * target.h (can_check_for_function_pointers): New function. * testsuite/Makefile.am: Add icf_safe_so_test test case. Modify icf_safe_test for X86-64. * testsuite/Makefile.in: Regenerate. * testsuite/icf_safe_so_test.cc: New file. * testsuite/icf_safe_so_test.sh: New file. * testsuite/icf_safe_test.cc (kept_func_3): New function. (main): Change to take pointer to function kept_func_3. * testsuite/icf_safe_test.sh (arch_specific_safe_fold): Check if safe folding is done correctly for X86-64.
2010-02-13 03:04:21 +01:00
unsigned int ,
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
Output_section* ,
const elfcpp::Rela<size, big_endian>& ,
unsigned int ,
const elfcpp::Sym<size, big_endian>&)
2010-02-12 Sriraman Tallam <tmsriram@google.com> * arm.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. * sparc.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. * powerpc.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. * i386.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. * x86_64.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. (Scan::possible_function_pointer_reloc): New function. (Target_x86_64::can_check_for_function_pointers): New function. * gc.h (gc_process_relocs): Scan relocation types to determine if function pointers were taken for targets that support it. * icf.cc (Icf::find_identical_sections): Include functions for folding in safe ICF whose pointer is not taken. * icf.h (Secn_fptr_taken_set): New typedef. (fptr_section_id_): New member. (section_has_function_pointers): New function. (set_section_has_function_pointers): New function. (check_section_for_function_pointers): New function. * options.h: Fix comment for safe ICF option. * target.h (can_check_for_function_pointers): New function. * testsuite/Makefile.am: Add icf_safe_so_test test case. Modify icf_safe_test for X86-64. * testsuite/Makefile.in: Regenerate. * testsuite/icf_safe_so_test.cc: New file. * testsuite/icf_safe_so_test.sh: New file. * testsuite/icf_safe_test.cc (kept_func_3): New function. (main): Change to take pointer to function kept_func_3. * testsuite/icf_safe_test.sh (arch_specific_safe_fold): Check if safe folding is done correctly for X86-64.
2010-02-13 03:04:21 +01:00
{ return false; }
inline bool
global_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
Target_powerpc* ,
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
Sized_relobj_file<size, big_endian>* ,
unsigned int ,
Output_section* ,
const elfcpp::Rela<size,
2010-02-12 Sriraman Tallam <tmsriram@google.com> * arm.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. * sparc.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. * powerpc.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. * i386.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. * x86_64.cc (Scan::local_reloc_may_be_function_pointer): New function. (Scan::global_reloc_may_be_function_pointer): New function. (Scan::possible_function_pointer_reloc): New function. (Target_x86_64::can_check_for_function_pointers): New function. * gc.h (gc_process_relocs): Scan relocation types to determine if function pointers were taken for targets that support it. * icf.cc (Icf::find_identical_sections): Include functions for folding in safe ICF whose pointer is not taken. * icf.h (Secn_fptr_taken_set): New typedef. (fptr_section_id_): New member. (section_has_function_pointers): New function. (set_section_has_function_pointers): New function. (check_section_for_function_pointers): New function. * options.h: Fix comment for safe ICF option. * target.h (can_check_for_function_pointers): New function. * testsuite/Makefile.am: Add icf_safe_so_test test case. Modify icf_safe_test for X86-64. * testsuite/Makefile.in: Regenerate. * testsuite/icf_safe_so_test.cc: New file. * testsuite/icf_safe_so_test.sh: New file. * testsuite/icf_safe_test.cc (kept_func_3): New function. (main): Change to take pointer to function kept_func_3. * testsuite/icf_safe_test.sh (arch_specific_safe_fold): Check if safe folding is done correctly for X86-64.
2010-02-13 03:04:21 +01:00
big_endian>& ,
unsigned int , Symbol*)
{ return false; }
private:
static void
* incremental-dump.cc (dump_incremental_inputs): Print dynamic reloc 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.
2011-05-24 23:41:10 +02:00
unsupported_reloc_local(Sized_relobj_file<size, big_endian>*,
unsigned int r_type);
static void
* incremental-dump.cc (dump_incremental_inputs): Print dynamic reloc 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.
2011-05-24 23:41:10 +02:00
unsupported_reloc_global(Sized_relobj_file<size, big_endian>*,
unsigned int r_type, Symbol*);
static void
generate_tls_call(Symbol_table* symtab, Layout* layout,
Target_powerpc* target);
void
check_non_pic(Relobj*, unsigned int r_type);
bool
reloc_needs_plt_for_ifunc(Sized_relobj_file<size, big_endian>* object,
unsigned int r_type);
// Whether we have issued an error about a non-PIC compilation.
bool issued_non_pic_error_;
};
Address
symval_for_branch(Address value, const Sized_symbol<size>* gsym,
Powerpc_relobj<size, big_endian>* object,
unsigned int *dest_shndx);
// The class which implements relocation.
class Relocate
{
public:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// Use 'at' branch hints when true, 'y' when false.
// FIXME maybe: set this with an option.
static const bool is_isa_v2 = true;
enum skip_tls
{
CALL_NOT_EXPECTED = 0,
CALL_EXPECTED = 1,
CALL_SKIP = 2
};
Relocate()
: call_tls_get_addr_(CALL_NOT_EXPECTED)
{ }
~Relocate()
{
if (this->call_tls_get_addr_ != CALL_NOT_EXPECTED)
{
// FIXME: This needs to specify the location somehow.
gold_error(_("missing expected __tls_get_addr call"));
}
}
// Do a relocation. Return false if the caller should not issue
// any warnings about this relocation.
inline bool
relocate(const Relocate_info<size, big_endian>*, Target_powerpc*,
Output_section*, size_t relnum,
const elfcpp::Rela<size, big_endian>&,
unsigned int r_type, const Sized_symbol<size>*,
const Symbol_value<size>*,
unsigned char*,
typename elfcpp::Elf_types<size>::Elf_Addr,
section_size_type);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// This is set if we should skip the next reloc, which should be a
// call to __tls_get_addr.
enum skip_tls call_tls_get_addr_;
};
class Relocate_comdat_behavior
{
public:
// Decide what the linker should do for relocations that refer to
// discarded comdat sections.
inline Comdat_behavior
get(const char* name)
{
gold::Default_comdat_behavior default_behavior;
Comdat_behavior ret = default_behavior.get(name);
if (ret == CB_WARNING)
{
if (size == 32
&& (strcmp(name, ".fixup") == 0
|| strcmp(name, ".got2") == 0))
ret = CB_IGNORE;
if (size == 64
&& (strcmp(name, ".opd") == 0
|| strcmp(name, ".toc") == 0
|| strcmp(name, ".toc1") == 0))
ret = CB_IGNORE;
}
return ret;
}
};
// A class which returns the size required for a relocation type,
// used while scanning relocs during a relocatable link.
class Relocatable_size_for_reloc
{
public:
unsigned int
get_size_for_reloc(unsigned int, Relobj*)
{
gold_unreachable();
return 0;
}
};
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// Optimize the TLS relocation type based on what we know about the
// symbol. IS_FINAL is true if the final address of this symbol is
// known at link time.
tls::Tls_optimization
optimize_tls_gd(bool is_final)
{
// If we are generating a shared library, then we can't do anything
// in the linker.
if (parameters->options().shared())
return tls::TLSOPT_NONE;
if (!is_final)
return tls::TLSOPT_TO_IE;
return tls::TLSOPT_TO_LE;
}
tls::Tls_optimization
optimize_tls_ld()
{
if (parameters->options().shared())
return tls::TLSOPT_NONE;
return tls::TLSOPT_TO_LE;
}
tls::Tls_optimization
optimize_tls_ie(bool is_final)
{
if (!is_final || parameters->options().shared())
return tls::TLSOPT_NONE;
return tls::TLSOPT_TO_LE;
}
// Create glink.
void
make_glink_section(Layout*);
// Create the PLT section.
void
make_plt_section(Symbol_table*, Layout*);
void
make_iplt_section(Symbol_table*, Layout*);
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
void
make_brlt_section(Layout*);
// Create a PLT entry for a global symbol.
void
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
make_plt_entry(Symbol_table*, Layout*, Symbol*);
// Create a PLT entry for a local IFUNC symbol.
void
make_local_ifunc_plt_entry(Symbol_table*, Layout*,
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Sized_relobj_file<size, big_endian>*,
unsigned int);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// Create a GOT entry for local dynamic __tls_get_addr.
unsigned int
tlsld_got_offset(Symbol_table* symtab, Layout* layout,
Sized_relobj_file<size, big_endian>* object);
unsigned int
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
tlsld_got_offset() const
{
return this->tlsld_got_offset_;
}
// Get the dynamic reloc section, creating it if necessary.
Reloc_section*
rela_dyn_section(Layout*);
// Copy a relocation against a global symbol.
void
Handle output sections with more than 0x7fffffff bytes. * object.h (class Relobj): Change map_to_output_ to output_sections_, and just keep a section pointer. Change all uses. Move comdat group support to Sized_relobj. (Relobj::is_section_specially_mapped): Remove. (Relobj::output_section): Remove poff parameter. Change all callers. (Relobj::output_section_offset): New function. (Relobj::set_section_offset): Rewrite. (Relobj::map_to_output): Remove. (Relobj::output_sections): New function. (Relobj::do_output_section_offset): New pure virtual function. (Relobj::do_set_section_offset): Likewise. (class Sized_relobj): Add section_offsets_ field. Add comdat group support from Relobj. Update declarations. (Sized_relobj::get_output_section_offset): New function. (Sized_relobj::do_output_section_offset): New function. (Sized_relobj::do_set_section_offset): New function. * object.cc (Relobj::output_section_address): Remove. (Sized_relobj::Sized_relobj): Initialize new fields. (Sized_relobj::include_section_group): Cast find_kept_object to Sized_relobj. (Sized_relobj::include_linkonce_section): Likewise. (Sized_relobj::do_layout): Use separate arrays for output section and output offset. (Sized_relobj::do_count_local_symbols): Change map_to_output to output_sections. (Sized_relobj::do_finalize_local_symbols): Change map_to_output to output_sections and section_offsets. (Sized_relobj::write_local_symbols): Likewise. (map_to_kept_section): Compute output address directly. * reloc.cc (Sized_relobj::do_read_relocs): Change map_to_output to output_sections and section_offsets. (Sized_relobj::write_sections): Likewise. (Sized_relobj::relocate_sections): Likewise. * symtab.cc (sized_finalize_symbol): Use output_section_offset. * output.h (class Output_reloc): Update declarations. Change u2_.relobj to Sized_relobj*. (class Output_data_reloc): Change add functions to use Sized_relobj*. * output.cc (Output_reloc::Output_reloc): Change relobj to Sized_relobj*. (Output_reloc::local_section_offset): Change return type to Elf_Addr. Use get_output_section_offset. (Output_reloc::get_address): Likewise. (Output_section::is_input_address_mapped): Don't call is_section_specially_mapped. (Output_section::output_offset): Likewise. (Output_section::output_address): Likewise. (Output_section::starting_output_address): Likewise. * copy-relocs.cc (Copy_relocs::copy_reloc): Change object parameter to Sized_relobj*. (Copy_relocs::need_copy_reloc): Likewise. (Copy_relocs::save): Likewise. * copy-relocs.h (class Copy_relocs): Update declarations. (class Copy_relocs::Copy_reloc_entry): Change constructor to use Sized_relobj*. Change relobj_ field to Sized_relobj*. * target-reloc.h (relocate_for_relocatable): Change offset_in_output_section type to Elf_Addr. Change code that uses it as well. * layout.cc (Layout::layout): Always set *off. * mapfile.cc (Mapfile::print_input_section): Use output_section_offset. * i386.cc (Target_i386::copy_reloc): Change object parameter to Sized_relobj*. * powerpc.cc (Target_powerpc::copy_reloc): Likewise. * sparc.cc (Target_sparc::copy_reloc): Likewise. * x86_64.cc (Target_x86_64::copy_reloc): Likewise.
2008-07-11 01:01:20 +02:00
copy_reloc(Symbol_table* symtab, Layout* layout,
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
Sized_relobj_file<size, big_endian>* object,
unsigned int shndx, Output_section* output_section,
Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc)
{
this->copy_relocs_.copy_reloc(symtab, layout,
symtab->get_sized_symbol<size>(sym),
object, shndx, output_section,
reloc, this->rela_dyn_section(layout));
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// Look over all the input sections, deciding where to place stub.
void
group_sections(Layout*, const Task*);
// Sort output sections by address.
struct Sort_sections
{
bool
operator()(const Output_section* sec1, const Output_section* sec2)
{ return sec1->address() < sec2->address(); }
};
class Branch_info
{
public:
Branch_info(Powerpc_relobj<size, big_endian>* ppc_object,
unsigned int data_shndx,
Address r_offset,
unsigned int r_type,
unsigned int r_sym,
Address addend)
: object_(ppc_object), shndx_(data_shndx), offset_(r_offset),
r_type_(r_type), r_sym_(r_sym), addend_(addend)
{ }
~Branch_info()
{ }
// If this branch needs a plt call stub, or a long branch stub, make one.
void
make_stub(Stub_table<size, big_endian>*,
Stub_table<size, big_endian>*,
Symbol_table*) const;
private:
// The branch location..
Powerpc_relobj<size, big_endian>* object_;
unsigned int shndx_;
Address offset_;
// ..and the branch type and destination.
unsigned int r_type_;
unsigned int r_sym_;
Address addend_;
};
// Information about this specific target which we pass to the
// general Target structure.
static Target::Target_info powerpc_info;
// The types of GOT entries needed for this platform.
elfcpp/ChangeLog: * 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.
2010-08-13 00:15:00 +02:00
// These values are exposed to the ABI in an incremental link.
// Do not renumber existing values without changing the version
// number of the .gnu_incremental_inputs section.
enum Got_type
{
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
GOT_TYPE_STANDARD,
GOT_TYPE_TLSGD, // double entry for @got@tlsgd
GOT_TYPE_DTPREL, // entry for @got@dtprel
GOT_TYPE_TPREL // entry for @got@tprel
};
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// The GOT section.
Output_data_got_powerpc<size, big_endian>* got_;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// The PLT section.
Output_data_plt_powerpc<size, big_endian>* plt_;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// The IPLT section.
Output_data_plt_powerpc<size, big_endian>* iplt_;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// Section holding long branch destinations.
Output_data_brlt_powerpc<size, big_endian>* brlt_section_;
// The .glink section.
Output_data_glink<size, big_endian>* glink_;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// The dynamic reloc section.
Reloc_section* rela_dyn_;
// Relocs saved to avoid a COPY reloc.
Copy_relocs<elfcpp::SHT_RELA, size, big_endian> copy_relocs_;
// Space for variables copied with a COPY reloc.
Output_data_space* dynbss_;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// Offset of the GOT entry for local dynamic __tls_get_addr calls.
unsigned int tlsld_got_offset_;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Stub_tables stub_tables_;
typedef Unordered_map<Address, unsigned int> Branch_lookup_table;
Branch_lookup_table branch_lookup_table_;
typedef std::vector<Branch_info> Branches;
Branches branch_info_;
bool plt_thread_safe_;
};
template<>
Target::Target_info Target_powerpc<32, true>::powerpc_info =
{
32, // size
true, // is_big_endian
elfcpp::EM_PPC, // machine_code
false, // has_make_symbol
false, // has_resolve
false, // has_code_fill
true, // is_default_stack_executable
false, // can_icf_inline_merge_sections
'\0', // wrap_char
"/usr/lib/ld.so.1", // dynamic_linker
0x10000000, // default_text_segment_address
64 * 1024, // abi_pagesize (overridable by -z max-page-size)
* layout.cc (Layout::make_output_section): Call Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
2009-06-22 08:51:53 +02:00
4 * 1024, // common_pagesize (overridable by -z common-page-size)
false, // isolate_execinstr
0, // rosegment_gap
* layout.cc (Layout::make_output_section): Call Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
2009-06-22 08:51:53 +02:00
elfcpp::SHN_UNDEF, // small_common_shndx
elfcpp::SHN_UNDEF, // large_common_shndx
0, // small_common_section_flags
0, // large_common_section_flags
NULL, // attributes_section
NULL // attributes_vendor
};
template<>
Target::Target_info Target_powerpc<32, false>::powerpc_info =
{
32, // size
false, // is_big_endian
elfcpp::EM_PPC, // machine_code
false, // has_make_symbol
false, // has_resolve
false, // has_code_fill
true, // is_default_stack_executable
false, // can_icf_inline_merge_sections
'\0', // wrap_char
"/usr/lib/ld.so.1", // dynamic_linker
0x10000000, // default_text_segment_address
64 * 1024, // abi_pagesize (overridable by -z max-page-size)
* layout.cc (Layout::make_output_section): Call Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
2009-06-22 08:51:53 +02:00
4 * 1024, // common_pagesize (overridable by -z common-page-size)
false, // isolate_execinstr
0, // rosegment_gap
* layout.cc (Layout::make_output_section): Call Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
2009-06-22 08:51:53 +02:00
elfcpp::SHN_UNDEF, // small_common_shndx
elfcpp::SHN_UNDEF, // large_common_shndx
0, // small_common_section_flags
0, // large_common_section_flags
NULL, // attributes_section
NULL // attributes_vendor
};
template<>
Target::Target_info Target_powerpc<64, true>::powerpc_info =
{
64, // size
true, // is_big_endian
elfcpp::EM_PPC64, // machine_code
false, // has_make_symbol
false, // has_resolve
false, // has_code_fill
true, // is_default_stack_executable
false, // can_icf_inline_merge_sections
'\0', // wrap_char
"/usr/lib/ld.so.1", // dynamic_linker
0x10000000, // default_text_segment_address
64 * 1024, // abi_pagesize (overridable by -z max-page-size)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
4 * 1024, // common_pagesize (overridable by -z common-page-size)
false, // isolate_execinstr
0, // rosegment_gap
* layout.cc (Layout::make_output_section): Call Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
2009-06-22 08:51:53 +02:00
elfcpp::SHN_UNDEF, // small_common_shndx
elfcpp::SHN_UNDEF, // large_common_shndx
0, // small_common_section_flags
0, // large_common_section_flags
NULL, // attributes_section
NULL // attributes_vendor
};
template<>
Target::Target_info Target_powerpc<64, false>::powerpc_info =
{
64, // size
false, // is_big_endian
elfcpp::EM_PPC64, // machine_code
false, // has_make_symbol
false, // has_resolve
false, // has_code_fill
true, // is_default_stack_executable
false, // can_icf_inline_merge_sections
'\0', // wrap_char
"/usr/lib/ld.so.1", // dynamic_linker
0x10000000, // default_text_segment_address
64 * 1024, // abi_pagesize (overridable by -z max-page-size)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
4 * 1024, // common_pagesize (overridable by -z common-page-size)
false, // isolate_execinstr
0, // rosegment_gap
* layout.cc (Layout::make_output_section): Call Target::new_output_section. (Layout::attach_allocated_section_to_segment): Put large section sections in a separate load segment with the large segment flag set. (Layout::segment_precedes): Sort large data segments after other load segments. (align_file_offset): New static function. (Layout::set_segment_offsets): Use align_file_offset. * output.h (class Output_section): Add is_small_section_ and is_large_section_ fields. (Output_section::is_small_section): New function. (Output_section::set_is_small_section): New function. (Output_section::is_large_section): New function. (Output_section::set_is_large_section): New function. (Output_section::is_large_data_section): New function. (class Output_segment): Add is_large_data_segment_ field. (Output_segment::is_large_data_segment): New function. (Output_segment::set_is_large_data_segment): New function. * output.cc (Output_section::Output_section): Initialize new fields. (Output_segment::Output_segment): Likewise. (Output_segment::add_output_section): Add assertion that large data sections always go in large data segments. Force small data sections to the end of the list of data sections. Force small BSS sections to the start of the list of BSS sections. For large BSS sections to the end of the list of BSS sections. * symtab.h (class Symbol): Declare is_common_shndx. (Symbol::is_defined): Check Symbol::is_common_shndx. (Symbol::is_common): Likewise. (class Symbol_table): Define enum Commons_section_type. Update declarations. Add small_commons_ and large_commons_ fields. * symtab.cc (Symbol::is_common_shndx): New function. (Symbol_table::Symbol_table): Initialize new fields. (Symbol_table::add_from_object): Put small and large common symbols in the right list. (Symbol_table::sized_finalized_symbol): Check Symbol::is_common_shndx. (Symbol_table::sized_write_globals): Likewise. * common.cc (Symbol_table::do_allocate_commons): Allocate new common symbol lists. Don't call do_allocate_commons_list if the list is empty. (Symbol_table::do_allocate_commons_list): Remove is_tls parameter. Add comons_section_type parameter. Change all callers. Handle small and large common symbols. * object.cc (Sized_relobj::do_finalize_local_symbols): Check Symbol::is_common_shndx. * resolve.cc (symbol_to_bits): Likewise. * target.h (Target::small_common_shndx): New function. (Target::small_common_section_flags): New function. (Target::large_common_shndx): New function. (Target::large_common_section_flags): New function. (Target::new_output_section): New function. (Target::Target_info): Add small_common_shndx, large_common_shndx, small_common_section_flags, and large_common_section_flags fields. (Target::do_new_output_section): New virtual function. * arm.cc (Target_arm::arm_info): Initialize new fields. * i386.cc (Target_i386::i386_info): Likewise. * powerpc.cc (Target_powerpc::powerpc_info) [all versions]: Likewise. * sparc.c (Target_sparc::sparc_info) [all versions]: Likewise. * x86_64.cc (Target_x86_64::x86_64_info): Likewise. (Target_x86_64::do_new_output_section): New function. * configure.ac: Define conditional MCMODEL_MEDIUM. * testsuite/Makefile.am (check_PROGRAMS): Add large. (large_SOURCES, large_CFLAGS, large_DEPENDENCIES): Define. (large_LDFLAGS): Define. * testsuite/large.c: New file. * testsuite/testfile.cc (Target_test::test_target_info): Initialize new fields. * configure, testsuite/Makefile.in: Rebuild.
2009-06-22 08:51:53 +02:00
elfcpp::SHN_UNDEF, // small_common_shndx
elfcpp::SHN_UNDEF, // large_common_shndx
0, // small_common_section_flags
0, // large_common_section_flags
NULL, // attributes_section
NULL // attributes_vendor
};
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
inline bool
is_branch_reloc(unsigned int r_type)
{
return (r_type == elfcpp::R_POWERPC_REL24
|| r_type == elfcpp::R_PPC_PLTREL24
|| r_type == elfcpp::R_PPC_LOCAL24PC
|| r_type == elfcpp::R_POWERPC_REL14
|| r_type == elfcpp::R_POWERPC_REL14_BRTAKEN
|| r_type == elfcpp::R_POWERPC_REL14_BRNTAKEN
|| r_type == elfcpp::R_POWERPC_ADDR24
|| r_type == elfcpp::R_POWERPC_ADDR14
|| r_type == elfcpp::R_POWERPC_ADDR14_BRTAKEN
|| r_type == elfcpp::R_POWERPC_ADDR14_BRNTAKEN);
}
// If INSN is an opcode that may be used with an @tls operand, return
// the transformed insn for TLS optimisation, otherwise return 0. If
// REG is non-zero only match an insn with RB or RA equal to REG.
uint32_t
at_tls_transform(uint32_t insn, unsigned int reg)
{
if ((insn & (0x3f << 26)) != 31 << 26)
return 0;
unsigned int rtra;
if (reg == 0 || ((insn >> 11) & 0x1f) == reg)
rtra = insn & ((1 << 26) - (1 << 16));
else if (((insn >> 16) & 0x1f) == reg)
rtra = (insn & (0x1f << 21)) | ((insn & (0x1f << 11)) << 5);
else
return 0;
if ((insn & (0x3ff << 1)) == 266 << 1)
// add -> addi
insn = 14 << 26;
else if ((insn & (0x1f << 1)) == 23 << 1
&& ((insn & (0x1f << 6)) < 14 << 6
|| ((insn & (0x1f << 6)) >= 16 << 6
&& (insn & (0x1f << 6)) < 24 << 6)))
// load and store indexed -> dform
insn = (32 | ((insn >> 6) & 0x1f)) << 26;
else if ((insn & (((0x1a << 5) | 0x1f) << 1)) == 21 << 1)
// ldx, ldux, stdx, stdux -> ld, ldu, std, stdu
insn = ((58 | ((insn >> 6) & 4)) << 26) | ((insn >> 6) & 1);
else if ((insn & (((0x1f << 5) | 0x1f) << 1)) == 341 << 1)
// lwax -> lwa
insn = (58 << 26) | 2;
else
return 0;
insn |= rtra;
return insn;
}
// Modified version of symtab.h class Symbol member
// Given a direct absolute or pc-relative static relocation against
// the global symbol, this function returns whether a dynamic relocation
// is needed.
template<int size>
bool
needs_dynamic_reloc(const Symbol* gsym, int flags)
{
// No dynamic relocations in a static link!
if (parameters->doing_static_link())
return false;
// A reference to an undefined symbol from an executable should be
// statically resolved to 0, and does not need a dynamic relocation.
// This matches gnu ld behavior.
if (gsym->is_undefined() && !parameters->options().shared())
return false;
// A reference to an absolute symbol does not need a dynamic relocation.
if (gsym->is_absolute())
return false;
// An absolute reference within a position-independent output file
// will need a dynamic relocation.
if ((flags & Symbol::ABSOLUTE_REF)
&& parameters->options().output_is_position_independent())
return true;
// A function call that can branch to a local PLT entry does not need
// a dynamic relocation.
if ((flags & Symbol::FUNCTION_CALL) && gsym->has_plt_offset())
return false;
// A reference to any PLT entry in a non-position-independent executable
// does not need a dynamic relocation.
// Except due to having function descriptors on powerpc64 we don't define
// functions to their plt code in an executable, so this doesn't apply.
if (size == 32
&& !parameters->options().output_is_position_independent()
&& gsym->has_plt_offset())
return false;
// A reference to a symbol defined in a dynamic object or to a
// symbol that is preemptible will need a dynamic relocation.
if (gsym->is_from_dynobj()
|| gsym->is_undefined()
|| gsym->is_preemptible())
return true;
// For all other cases, return FALSE.
return false;
}
// Modified version of symtab.h class Symbol member
// Whether we should use the PLT offset associated with a symbol for
// a relocation. FLAGS is a set of Reference_flags.
template<int size>
bool
use_plt_offset(const Symbol* gsym, int flags)
{
// If the symbol doesn't have a PLT offset, then naturally we
// don't want to use it.
if (!gsym->has_plt_offset())
return false;
// For a STT_GNU_IFUNC symbol we always have to use the PLT entry.
if (gsym->type() == elfcpp::STT_GNU_IFUNC)
return true;
// If we are going to generate a dynamic relocation, then we will
// wind up using that, so no need to use the PLT entry.
if (needs_dynamic_reloc<size>(gsym, flags))
return false;
// If the symbol is from a dynamic object, we need to use the PLT
// entry.
if (gsym->is_from_dynobj())
return true;
// If we are generating a shared object, and this symbol is
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// undefined or preemptible, we need to use the PLT entry.
if (parameters->options().shared()
&& (gsym->is_undefined() || gsym->is_preemptible()))
return true;
// If this is a call to a weak undefined symbol, we need to use
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// the PLT entry; the symbol may be defined by a library loaded
// at runtime.
if ((flags & Symbol::FUNCTION_CALL) && gsym->is_weak_undefined())
return true;
// Otherwise we can use the regular definition.
return false;
}
template<int size, bool big_endian>
class Powerpc_relocate_functions
{
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
public:
enum Overflow_check
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{
CHECK_NONE,
CHECK_SIGNED,
CHECK_BITFIELD
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
};
enum Status
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{
STATUS_OK,
STATUS_OVERFLOW
};
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
private:
typedef Powerpc_relocate_functions<size, big_endian> This;
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
template<int valsize>
static inline bool
has_overflow_signed(Address value)
{
// limit = 1 << (valsize - 1) without shift count exceeding size of type
Address limit = static_cast<Address>(1) << ((valsize - 1) >> 1);
limit <<= ((valsize - 1) >> 1);
limit <<= ((valsize - 1) - 2 * ((valsize - 1) >> 1));
return value + limit > (limit << 1) - 1;
}
template<int valsize>
static inline bool
has_overflow_bitfield(Address value)
{
Address limit = static_cast<Address>(1) << ((valsize - 1) >> 1);
limit <<= ((valsize - 1) >> 1);
limit <<= ((valsize - 1) - 2 * ((valsize - 1) >> 1));
return value > (limit << 1) - 1 && value + limit > (limit << 1) - 1;
}
template<int valsize>
static inline Status
overflowed(Address value, Overflow_check overflow)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{
if (overflow == CHECK_SIGNED)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{
if (has_overflow_signed<valsize>(value))
return STATUS_OVERFLOW;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
else if (overflow == CHECK_BITFIELD)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{
if (has_overflow_bitfield<valsize>(value))
return STATUS_OVERFLOW;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
return STATUS_OK;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
// Do a simple RELA relocation
template<int valsize>
static inline Status
rela(unsigned char* view, Address value, Overflow_check overflow)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{
typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
Valtype* wv = reinterpret_cast<Valtype*>(view);
elfcpp::Swap<valsize, big_endian>::writeval(wv, value);
return overflowed<valsize>(value, overflow);
}
template<int valsize>
static inline Status
rela(unsigned char* view,
unsigned int right_shift,
typename elfcpp::Valtype_base<valsize>::Valtype dst_mask,
Address value,
Overflow_check overflow)
{
typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
Valtype* wv = reinterpret_cast<Valtype*>(view);
Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Valtype reloc = value >> right_shift;
val &= ~dst_mask;
reloc &= dst_mask;
elfcpp::Swap<valsize, big_endian>::writeval(wv, val | reloc);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
return overflowed<valsize>(value >> right_shift, overflow);
}
// Do a simple RELA relocation, unaligned.
template<int valsize>
static inline Status
rela_ua(unsigned char* view, Address value, Overflow_check overflow)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{
elfcpp::Swap_unaligned<valsize, big_endian>::writeval(view, value);
return overflowed<valsize>(value, overflow);
}
template<int valsize>
static inline Status
rela_ua(unsigned char* view,
unsigned int right_shift,
typename elfcpp::Valtype_base<valsize>::Valtype dst_mask,
Address value,
Overflow_check overflow)
{
typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype
Valtype;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Valtype val = elfcpp::Swap<valsize, big_endian>::readval(view);
Valtype reloc = value >> right_shift;
val &= ~dst_mask;
reloc &= dst_mask;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
elfcpp::Swap_unaligned<valsize, big_endian>::writeval(view, val | reloc);
return overflowed<valsize>(value >> right_shift, overflow);
}
public:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// R_PPC64_ADDR64: (Symbol + Addend)
static inline void
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
addr64(unsigned char* view, Address value)
{ This::template rela<64>(view, value, CHECK_NONE); }
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// R_PPC64_UADDR64: (Symbol + Addend) unaligned
static inline void
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
addr64_u(unsigned char* view, Address value)
{ This::template rela_ua<64>(view, value, CHECK_NONE); }
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// R_POWERPC_ADDR32: (Symbol + Addend)
static inline Status
addr32(unsigned char* view, Address value, Overflow_check overflow)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{ return This::template rela<32>(view, value, overflow); }
// R_POWERPC_UADDR32: (Symbol + Addend) unaligned
static inline Status
addr32_u(unsigned char* view, Address value, Overflow_check overflow)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{ return This::template rela_ua<32>(view, value, overflow); }
// R_POWERPC_ADDR24: (Symbol + Addend) & 0x3fffffc
static inline Status
addr24(unsigned char* view, Address value, Overflow_check overflow)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{
Status stat = This::template rela<32>(view, 0, 0x03fffffc, value, overflow);
if (overflow != CHECK_NONE && (value & 3) != 0)
stat = STATUS_OVERFLOW;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
return stat;
}
// R_POWERPC_ADDR16: (Symbol + Addend) & 0xffff
static inline Status
addr16(unsigned char* view, Address value, Overflow_check overflow)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{ return This::template rela<16>(view, value, overflow); }
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// R_POWERPC_ADDR16: (Symbol + Addend) & 0xffff, unaligned
static inline Status
addr16_u(unsigned char* view, Address value, Overflow_check overflow)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{ return This::template rela_ua<16>(view, value, overflow); }
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// R_POWERPC_ADDR16_DS: (Symbol + Addend) & 0xfffc
static inline Status
addr16_ds(unsigned char* view, Address value, Overflow_check overflow)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{
Status stat = This::template rela<16>(view, 0, 0xfffc, value, overflow);
if (overflow != CHECK_NONE && (value & 3) != 0)
stat = STATUS_OVERFLOW;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
return stat;
}
// R_POWERPC_ADDR16_HI: ((Symbol + Addend) >> 16) & 0xffff
static inline void
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
addr16_hi(unsigned char* view, Address value)
{ This::template rela<16>(view, 16, 0xffff, value, CHECK_NONE); }
// R_POWERPC_ADDR16_HA: ((Symbol + Addend + 0x8000) >> 16) & 0xffff
static inline void
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
addr16_ha(unsigned char* view, Address value)
{ This::addr16_hi(view, value + 0x8000); }
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// R_POWERPC_ADDR16_HIGHER: ((Symbol + Addend) >> 32) & 0xffff
static inline void
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
addr16_hi2(unsigned char* view, Address value)
{ This::template rela<16>(view, 32, 0xffff, value, CHECK_NONE); }
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// R_POWERPC_ADDR16_HIGHERA: ((Symbol + Addend + 0x8000) >> 32) & 0xffff
static inline void
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
addr16_ha2(unsigned char* view, Address value)
{ This::addr16_hi2(view, value + 0x8000); }
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// R_POWERPC_ADDR16_HIGHEST: ((Symbol + Addend) >> 48) & 0xffff
static inline void
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
addr16_hi3(unsigned char* view, Address value)
{ This::template rela<16>(view, 48, 0xffff, value, CHECK_NONE); }
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// R_POWERPC_ADDR16_HIGHESTA: ((Symbol + Addend + 0x8000) >> 48) & 0xffff
static inline void
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
addr16_ha3(unsigned char* view, Address value)
{ This::addr16_hi3(view, value + 0x8000); }
// R_POWERPC_ADDR14: (Symbol + Addend) & 0xfffc
static inline Status
addr14(unsigned char* view, Address value, Overflow_check overflow)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{
Status stat = This::template rela<32>(view, 0, 0xfffc, value, overflow);
if (overflow != CHECK_NONE && (value & 3) != 0)
stat = STATUS_OVERFLOW;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
return stat;
}
};
// Stash away the index of .got2 or .opd in a relocatable object, if
// such a section exists.
template<int size, bool big_endian>
bool
Powerpc_relobj<size, big_endian>::do_find_special_sections(
Read_symbols_data* sd)
{
const unsigned char* const pshdrs = sd->section_headers->data();
const unsigned char* namesu = sd->section_names->data();
const char* names = reinterpret_cast<const char*>(namesu);
section_size_type names_size = sd->section_names_size;
const unsigned char* s;
s = this->find_shdr(pshdrs, size == 32 ? ".got2" : ".opd",
names, names_size, NULL);
if (s != NULL)
{
unsigned int ndx = (s - pshdrs) / elfcpp::Elf_sizes<size>::shdr_size;
this->special_ = ndx;
}
return Sized_relobj_file<size, big_endian>::do_find_special_sections(sd);
}
// Examine .rela.opd to build info about function entry points.
template<int size, bool big_endian>
void
Powerpc_relobj<size, big_endian>::scan_opd_relocs(
size_t reloc_count,
const unsigned char* prelocs,
const unsigned char* plocal_syms)
{
if (size == 64)
{
typedef typename Reloc_types<elfcpp::SHT_RELA, size, big_endian>::Reloc
Reltype;
const int reloc_size
= Reloc_types<elfcpp::SHT_RELA, size, big_endian>::reloc_size;
const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
Address expected_off = 0;
bool regular = true;
unsigned int opd_ent_size = 0;
for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
{
Reltype reloc(prelocs);
typename elfcpp::Elf_types<size>::Elf_WXword r_info
= reloc.get_r_info();
unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
if (r_type == elfcpp::R_PPC64_ADDR64)
{
unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
typename elfcpp::Elf_types<size>::Elf_Addr value;
bool is_ordinary;
unsigned int shndx;
if (r_sym < this->local_symbol_count())
{
typename elfcpp::Sym<size, big_endian>
lsym(plocal_syms + r_sym * sym_size);
shndx = lsym.get_st_shndx();
shndx = this->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
value = lsym.get_st_value();
}
else
shndx = this->symbol_section_and_value(r_sym, &value,
&is_ordinary);
this->set_opd_ent(reloc.get_r_offset(), shndx,
value + reloc.get_r_addend());
if (i == 2)
{
expected_off = reloc.get_r_offset();
opd_ent_size = expected_off;
}
else if (expected_off != reloc.get_r_offset())
regular = false;
expected_off += opd_ent_size;
}
else if (r_type == elfcpp::R_PPC64_TOC)
{
if (expected_off - opd_ent_size + 8 != reloc.get_r_offset())
regular = false;
}
else
{
gold_warning(_("%s: unexpected reloc type %u in .opd section"),
this->name().c_str(), r_type);
regular = false;
}
}
if (reloc_count <= 2)
opd_ent_size = this->section_size(this->opd_shndx());
if (opd_ent_size != 24 && opd_ent_size != 16)
regular = false;
if (!regular)
{
gold_warning(_("%s: .opd is not a regular array of opd entries"),
this->name().c_str());
opd_ent_size = 0;
}
}
}
template<int size, bool big_endian>
void
Powerpc_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
{
Sized_relobj_file<size, big_endian>::do_read_relocs(rd);
if (size == 64)
{
for (Read_relocs_data::Relocs_list::iterator p = rd->relocs.begin();
p != rd->relocs.end();
++p)
{
if (p->data_shndx == this->opd_shndx())
{
uint64_t opd_size = this->section_size(this->opd_shndx());
gold_assert(opd_size == static_cast<size_t>(opd_size));
if (opd_size != 0)
{
this->init_opd(opd_size);
this->scan_opd_relocs(p->reloc_count, p->contents->data(),
rd->local_symbols->data());
}
break;
}
}
}
}
// Set up some symbols.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::do_define_standard_symbols(
Symbol_table* symtab,
Layout* layout)
{
if (size == 32)
{
// Define _GLOBAL_OFFSET_TABLE_ to ensure it isn't seen as
// undefined when scanning relocs (and thus requires
// non-relative dynamic relocs). The proper value will be
// updated later.
Symbol *gotsym = symtab->lookup("_GLOBAL_OFFSET_TABLE_", NULL);
if (gotsym != NULL && gotsym->is_undefined())
{
Target_powerpc<size, big_endian>* target =
static_cast<Target_powerpc<size, big_endian>*>(
parameters->sized_target<size, big_endian>());
Output_data_got_powerpc<size, big_endian>* got
= target->got_section(symtab, layout);
symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
Symbol_table::PREDEFINED,
got, 0, 0,
elfcpp::STT_OBJECT,
elfcpp::STB_LOCAL,
elfcpp::STV_HIDDEN, 0,
false, false);
}
// Define _SDA_BASE_ at the start of the .sdata section + 32768.
Symbol *sdasym = symtab->lookup("_SDA_BASE_", NULL);
if (sdasym != NULL && sdasym->is_undefined())
{
Output_data_space* sdata = new Output_data_space(4, "** sdata");
Output_section* os
= layout->add_output_section_data(".sdata", 0,
elfcpp::SHF_ALLOC
| elfcpp::SHF_WRITE,
sdata, ORDER_SMALL_DATA, false);
symtab->define_in_output_data("_SDA_BASE_", NULL,
Symbol_table::PREDEFINED,
os, 32768, 0, elfcpp::STT_OBJECT,
elfcpp::STB_LOCAL, elfcpp::STV_HIDDEN,
0, false, false);
}
}
}
// Set up PowerPC target specific relobj.
template<int size, bool big_endian>
Object*
Target_powerpc<size, big_endian>::do_make_elf_object(
const std::string& name,
Input_file* input_file,
off_t offset, const elfcpp::Ehdr<size, big_endian>& ehdr)
{
int et = ehdr.get_e_type();
// ET_EXEC files are valid input for --just-symbols/-R,
// and we treat them as relocatable objects.
if (et == elfcpp::ET_REL
|| (et == elfcpp::ET_EXEC && input_file->just_symbols()))
{
Powerpc_relobj<size, big_endian>* obj =
new Powerpc_relobj<size, big_endian>(name, input_file, offset, ehdr);
obj->setup();
return obj;
}
else if (et == elfcpp::ET_DYN)
{
Sized_dynobj<size, big_endian>* obj =
new Sized_dynobj<size, big_endian>(name, input_file, offset, ehdr);
obj->setup();
return obj;
}
else
{
gold_error(_("%s: unsupported ELF file type %d"), name.c_str(), et);
return NULL;
}
}
template<int size, bool big_endian>
class Output_data_got_powerpc : public Output_data_got<size, big_endian>
{
public:
typedef typename elfcpp::Elf_types<size>::Elf_Addr Valtype;
typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian> Rela_dyn;
Output_data_got_powerpc(Symbol_table* symtab, Layout* layout)
: Output_data_got<size, big_endian>(),
symtab_(symtab), layout_(layout),
header_ent_cnt_(size == 32 ? 3 : 1),
header_index_(size == 32 ? 0x2000 : 0)
{ }
class Got_entry;
// Create a new GOT entry and return its offset.
unsigned int
add_got_entry(Got_entry got_entry)
{
this->reserve_ent();
return Output_data_got<size, big_endian>::add_got_entry(got_entry);
}
// Create a pair of new GOT entries and return the offset of the first.
unsigned int
add_got_entry_pair(Got_entry got_entry_1, Got_entry got_entry_2)
{
this->reserve_ent(2);
return Output_data_got<size, big_endian>::add_got_entry_pair(got_entry_1,
got_entry_2);
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
unsigned int
add_constant_pair(Valtype c1, Valtype c2)
{
this->reserve_ent(2);
unsigned int got_offset = this->add_constant(c1);
this->add_constant(c2);
return got_offset;
}
// Offset of _GLOBAL_OFFSET_TABLE_.
unsigned int
g_o_t() const
{
return this->got_offset(this->header_index_);
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// Offset of base used to access the GOT/TOC.
// The got/toc pointer reg will be set to this value.
Valtype
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
got_base_offset(const Powerpc_relobj<size, big_endian>* object) const
{
if (size == 32)
return this->g_o_t();
else
return (this->output_section()->address()
+ object->toc_base_offset()
- this->address());
}
// Ensure our GOT has a header.
void
set_final_data_size()
{
if (this->header_ent_cnt_ != 0)
this->make_header();
Output_data_got<size, big_endian>::set_final_data_size();
}
// First word of GOT header needs some values that are not
// handled by Output_data_got so poke them in here.
// For 32-bit, address of .dynamic, for 64-bit, address of TOCbase.
void
do_write(Output_file* of)
{
Valtype val = 0;
if (size == 32 && this->layout_->dynamic_data() != NULL)
val = this->layout_->dynamic_section()->address();
if (size == 64)
val = this->output_section()->address() + 0x8000;
this->replace_constant(this->header_index_, val);
Output_data_got<size, big_endian>::do_write(of);
}
private:
void
reserve_ent(unsigned int cnt = 1)
{
if (this->header_ent_cnt_ == 0)
return;
if (this->num_entries() + cnt > this->header_index_)
this->make_header();
}
void
make_header()
{
this->header_ent_cnt_ = 0;
this->header_index_ = this->num_entries();
if (size == 32)
{
Output_data_got<size, big_endian>::add_constant(0);
Output_data_got<size, big_endian>::add_constant(0);
Output_data_got<size, big_endian>::add_constant(0);
// Define _GLOBAL_OFFSET_TABLE_ at the header
Symbol *gotsym = this->symtab_->lookup("_GLOBAL_OFFSET_TABLE_", NULL);
if (gotsym != NULL)
{
Sized_symbol<size>* sym = static_cast<Sized_symbol<size>*>(gotsym);
sym->set_value(this->g_o_t());
}
else
this->symtab_->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
Symbol_table::PREDEFINED,
this, this->g_o_t(), 0,
elfcpp::STT_OBJECT,
elfcpp::STB_LOCAL,
elfcpp::STV_HIDDEN, 0,
false, false);
}
else
Output_data_got<size, big_endian>::add_constant(0);
}
// Stashed pointers.
Symbol_table* symtab_;
Layout* layout_;
// GOT header size.
unsigned int header_ent_cnt_;
// GOT header index.
unsigned int header_index_;
};
// Get the GOT section, creating it if necessary.
template<int size, bool big_endian>
Output_data_got_powerpc<size, big_endian>*
Target_powerpc<size, big_endian>::got_section(Symbol_table* symtab,
Layout* layout)
{
if (this->got_ == NULL)
{
gold_assert(symtab != NULL && layout != NULL);
this->got_
= new Output_data_got_powerpc<size, big_endian>(symtab, layout);
layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
2010-08-03 Ian Lance Taylor <iant@google.com> PR 11805 * layout.h (enum Output_section_order): Define. (class Layout): Update declarations. * layout.cc (Layout::get_output_section): Add order parameter. Remove is_interp, is_dynamic_linker_section, is_last_relro, and is_first_non_relro parameters. Change all callers. (Layout::choose_output_section): Likewise. (Layout::add_output_section_data): Likewise. (Layout::make_output_section): Likewise. Set order. (Layout::default_section_order): New function. (Layout::layout_eh_frame): Call add_output_section_to_nonload. * output.cc (Output_section::Output_section): Initialize order_. Don't initialize deleted fields. (Output_segment::Output_segment): Don't initialize deleted fields. (Output_segment::add_output_section_to_load): New function replacing add_output_section. Change all callers to call this or add_output_section_to_nonload. (Output_segment::add_output_section_to_nonload): New function. (Output_segment::remove_output_section): Rewrite. (Output_segment::add_initial_output_data): Likewise. (Output_segment::has_any_data_sections): Likewise. (Output_segment::is_first_section_relro): Likewise. (Output_segment::maximum_alignment): Likewise. (Output_segment::has_dynamic_reloc): New function replacing dynamic_reloc_count. Change all callers. (Output_segment::has_dynamic_reloc_list): New function replacing dynamic_reloc_count_list. Change all callers. (Output_segment::set_section_addresses): Rewrite. (Output_segment::set_offset): Rewrite. (Output_segment::find_first_and_last_list): Remove. (Output_segment::set_tls_offsets): Rewrite. (Output_segment::first_section_load_address): Likewise. (Output_segment::output_section_count): Likewise. (Output_segment::section_with_lowest_load_address): Likewise. (Output_segment::write_section_headers): Likewise. (Output_segment::print_sections_to_map): Likewise. * output.h (class Output_data): Remove dynamic_reloc_count_ field. Add has_dynamic_reloc_ field. Make bools into bitfields. (Output_data::add_dynamic_reloc): Rewrite. (Output_data::has_dynamic_reloc): New function. (Output_data::dynamic_reloc_count): Remove. (class Output_section): Add order_ field. Remvoe is_relro_local_, is_last_relro_, is_first_non_relro_, is_interp_, is_dynamic_linker_section_ fields. Add order and set_order functions. Remove is_relro_local, set_is_relro_local, is_last_relro, set_is_last_relro, is_first_non_relro, set_is_first_non_relro functions, is_interp, set_is_interp, is_dynamic_linker_section, and set_is_dynamic_linker_section functions. (class Output_segment): Change Output_data_list from std::list to std:;vector. Add output_lists_ field. Remove output_data_ and output_bss_ fields. Update declarations.
2010-08-03 16:07:13 +02:00
this->got_, ORDER_DATA, false);
}
return this->got_;
}
// Get the dynamic reloc section, creating it if necessary.
template<int size, bool big_endian>
typename Target_powerpc<size, big_endian>::Reloc_section*
Target_powerpc<size, big_endian>::rela_dyn_section(Layout* layout)
{
if (this->rela_dyn_ == NULL)
{
gold_assert(layout != NULL);
this->rela_dyn_ = new Reloc_section(parameters->options().combreloc());
layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
2010-08-03 Ian Lance Taylor <iant@google.com> PR 11805 * layout.h (enum Output_section_order): Define. (class Layout): Update declarations. * layout.cc (Layout::get_output_section): Add order parameter. Remove is_interp, is_dynamic_linker_section, is_last_relro, and is_first_non_relro parameters. Change all callers. (Layout::choose_output_section): Likewise. (Layout::add_output_section_data): Likewise. (Layout::make_output_section): Likewise. Set order. (Layout::default_section_order): New function. (Layout::layout_eh_frame): Call add_output_section_to_nonload. * output.cc (Output_section::Output_section): Initialize order_. Don't initialize deleted fields. (Output_segment::Output_segment): Don't initialize deleted fields. (Output_segment::add_output_section_to_load): New function replacing add_output_section. Change all callers to call this or add_output_section_to_nonload. (Output_segment::add_output_section_to_nonload): New function. (Output_segment::remove_output_section): Rewrite. (Output_segment::add_initial_output_data): Likewise. (Output_segment::has_any_data_sections): Likewise. (Output_segment::is_first_section_relro): Likewise. (Output_segment::maximum_alignment): Likewise. (Output_segment::has_dynamic_reloc): New function replacing dynamic_reloc_count. Change all callers. (Output_segment::has_dynamic_reloc_list): New function replacing dynamic_reloc_count_list. Change all callers. (Output_segment::set_section_addresses): Rewrite. (Output_segment::set_offset): Rewrite. (Output_segment::find_first_and_last_list): Remove. (Output_segment::set_tls_offsets): Rewrite. (Output_segment::first_section_load_address): Likewise. (Output_segment::output_section_count): Likewise. (Output_segment::section_with_lowest_load_address): Likewise. (Output_segment::write_section_headers): Likewise. (Output_segment::print_sections_to_map): Likewise. * output.h (class Output_data): Remove dynamic_reloc_count_ field. Add has_dynamic_reloc_ field. Make bools into bitfields. (Output_data::add_dynamic_reloc): Rewrite. (Output_data::has_dynamic_reloc): New function. (Output_data::dynamic_reloc_count): Remove. (class Output_section): Add order_ field. Remvoe is_relro_local_, is_last_relro_, is_first_non_relro_, is_interp_, is_dynamic_linker_section_ fields. Add order and set_order functions. Remove is_relro_local, set_is_relro_local, is_last_relro, set_is_last_relro, is_first_non_relro, set_is_first_non_relro functions, is_interp, set_is_interp, is_dynamic_linker_section, and set_is_dynamic_linker_section functions. (class Output_segment): Change Output_data_list from std::list to std:;vector. Add output_lists_ field. Remove output_data_ and output_bss_ fields. Update declarations.
2010-08-03 16:07:13 +02:00
elfcpp::SHF_ALLOC, this->rela_dyn_,
ORDER_DYNAMIC_RELOCS, false);
}
return this->rela_dyn_;
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
class Stub_control
{
public:
// Determine the stub group size. The group size is the absolute
// value of the parameter --stub-group-size. If --stub-group-size
// is passed a negative value, we restrict stubs to be always before
// the stubbed branches.
Stub_control(int32_t size)
: state_(NO_GROUP), stub_group_size_(abs(size)),
stub14_group_size_(abs(size)),
stubs_always_before_branch_(size < 0), suppress_size_errors_(false),
group_end_addr_(0), owner_(NULL), output_section_(NULL)
{
if (stub_group_size_ == 1)
{
// Default values.
if (stubs_always_before_branch_)
{
stub_group_size_ = 0x1e00000;
stub14_group_size_ = 0x7800;
}
else
{
stub_group_size_ = 0x1c00000;
stub14_group_size_ = 0x7000;
}
suppress_size_errors_ = true;
}
}
// Return true iff input section can be handled by current stub
// group.
bool
can_add_to_stub_group(Output_section* o,
const Output_section::Input_section* i,
bool has14);
const Output_section::Input_section*
owner()
{ return owner_; }
Output_section*
output_section()
{ return output_section_; }
private:
typedef enum
{
NO_GROUP,
FINDING_STUB_SECTION,
HAS_STUB_SECTION
} State;
State state_;
uint32_t stub_group_size_;
uint32_t stub14_group_size_;
bool stubs_always_before_branch_;
bool suppress_size_errors_;
uint64_t group_end_addr_;
const Output_section::Input_section* owner_;
Output_section* output_section_;
};
// Return true iff input section can be handled by current stub/
// group.
bool
Stub_control::can_add_to_stub_group(Output_section* o,
const Output_section::Input_section* i,
bool has14)
{
uint32_t group_size
= has14 ? this->stub14_group_size_ : this->stub_group_size_;
bool whole_sec = o->order() == ORDER_INIT || o->order() == ORDER_FINI;
uint64_t this_size;
uint64_t start_addr = o->address();
if (whole_sec)
// .init and .fini sections are pasted together to form a single
// function. We can't be adding stubs in the middle of the function.
this_size = o->data_size();
else
{
start_addr += i->relobj()->output_section_offset(i->shndx());
this_size = i->data_size();
}
uint64_t end_addr = start_addr + this_size;
bool toobig = this_size > group_size;
if (toobig && !this->suppress_size_errors_)
gold_warning(_("%s:%s exceeds group size"),
i->relobj()->name().c_str(),
i->relobj()->section_name(i->shndx()).c_str());
if (this->state_ != HAS_STUB_SECTION
&& (!whole_sec || this->output_section_ != o))
{
this->owner_ = i;
this->output_section_ = o;
}
if (this->state_ == NO_GROUP)
{
this->state_ = FINDING_STUB_SECTION;
this->group_end_addr_ = end_addr;
}
else if (this->group_end_addr_ - start_addr < group_size)
;
// Adding this section would make the group larger than GROUP_SIZE.
else if (this->state_ == FINDING_STUB_SECTION
&& !this->stubs_always_before_branch_
&& !toobig)
{
// But wait, there's more! Input sections up to GROUP_SIZE
// bytes before the stub table can be handled by it too.
this->state_ = HAS_STUB_SECTION;
this->group_end_addr_ = end_addr;
}
else
{
this->state_ = NO_GROUP;
return false;
}
return true;
}
// Look over all the input sections, deciding where to place stubs.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::group_sections(Layout* layout,
const Task*)
{
Stub_control stub_control(parameters->options().stub_group_size());
// Group input sections and insert stub table
Stub_table<size, big_endian>* stub_table = NULL;
Layout::Section_list section_list;
layout->get_executable_sections(&section_list);
std::stable_sort(section_list.begin(), section_list.end(), Sort_sections());
for (Layout::Section_list::reverse_iterator o = section_list.rbegin();
o != section_list.rend();
++o)
{
typedef Output_section::Input_section_list Input_section_list;
for (Input_section_list::const_reverse_iterator i
= (*o)->input_sections().rbegin();
i != (*o)->input_sections().rend();
++i)
{
if (i->is_input_section())
{
Powerpc_relobj<size, big_endian>* ppcobj = static_cast
<Powerpc_relobj<size, big_endian>*>(i->relobj());
bool has14 = ppcobj->has_14bit_branch(i->shndx());
if (!stub_control.can_add_to_stub_group(*o, &*i, has14))
{
stub_table->init(stub_control.owner(),
stub_control.output_section());
stub_table = NULL;
}
if (stub_table == NULL)
stub_table = this->new_stub_table();
ppcobj->set_stub_table(i->shndx(), stub_table);
}
}
}
if (stub_table != NULL)
stub_table->init(stub_control.owner(), stub_control.output_section());
}
// If this branch needs a plt call stub, or a long branch stub, make one.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::Branch_info::make_stub(
Stub_table<size, big_endian>* stub_table,
Stub_table<size, big_endian>* ifunc_stub_table,
Symbol_table* symtab) const
{
Symbol* sym = this->object_->global_symbol(this->r_sym_);
if (sym != NULL && sym->is_forwarder())
sym = symtab->resolve_forwards(sym);
const Sized_symbol<size>* gsym = static_cast<const Sized_symbol<size>*>(sym);
if (gsym != NULL
? use_plt_offset<size>(gsym, Scan::get_reference_flags(this->r_type_))
: this->object_->local_has_plt_offset(this->r_sym_))
{
if (stub_table == NULL)
stub_table = this->object_->stub_table(this->shndx_);
if (stub_table == NULL)
{
// This is a ref from a data section to an ifunc symbol.
stub_table = ifunc_stub_table;
}
gold_assert(stub_table != NULL);
if (gsym != NULL)
stub_table->add_plt_call_entry(this->object_, gsym,
this->r_type_, this->addend_);
else
stub_table->add_plt_call_entry(this->object_, this->r_sym_,
this->r_type_, this->addend_);
}
else
{
unsigned int max_branch_offset;
if (this->r_type_ == elfcpp::R_POWERPC_REL14
|| this->r_type_ == elfcpp::R_POWERPC_REL14_BRTAKEN
|| this->r_type_ == elfcpp::R_POWERPC_REL14_BRNTAKEN)
max_branch_offset = 1 << 15;
else if (this->r_type_ == elfcpp::R_POWERPC_REL24
|| this->r_type_ == elfcpp::R_PPC_PLTREL24
|| this->r_type_ == elfcpp::R_PPC_LOCAL24PC)
max_branch_offset = 1 << 25;
else
return;
Address from = this->object_->get_output_section_offset(this->shndx_);
gold_assert(from != invalid_address);
from += (this->object_->output_section(this->shndx_)->address()
+ this->offset_);
Address to;
if (gsym != NULL)
{
switch (gsym->source())
{
case Symbol::FROM_OBJECT:
{
Object* symobj = gsym->object();
if (symobj->is_dynamic()
|| symobj->pluginobj() != NULL)
return;
bool is_ordinary;
unsigned int shndx = gsym->shndx(&is_ordinary);
if (shndx == elfcpp::SHN_UNDEF)
return;
}
break;
case Symbol::IS_UNDEFINED:
return;
default:
break;
}
Symbol_table::Compute_final_value_status status;
to = symtab->compute_final_value<size>(gsym, &status);
if (status != Symbol_table::CFVS_OK)
return;
}
else
{
const Symbol_value<size>* psymval
= this->object_->local_symbol(this->r_sym_);
Symbol_value<size> symval;
typedef Sized_relobj_file<size, big_endian> ObjType;
typename ObjType::Compute_final_local_value_status status
= this->object_->compute_final_local_value(this->r_sym_, psymval,
&symval, symtab);
if (status != ObjType::CFLV_OK
|| !symval.has_output_value())
return;
to = symval.value(this->object_, 0);
}
if (stub_table == NULL)
stub_table = this->object_->stub_table(this->shndx_);
gold_assert(stub_table != NULL);
if (size == 64 && is_branch_reloc(this->r_type_))
{
unsigned int dest_shndx;
to = stub_table->targ()->symval_for_branch(to, gsym, this->object_,
&dest_shndx);
}
Address delta = to - from;
if (delta + max_branch_offset >= 2 * max_branch_offset)
{
stub_table->add_long_branch_entry(this->object_, to);
}
}
}
// Relaxation hook. This is where we do stub generation.
template<int size, bool big_endian>
bool
Target_powerpc<size, big_endian>::do_relax(int pass,
const Input_objects*,
Symbol_table* symtab,
Layout* layout,
const Task* task)
{
unsigned int prev_brlt_size = 0;
if (pass == 1)
{
bool thread_safe = parameters->options().plt_thread_safe();
if (size == 64 && !parameters->options().user_set_plt_thread_safe())
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
{
const char* const thread_starter[] =
{
"pthread_create",
/* libstdc++ */
"_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE",
/* librt */
"aio_init", "aio_read", "aio_write", "aio_fsync", "lio_listio",
"mq_notify", "create_timer",
/* libanl */
"getaddrinfo_a",
/* libgomp */
"GOMP_parallel_start",
"GOMP_parallel_loop_static_start",
"GOMP_parallel_loop_dynamic_start",
"GOMP_parallel_loop_guided_start",
"GOMP_parallel_loop_runtime_start",
"GOMP_parallel_sections_start",
};
for (unsigned int i = 0;
i < sizeof(thread_starter) / sizeof(thread_starter[0]);
i++)
{
Symbol* sym = symtab->lookup(thread_starter[i], NULL);
thread_safe = sym != NULL && sym->in_reg() && sym->in_real_elf();
if (thread_safe)
break;
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
}
this->plt_thread_safe_ = thread_safe;
this->group_sections(layout, task);
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
}
// We need address of stub tables valid for make_stub.
for (typename Stub_tables::iterator p = this->stub_tables_.begin();
p != this->stub_tables_.end();
++p)
{
const Powerpc_relobj<size, big_endian>* object
= static_cast<const Powerpc_relobj<size, big_endian>*>((*p)->relobj());
Address off = object->get_output_section_offset((*p)->shndx());
gold_assert(off != invalid_address);
Output_section* os = (*p)->output_section();
(*p)->set_address_and_size(os, off);
}
if (pass != 1)
{
// Clear plt call stubs, long branch stubs and branch lookup table.
prev_brlt_size = this->branch_lookup_table_.size();
this->branch_lookup_table_.clear();
for (typename Stub_tables::iterator p = this->stub_tables_.begin();
p != this->stub_tables_.end();
++p)
{
(*p)->clear_stubs();
}
}
// Build all the stubs.
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Stub_table<size, big_endian>* ifunc_stub_table
= this->stub_tables_.size() == 0 ? NULL : this->stub_tables_[0];
Stub_table<size, big_endian>* one_stub_table
= this->stub_tables_.size() != 1 ? NULL : ifunc_stub_table;
for (typename Branches::const_iterator b = this->branch_info_.begin();
b != this->branch_info_.end();
b++)
{
b->make_stub(one_stub_table, ifunc_stub_table, symtab);
}
// Did anything change size?
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
unsigned int num_huge_branches = this->branch_lookup_table_.size();
bool again = num_huge_branches != prev_brlt_size;
if (size == 64 && num_huge_branches != 0)
this->make_brlt_section(layout);
if (size == 64 && again)
this->brlt_section_->set_current_size(num_huge_branches);
typedef Unordered_set<Output_section*> Output_sections;
Output_sections os_need_update;
for (typename Stub_tables::iterator p = this->stub_tables_.begin();
p != this->stub_tables_.end();
++p)
{
if ((*p)->size_update())
{
again = true;
os_need_update.insert((*p)->output_section());
}
}
// Set output section offsets for all input sections in an output
// section that just changed size. Anything past the stubs will
// need updating.
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
for (typename Output_sections::iterator p = os_need_update.begin();
p != os_need_update.end();
p++)
{
Output_section* os = *p;
Address off = 0;
typedef Output_section::Input_section_list Input_section_list;
for (Input_section_list::const_iterator i = os->input_sections().begin();
i != os->input_sections().end();
++i)
{
off = align_address(off, i->addralign());
if (i->is_input_section() || i->is_relaxed_input_section())
i->relobj()->set_section_offset(i->shndx(), off);
if (i->is_relaxed_input_section())
{
Stub_table<size, big_endian>* stub_table
= static_cast<Stub_table<size, big_endian>*>(
i->relaxed_input_section());
off += stub_table->set_address_and_size(os, off);
}
else
off += i->data_size();
}
// If .brlt is part of this output section, then we have just
// done the offset adjustment.
os->clear_section_offsets_need_adjustment();
}
if (size == 64
&& !again
&& num_huge_branches != 0
&& parameters->options().output_is_position_independent())
{
// Fill in the BRLT relocs.
this->brlt_section_->reset_data_size();
for (typename Branch_lookup_table::const_iterator p
= this->branch_lookup_table_.begin();
p != this->branch_lookup_table_.end();
++p)
{
this->brlt_section_->add_reloc(p->first, p->second);
}
this->brlt_section_->finalize_data_size();
}
return again;
}
// A class to handle the PLT data.
template<int size, bool big_endian>
class Output_data_plt_powerpc : public Output_section_data_build
{
public:
typedef Output_data_reloc<elfcpp::SHT_RELA, true,
size, big_endian> Reloc_section;
Output_data_plt_powerpc(Target_powerpc<size, big_endian>* targ,
Reloc_section* plt_rel,
unsigned int reserved_size,
const char* name)
: Output_section_data_build(size == 32 ? 4 : 8),
rel_(plt_rel),
targ_(targ),
initial_plt_entry_size_(reserved_size),
name_(name)
{ }
// Add an entry to the PLT.
void
add_entry(Symbol*);
void
add_ifunc_entry(Symbol*);
void
add_local_ifunc_entry(Sized_relobj_file<size, big_endian>*, unsigned int);
// Return the .rela.plt section data.
Reloc_section*
rel_plt() const
{
return this->rel_;
}
elfcpp/ChangeLog: * 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.
2010-08-13 00:15:00 +02:00
// Return the number of PLT entries.
unsigned int
entry_count() const
{
return ((this->current_data_size() - this->initial_plt_entry_size_)
/ plt_entry_size);
}
elfcpp/ChangeLog: * 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.
2010-08-13 00:15:00 +02:00
// Return the offset of the first non-reserved PLT entry.
unsigned int
elfcpp/ChangeLog: * 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.
2010-08-13 00:15:00 +02:00
first_plt_entry_offset()
{ return this->initial_plt_entry_size_; }
elfcpp/ChangeLog: * 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.
2010-08-13 00:15:00 +02:00
// Return the size of a PLT entry.
static unsigned int
get_plt_entry_size()
{ return plt_entry_size; }
elfcpp/ChangeLog: * 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.
2010-08-13 00:15:00 +02:00
protected:
void
do_adjust_output_section(Output_section* os)
{
os->set_entsize(0);
}
// Write to a map file.
void
do_print_to_mapfile(Mapfile* mapfile) const
{ mapfile->print_output_data(this, this->name_); }
private:
// The size of an entry in the PLT.
static const int plt_entry_size = size == 32 ? 4 : 24;
// Write out the PLT data.
void
do_write(Output_file*);
// The reloc section.
Reloc_section* rel_;
// Allows access to .glink for do_write.
Target_powerpc<size, big_endian>* targ_;
// The size of the first reserved entry.
int initial_plt_entry_size_;
// What to report in map file.
const char *name_;
};
// Add an entry to the PLT.
template<int size, bool big_endian>
void
Output_data_plt_powerpc<size, big_endian>::add_entry(Symbol* gsym)
{
if (!gsym->has_plt_offset())
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
section_size_type off = this->current_data_size();
if (off == 0)
off += this->first_plt_entry_offset();
gsym->set_plt_offset(off);
gsym->set_needs_dynsym_entry();
unsigned int dynrel = elfcpp::R_POWERPC_JMP_SLOT;
this->rel_->add_global(gsym, dynrel, this, off, 0);
off += plt_entry_size;
this->set_current_data_size(off);
}
}
// Add an entry for a global ifunc symbol that resolves locally, to the IPLT.
template<int size, bool big_endian>
void
Output_data_plt_powerpc<size, big_endian>::add_ifunc_entry(Symbol* gsym)
{
if (!gsym->has_plt_offset())
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
section_size_type off = this->current_data_size();
gsym->set_plt_offset(off);
unsigned int dynrel = elfcpp::R_POWERPC_IRELATIVE;
if (size == 64)
dynrel = elfcpp::R_PPC64_JMP_IREL;
this->rel_->add_symbolless_global_addend(gsym, dynrel, this, off, 0);
off += plt_entry_size;
this->set_current_data_size(off);
}
}
// Add an entry for a local ifunc symbol to the IPLT.
template<int size, bool big_endian>
void
Output_data_plt_powerpc<size, big_endian>::add_local_ifunc_entry(
Sized_relobj_file<size, big_endian>* relobj,
unsigned int local_sym_index)
{
if (!relobj->local_has_plt_offset(local_sym_index))
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
section_size_type off = this->current_data_size();
relobj->set_local_plt_offset(local_sym_index, off);
unsigned int dynrel = elfcpp::R_POWERPC_IRELATIVE;
if (size == 64)
dynrel = elfcpp::R_PPC64_JMP_IREL;
this->rel_->add_symbolless_local_addend(relobj, local_sym_index, dynrel,
this, off, 0);
off += plt_entry_size;
this->set_current_data_size(off);
}
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
static const uint32_t add_0_11_11 = 0x7c0b5a14;
static const uint32_t add_2_2_11 = 0x7c425a14;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
static const uint32_t add_3_3_2 = 0x7c631214;
static const uint32_t add_3_3_13 = 0x7c636a14;
static const uint32_t add_11_0_11 = 0x7d605a14;
static const uint32_t add_12_2_11 = 0x7d825a14;
static const uint32_t add_12_12_11 = 0x7d8c5a14;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
static const uint32_t addi_11_11 = 0x396b0000;
static const uint32_t addi_12_12 = 0x398c0000;
static const uint32_t addi_2_2 = 0x38420000;
static const uint32_t addi_3_2 = 0x38620000;
static const uint32_t addi_3_3 = 0x38630000;
static const uint32_t addis_0_2 = 0x3c020000;
static const uint32_t addis_0_13 = 0x3c0d0000;
static const uint32_t addis_11_11 = 0x3d6b0000;
static const uint32_t addis_11_30 = 0x3d7e0000;
static const uint32_t addis_12_12 = 0x3d8c0000;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
static const uint32_t addis_12_2 = 0x3d820000;
static const uint32_t addis_3_2 = 0x3c620000;
static const uint32_t addis_3_13 = 0x3c6d0000;
static const uint32_t b = 0x48000000;
static const uint32_t bcl_20_31 = 0x429f0005;
static const uint32_t bctr = 0x4e800420;
static const uint32_t blr = 0x4e800020;
static const uint32_t blrl = 0x4e800021;
static const uint32_t bnectr_p4 = 0x4ce20420;
static const uint32_t cmpldi_2_0 = 0x28220000;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
static const uint32_t cror_15_15_15 = 0x4def7b82;
static const uint32_t cror_31_31_31 = 0x4ffffb82;
static const uint32_t ld_0_1 = 0xe8010000;
static const uint32_t ld_0_12 = 0xe80c0000;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
static const uint32_t ld_11_12 = 0xe96c0000;
static const uint32_t ld_11_2 = 0xe9620000;
static const uint32_t ld_2_1 = 0xe8410000;
static const uint32_t ld_2_11 = 0xe84b0000;
static const uint32_t ld_2_12 = 0xe84c0000;
static const uint32_t ld_2_2 = 0xe8420000;
static const uint32_t lfd_0_1 = 0xc8010000;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
static const uint32_t li_0_0 = 0x38000000;
static const uint32_t li_12_0 = 0x39800000;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
static const uint32_t lis_0_0 = 0x3c000000;
static const uint32_t lis_11 = 0x3d600000;
static const uint32_t lis_12 = 0x3d800000;
static const uint32_t lwz_0_12 = 0x800c0000;
static const uint32_t lwz_11_11 = 0x816b0000;
static const uint32_t lwz_11_30 = 0x817e0000;
static const uint32_t lwz_12_12 = 0x818c0000;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
static const uint32_t lwzu_0_12 = 0x840c0000;
static const uint32_t lvx_0_12_0 = 0x7c0c00ce;
static const uint32_t mflr_0 = 0x7c0802a6;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
static const uint32_t mflr_11 = 0x7d6802a6;
static const uint32_t mflr_12 = 0x7d8802a6;
static const uint32_t mtctr_0 = 0x7c0903a6;
static const uint32_t mtctr_11 = 0x7d6903a6;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
static const uint32_t mtctr_12 = 0x7d8903a6;
static const uint32_t mtlr_0 = 0x7c0803a6;
static const uint32_t mtlr_12 = 0x7d8803a6;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
static const uint32_t nop = 0x60000000;
static const uint32_t ori_0_0_0 = 0x60000000;
static const uint32_t std_0_1 = 0xf8010000;
static const uint32_t std_0_12 = 0xf80c0000;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
static const uint32_t std_2_1 = 0xf8410000;
static const uint32_t stfd_0_1 = 0xd8010000;
static const uint32_t stvx_0_12_0 = 0x7c0c01ce;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
static const uint32_t sub_11_11_12 = 0x7d6c5850;
static const uint32_t xor_11_11_11 = 0x7d6b5a78;
// Write out the PLT.
template<int size, bool big_endian>
void
Output_data_plt_powerpc<size, big_endian>::do_write(Output_file* of)
{
if (size == 32)
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
const section_size_type offset = this->offset();
const section_size_type oview_size
= convert_to_section_size_type(this->data_size());
unsigned char* const oview = of->get_output_view(offset, oview_size);
unsigned char* pov = oview;
unsigned char* endpov = oview + oview_size;
// The address of the .glink branch table
const Output_data_glink<size, big_endian>* glink
= this->targ_->glink_section();
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
elfcpp::Elf_types<32>::Elf_Addr branch_tab = glink->address();
while (pov < endpov)
{
elfcpp::Swap<32, big_endian>::writeval(pov, branch_tab);
pov += 4;
branch_tab += 4;
}
of->write_output_view(offset, oview_size, oview);
}
}
// Create the PLT section.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::make_plt_section(Symbol_table* symtab,
Layout* layout)
{
if (this->plt_ == NULL)
{
if (this->got_ == NULL)
this->got_section(symtab, layout);
if (this->glink_ == NULL)
make_glink_section(layout);
// Ensure that .rela.dyn always appears before .rela.plt This is
// necessary due to how, on PowerPC and some other targets, .rela.dyn
// needs to include .rela.plt in it's range.
this->rela_dyn_section(layout);
Reloc_section* plt_rel = new Reloc_section(false);
layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
elfcpp::SHF_ALLOC, plt_rel,
ORDER_DYNAMIC_PLT_RELOCS, false);
this->plt_
= new Output_data_plt_powerpc<size, big_endian>(this, plt_rel,
size == 32 ? 0 : 24,
"** PLT");
layout->add_output_section_data(".plt",
(size == 32
? elfcpp::SHT_PROGBITS
: elfcpp::SHT_NOBITS),
elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
this->plt_,
(size == 32
? ORDER_SMALL_DATA
: ORDER_SMALL_BSS),
false);
}
}
// Create the IPLT section.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::make_iplt_section(Symbol_table* symtab,
Layout* layout)
{
if (this->iplt_ == NULL)
{
this->make_plt_section(symtab, layout);
Reloc_section* iplt_rel = new Reloc_section(false);
this->rela_dyn_->output_section()->add_output_section_data(iplt_rel);
this->iplt_
= new Output_data_plt_powerpc<size, big_endian>(this, iplt_rel,
0, "** IPLT");
this->plt_->output_section()->add_output_section_data(this->iplt_);
}
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// A section for huge long branch addresses, similar to plt section.
template<int size, bool big_endian>
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
class Output_data_brlt_powerpc : public Output_section_data_build
{
public:
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
typedef Output_data_reloc<elfcpp::SHT_RELA, true,
size, big_endian> Reloc_section;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Output_data_brlt_powerpc(Target_powerpc<size, big_endian>* targ,
Reloc_section* brlt_rel)
: Output_section_data_build(size == 32 ? 4 : 8),
rel_(brlt_rel),
targ_(targ)
{ }
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// Add a reloc for an entry in the BRLT.
void
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
add_reloc(Address to, unsigned int off)
{ this->rel_->add_relative(elfcpp::R_POWERPC_RELATIVE, this, off, to); }
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// Update section and reloc section size.
void
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
set_current_size(unsigned int num_branches)
{
this->reset_address_and_file_offset();
this->set_current_data_size(num_branches * 16);
this->finalize_data_size();
Output_section* os = this->output_section();
os->set_section_offsets_need_adjustment();
if (this->rel_ != NULL)
{
unsigned int reloc_size
= Reloc_types<elfcpp::SHT_RELA, size, big_endian>::reloc_size;
this->rel_->reset_address_and_file_offset();
this->rel_->set_current_data_size(num_branches * reloc_size);
this->rel_->finalize_data_size();
Output_section* os = this->rel_->output_section();
os->set_section_offsets_need_adjustment();
}
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
protected:
void
do_adjust_output_section(Output_section* os)
{
os->set_entsize(0);
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// Write to a map file.
void
do_print_to_mapfile(Mapfile* mapfile) const
{ mapfile->print_output_data(this, "** BRLT"); }
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
private:
// Write out the BRLT data.
void
do_write(Output_file*);
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// The reloc section.
Reloc_section* rel_;
Target_powerpc<size, big_endian>* targ_;
};
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// Make the branch lookup table section.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::make_brlt_section(Layout* layout)
{
if (size == 64 && this->brlt_section_ == NULL)
{
Reloc_section* brlt_rel = NULL;
bool is_pic = parameters->options().output_is_position_independent();
if (is_pic)
{
// When PIC we can't fill in .brlt (like .plt it can be a
// bss style section) but must initialise at runtime via
// dynamic relocats.
this->rela_dyn_section(layout);
brlt_rel = new Reloc_section(false);
this->rela_dyn_->output_section()->add_output_section_data(brlt_rel);
}
this->brlt_section_
= new Output_data_brlt_powerpc<size, big_endian>(this, brlt_rel);
if (this->plt_ && is_pic)
this->plt_->output_section()
->add_output_section_data(this->brlt_section_);
else
layout->add_output_section_data(".brlt",
(is_pic ? elfcpp::SHT_NOBITS
: elfcpp::SHT_PROGBITS),
elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
this->brlt_section_,
(is_pic ? ORDER_SMALL_BSS
: ORDER_SMALL_DATA),
false);
}
}
// Write out .brlt when non-PIC.
template<int size, bool big_endian>
void
Output_data_brlt_powerpc<size, big_endian>::do_write(Output_file* of)
{
if (size == 64 && !parameters->options().output_is_position_independent())
{
const section_size_type offset = this->offset();
const section_size_type oview_size
= convert_to_section_size_type(this->data_size());
unsigned char* const oview = of->get_output_view(offset, oview_size);
this->targ_->write_branch_lookup_table(oview);
of->write_output_view(offset, oview_size, oview);
}
}
static inline uint32_t
l(uint32_t a)
{
return a & 0xffff;
}
static inline uint32_t
hi(uint32_t a)
{
return l(a >> 16);
}
static inline uint32_t
ha(uint32_t a)
{
return hi(a + 0x8000);
}
template<bool big_endian>
static inline void
write_insn(unsigned char* p, uint32_t v)
{
elfcpp::Swap<32, big_endian>::writeval(p, v);
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// Stub_table holds information about plt and long branch stubs.
// Stubs are built in an area following some input section determined
// by group_sections(). This input section is converted to a relaxed
// input section allowing it to be resized to accommodate the stubs
template<int size, bool big_endian>
class Stub_table : public Output_relaxed_input_section
{
public:
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
static const Address invalid_address = static_cast<Address>(0) - 1;
Stub_table(Target_powerpc<size, big_endian>* targ)
: Output_relaxed_input_section(NULL, 0, 0),
targ_(targ), plt_call_stubs_(), long_branch_stubs_(),
orig_data_size_(0), plt_size_(0), last_plt_size_(0),
branch_size_(0), last_branch_size_(0)
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
{ }
// Delayed Output_relaxed_input_section init.
void
init(const Output_section::Input_section*, Output_section*);
// Add a plt call stub.
void
add_plt_call_entry(const Sized_relobj_file<size, big_endian>*,
const Symbol*,
unsigned int,
Address);
void
add_plt_call_entry(const Sized_relobj_file<size, big_endian>*,
unsigned int,
unsigned int,
Address);
// Find a given plt call stub.
Address
find_plt_call_entry(const Symbol*) const;
Address
find_plt_call_entry(const Sized_relobj_file<size, big_endian>*,
unsigned int) const;
Address
find_plt_call_entry(const Sized_relobj_file<size, big_endian>*,
const Symbol*,
unsigned int,
Address) const;
Address
find_plt_call_entry(const Sized_relobj_file<size, big_endian>*,
unsigned int,
unsigned int,
Address) const;
// Add a long branch stub.
void
add_long_branch_entry(const Powerpc_relobj<size, big_endian>*, Address);
Address
find_long_branch_entry(const Powerpc_relobj<size, big_endian>*, Address);
void
clear_stubs()
{
this->plt_call_stubs_.clear();
this->plt_size_ = 0;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
this->long_branch_stubs_.clear();
this->branch_size_ = 0;
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Address
set_address_and_size(const Output_section* os, Address off)
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Address start_off = off;
off += this->orig_data_size_;
Address my_size = this->plt_size_ + this->branch_size_;
if (my_size != 0)
off = align_address(off, this->stub_align());
// Include original section size and alignment padding in size
my_size += off - start_off;
this->reset_address_and_file_offset();
this->set_current_data_size(my_size);
this->set_address_and_file_offset(os->address() + start_off,
os->offset() + start_off);
return my_size;
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Address
stub_address()
{
return align_address(this->address() + this->orig_data_size_,
this->stub_align());
}
Address
stub_offset()
{
return align_address(this->offset() + this->orig_data_size_,
this->stub_align());
}
section_size_type
plt_size() const
{ return this->plt_size_; }
bool
size_update()
{
Output_section* os = this->output_section();
if (os->addralign() < this->stub_align())
{
os->set_addralign(this->stub_align());
// FIXME: get rid of the insane checkpointing.
// We can't increase alignment of the input section to which
// stubs are attached; The input section may be .init which
// is pasted together with other .init sections to form a
// function. Aligning might insert zero padding resulting in
// sigill. However we do need to increase alignment of the
// output section so that the align_address() on offset in
// set_address_and_size() adds the same padding as the
// align_address() on address in stub_address().
// What's more, we need this alignment for the layout done in
// relaxation_loop_body() so that the output section starts at
// a suitably aligned address.
os->checkpoint_set_addralign(this->stub_align());
}
if (this->last_plt_size_ != this->plt_size_
|| this->last_branch_size_ != this->branch_size_)
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
{
this->last_plt_size_ = this->plt_size_;
this->last_branch_size_ = this->branch_size_;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
return true;
}
return false;
}
Target_powerpc<size, big_endian>*
targ() const
{ return targ_; }
private:
class Plt_stub_ent;
class Plt_stub_ent_hash;
typedef Unordered_map<Plt_stub_ent, unsigned int,
Plt_stub_ent_hash> Plt_stub_entries;
// Alignment of stub section.
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
unsigned int
stub_align() const
{
if (size == 32)
return 16;
unsigned int min_align = 32;
unsigned int user_align = 1 << parameters->options().plt_align();
return std::max(user_align, min_align);
}
// Size of a given plt call stub.
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
unsigned int
plt_call_size(typename Plt_stub_entries::const_iterator p) const
{
if (size == 32)
return 16;
Address pltaddr = p->second;
if (p->first.sym_ == NULL
|| (p->first.sym_->type() == elfcpp::STT_GNU_IFUNC
&& p->first.sym_->can_use_relative_reloc(false)))
pltaddr += this->targ_->iplt_section()->address();
else
pltaddr += this->targ_->plt_section()->address();
Address tocbase = this->targ_->got_section()->output_section()->address();
const Powerpc_relobj<size, big_endian>* ppcobj = static_cast
<const Powerpc_relobj<size, big_endian>*>(p->first.object_);
tocbase += ppcobj->toc_base_offset();
Address off = pltaddr - tocbase;
bool static_chain = parameters->options().plt_static_chain();
bool thread_safe = this->targ_->plt_thread_safe();
unsigned int bytes = (4 * 5
+ 4 * static_chain
+ 8 * thread_safe
+ 4 * (ha(off) != 0)
+ 4 * (ha(off + 8 + 8 * static_chain) != ha(off)));
unsigned int align = 1 << parameters->options().plt_align();
if (align > 1)
bytes = (bytes + align - 1) & -align;
return bytes;
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// Return long branch stub size.
unsigned int
branch_stub_size(Address to)
{
Address loc
= this->stub_address() + this->last_plt_size_ + this->branch_size_;
if (to - loc + (1 << 25) < 2 << 25)
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
return 4;
if (size == 64 || !parameters->options().output_is_position_independent())
return 16;
return 32;
}
// Write out stubs.
void
do_write(Output_file*);
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// Plt call stub keys.
class Plt_stub_ent
{
public:
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Plt_stub_ent(const Symbol* sym)
: sym_(sym), object_(0), addend_(0), locsym_(0)
{ }
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Plt_stub_ent(const Sized_relobj_file<size, big_endian>* object,
unsigned int locsym_index)
: sym_(NULL), object_(object), addend_(0), locsym_(locsym_index)
{ }
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Plt_stub_ent(const Sized_relobj_file<size, big_endian>* object,
const Symbol* sym,
unsigned int r_type,
Address addend)
: sym_(sym), object_(0), addend_(0), locsym_(0)
{
if (size != 32)
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
this->addend_ = addend;
else if (parameters->options().output_is_position_independent()
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
&& r_type == elfcpp::R_PPC_PLTREL24)
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
this->addend_ = addend;
if (this->addend_ >= 32768)
this->object_ = object;
}
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Plt_stub_ent(const Sized_relobj_file<size, big_endian>* object,
unsigned int locsym_index,
unsigned int r_type,
Address addend)
: sym_(NULL), object_(object), addend_(0), locsym_(locsym_index)
{
if (size != 32)
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
this->addend_ = addend;
else if (parameters->options().output_is_position_independent()
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
&& r_type == elfcpp::R_PPC_PLTREL24)
this->addend_ = addend;
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
bool operator==(const Plt_stub_ent& that) const
{
return (this->sym_ == that.sym_
&& this->object_ == that.object_
&& this->addend_ == that.addend_
&& this->locsym_ == that.locsym_);
}
const Symbol* sym_;
const Sized_relobj_file<size, big_endian>* object_;
typename elfcpp::Elf_types<size>::Elf_Addr addend_;
unsigned int locsym_;
};
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
class Plt_stub_ent_hash
{
public:
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
size_t operator()(const Plt_stub_ent& ent) const
{
return (reinterpret_cast<uintptr_t>(ent.sym_)
^ reinterpret_cast<uintptr_t>(ent.object_)
^ ent.addend_
^ ent.locsym_);
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
};
// Long branch stub keys.
class Branch_stub_ent
{
public:
Branch_stub_ent(const Powerpc_relobj<size, big_endian>* obj, Address to)
: dest_(to), toc_base_off_(0)
{
if (size == 64)
toc_base_off_ = obj->toc_base_offset();
}
bool operator==(const Branch_stub_ent& that) const
{
return (this->dest_ == that.dest_
&& (size == 32
|| this->toc_base_off_ == that.toc_base_off_));
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Address dest_;
unsigned int toc_base_off_;
};
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
class Branch_stub_ent_hash
{
public:
size_t operator()(const Branch_stub_ent& ent) const
{ return ent.dest_ ^ ent.toc_base_off_; }
};
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// In a sane world this would be a global.
Target_powerpc<size, big_endian>* targ_;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// Map sym/object/addend to stub offset.
Plt_stub_entries plt_call_stubs_;
// Map destination address to stub offset.
typedef Unordered_map<Branch_stub_ent, unsigned int,
Branch_stub_ent_hash> Branch_stub_entries;
Branch_stub_entries long_branch_stubs_;
// size of input section
section_size_type orig_data_size_;
// size of stubs
section_size_type plt_size_, last_plt_size_, branch_size_, last_branch_size_;
};
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// Make a new stub table, and record.
template<int size, bool big_endian>
Stub_table<size, big_endian>*
Target_powerpc<size, big_endian>::new_stub_table()
{
Stub_table<size, big_endian>* stub_table
= new Stub_table<size, big_endian>(this);
this->stub_tables_.push_back(stub_table);
return stub_table;
}
// Delayed stub table initialisation, because we create the stub table
// before we know to which section it will be attached.
template<int size, bool big_endian>
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
void
Stub_table<size, big_endian>::init(
const Output_section::Input_section* owner,
Output_section* output_section)
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
this->set_relobj(owner->relobj());
this->set_shndx(owner->shndx());
this->set_addralign(this->relobj()->section_addralign(this->shndx()));
this->set_output_section(output_section);
this->orig_data_size_ = owner->current_data_size();
std::vector<Output_relaxed_input_section*> new_relaxed;
new_relaxed.push_back(this);
output_section->convert_input_sections_to_relaxed_sections(new_relaxed);
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// Add a plt call stub, if we do not already have one for this
// sym/object/addend combo.
template<int size, bool big_endian>
void
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Stub_table<size, big_endian>::add_plt_call_entry(
const Sized_relobj_file<size, big_endian>* object,
const Symbol* gsym,
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
unsigned int r_type,
Address addend)
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Plt_stub_ent ent(object, gsym, r_type, addend);
Address off = this->plt_size_;
std::pair<typename Plt_stub_entries::iterator, bool> p
= this->plt_call_stubs_.insert(std::make_pair(ent, off));
if (p.second)
this->plt_size_ = off + this->plt_call_size(p.first);
}
template<int size, bool big_endian>
void
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Stub_table<size, big_endian>::add_plt_call_entry(
const Sized_relobj_file<size, big_endian>* object,
unsigned int locsym_index,
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
unsigned int r_type,
Address addend)
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Plt_stub_ent ent(object, locsym_index, r_type, addend);
Address off = this->plt_size_;
std::pair<typename Plt_stub_entries::iterator, bool> p
= this->plt_call_stubs_.insert(std::make_pair(ent, off));
if (p.second)
this->plt_size_ = off + this->plt_call_size(p.first);
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// Find a plt call stub.
template<int size, bool big_endian>
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
typename elfcpp::Elf_types<size>::Elf_Addr
Stub_table<size, big_endian>::find_plt_call_entry(
const Sized_relobj_file<size, big_endian>* object,
const Symbol* gsym,
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
unsigned int r_type,
Address addend) const
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Plt_stub_ent ent(object, gsym, r_type, addend);
typename Plt_stub_entries::const_iterator p = this->plt_call_stubs_.find(ent);
return p == this->plt_call_stubs_.end() ? invalid_address : p->second;
}
template<int size, bool big_endian>
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
typename elfcpp::Elf_types<size>::Elf_Addr
Stub_table<size, big_endian>::find_plt_call_entry(const Symbol* gsym) const
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Plt_stub_ent ent(gsym);
typename Plt_stub_entries::const_iterator p = this->plt_call_stubs_.find(ent);
return p == this->plt_call_stubs_.end() ? invalid_address : p->second;
}
template<int size, bool big_endian>
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
typename elfcpp::Elf_types<size>::Elf_Addr
Stub_table<size, big_endian>::find_plt_call_entry(
const Sized_relobj_file<size, big_endian>* object,
unsigned int locsym_index,
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
unsigned int r_type,
Address addend) const
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Plt_stub_ent ent(object, locsym_index, r_type, addend);
typename Plt_stub_entries::const_iterator p = this->plt_call_stubs_.find(ent);
return p == this->plt_call_stubs_.end() ? invalid_address : p->second;
}
template<int size, bool big_endian>
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
typename elfcpp::Elf_types<size>::Elf_Addr
Stub_table<size, big_endian>::find_plt_call_entry(
const Sized_relobj_file<size, big_endian>* object,
unsigned int locsym_index) const
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Plt_stub_ent ent(object, locsym_index);
typename Plt_stub_entries::const_iterator p = this->plt_call_stubs_.find(ent);
return p == this->plt_call_stubs_.end() ? invalid_address : p->second;
}
// Add a long branch stub if we don't already have one to given
// destination.
template<int size, bool big_endian>
void
Stub_table<size, big_endian>::add_long_branch_entry(
const Powerpc_relobj<size, big_endian>* object,
Address to)
{
Branch_stub_ent ent(object, to);
Address off = this->branch_size_;
if (this->long_branch_stubs_.insert(std::make_pair(ent, off)).second)
{
unsigned int stub_size = this->branch_stub_size(to);
this->branch_size_ = off + stub_size;
if (size == 64 && stub_size != 4)
this->targ_->add_branch_lookup_table(to);
}
}
// Find long branch stub.
template<int size, bool big_endian>
typename elfcpp::Elf_types<size>::Elf_Addr
Stub_table<size, big_endian>::find_long_branch_entry(
const Powerpc_relobj<size, big_endian>* object,
Address to)
{
Branch_stub_ent ent(object, to);
typename Branch_stub_entries::const_iterator p
= this->long_branch_stubs_.find(ent);
return p == this->long_branch_stubs_.end() ? invalid_address : p->second;
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// A class to handle .glink.
template<int size, bool big_endian>
class Output_data_glink : public Output_section_data
{
public:
static const int pltresolve_size = 16*4;
Output_data_glink(Target_powerpc<size, big_endian>* targ)
: Output_section_data(16), targ_(targ)
{ }
protected:
// Write to a map file.
void
do_print_to_mapfile(Mapfile* mapfile) const
{ mapfile->print_output_data(this, _("** glink")); }
private:
void
set_final_data_size();
// Write out .glink
void
do_write(Output_file*);
// Allows access to .got and .plt for do_write.
Target_powerpc<size, big_endian>* targ_;
};
template<int size, bool big_endian>
void
Output_data_glink<size, big_endian>::set_final_data_size()
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
unsigned int count = this->targ_->plt_entry_count();
section_size_type total = 0;
if (count != 0)
{
if (size == 32)
{
// space for branch table
total += 4 * (count - 1);
total += -total & 15;
total += this->pltresolve_size;
}
else
{
total += this->pltresolve_size;
// space for branch table
total += 8 * count;
if (count > 0x8000)
total += 4 * (count - 0x8000);
}
}
this->set_data_size(total);
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// Write out plt and long branch stub code.
template<int size, bool big_endian>
void
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Stub_table<size, big_endian>::do_write(Output_file* of)
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
if (this->plt_call_stubs_.empty()
&& this->long_branch_stubs_.empty())
return;
const section_size_type start_off = this->offset();
const section_size_type off = this->stub_offset();
const section_size_type oview_size =
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
convert_to_section_size_type(this->data_size() - (off - start_off));
unsigned char* const oview = of->get_output_view(off, oview_size);
unsigned char* p;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
static const Address invalid_address = static_cast<Address>(0) - 1;
if (size == 64)
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
const Output_data_got_powerpc<size, big_endian>* got
= this->targ_->got_section();
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Address got_os_addr = got->output_section()->address();
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
if (!this->plt_call_stubs_.empty())
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// The base address of the .plt section.
Address plt_base = this->targ_->plt_section()->address();
Address iplt_base = invalid_address;
// Write out plt call stubs.
typename Plt_stub_entries::const_iterator cs;
for (cs = this->plt_call_stubs_.begin();
cs != this->plt_call_stubs_.end();
++cs)
{
Address pltoff;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
bool is_ifunc;
const Symbol* gsym = cs->first.sym_;
if (gsym != NULL)
{
is_ifunc = (gsym->type() == elfcpp::STT_GNU_IFUNC
&& gsym->can_use_relative_reloc(false));
pltoff = gsym->plt_offset();
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
}
else
{
is_ifunc = true;
const Sized_relobj_file<size, big_endian>* relobj
= cs->first.object_;
unsigned int local_sym_index = cs->first.locsym_;
pltoff = relobj->local_plt_offset(local_sym_index);
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
}
Address plt_addr = pltoff;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
if (is_ifunc)
{
if (iplt_base == invalid_address)
iplt_base = this->targ_->iplt_section()->address();
plt_addr += iplt_base;
}
else
plt_addr += plt_base;
const Powerpc_relobj<size, big_endian>* ppcobj = static_cast
<const Powerpc_relobj<size, big_endian>*>(cs->first.object_);
Address got_addr = got_os_addr + ppcobj->toc_base_offset();
Address off = plt_addr - got_addr;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
gold_error(_("%s: linkage table error against `%s'"),
cs->first.object_->name().c_str(),
cs->first.sym_->demangled_name().c_str());
bool static_chain = parameters->options().plt_static_chain();
bool thread_safe = this->targ_->plt_thread_safe();
bool use_fake_dep = false;
Address cmp_branch_off = 0;
if (thread_safe)
{
unsigned int pltindex
= ((pltoff - this->targ_->first_plt_entry_offset())
/ this->targ_->plt_entry_size());
Address glinkoff
= (this->targ_->glink_section()->pltresolve_size
+ pltindex * 8);
if (pltindex > 32768)
glinkoff += (pltindex - 32768) * 4;
Address to
= this->targ_->glink_section()->address() + glinkoff;
Address from
= (this->stub_address() + cs->second + 24
+ 4 * (ha(off) != 0)
+ 4 * (ha(off + 8 + 8 * static_chain) != ha(off))
+ 4 * static_chain);
cmp_branch_off = to - from;
use_fake_dep = cmp_branch_off + (1 << 25) >= (1 << 26);
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
p = oview + cs->second;
if (ha(off) != 0)
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
{
write_insn<big_endian>(p, std_2_1 + 40), p += 4;
write_insn<big_endian>(p, addis_12_2 + ha(off)), p += 4;
write_insn<big_endian>(p, ld_11_12 + l(off)), p += 4;
if (ha(off + 8 + 8 * static_chain) != ha(off))
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
{
write_insn<big_endian>(p, addi_12_12 + l(off)), p += 4;
off = 0;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
}
write_insn<big_endian>(p, mtctr_11), p += 4;
if (use_fake_dep)
{
write_insn<big_endian>(p, xor_11_11_11), p += 4;
write_insn<big_endian>(p, add_12_12_11), p += 4;
}
write_insn<big_endian>(p, ld_2_12 + l(off + 8)), p += 4;
if (static_chain)
write_insn<big_endian>(p, ld_11_12 + l(off + 16)), p += 4;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
}
else
{
write_insn<big_endian>(p, std_2_1 + 40), p += 4;
write_insn<big_endian>(p, ld_11_2 + l(off)), p += 4;
if (ha(off + 8 + 8 * static_chain) != ha(off))
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
{
write_insn<big_endian>(p, addi_2_2 + l(off)), p += 4;
off = 0;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
}
write_insn<big_endian>(p, mtctr_11), p += 4;
if (use_fake_dep)
{
write_insn<big_endian>(p, xor_11_11_11), p += 4;
write_insn<big_endian>(p, add_2_2_11), p += 4;
}
if (static_chain)
write_insn<big_endian>(p, ld_11_2 + l(off + 16)), p += 4;
write_insn<big_endian>(p, ld_2_2 + l(off + 8)), p += 4;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
}
if (thread_safe && !use_fake_dep)
{
write_insn<big_endian>(p, cmpldi_2_0), p += 4;
write_insn<big_endian>(p, bnectr_p4), p += 4;
write_insn<big_endian>(p, b | (cmp_branch_off & 0x3fffffc));
}
else
write_insn<big_endian>(p, bctr);
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
}
// Write out long branch stubs.
typename Branch_stub_entries::const_iterator bs;
for (bs = this->long_branch_stubs_.begin();
bs != this->long_branch_stubs_.end();
++bs)
{
p = oview + this->plt_size_ + bs->second;
Address loc = this->stub_address() + this->plt_size_ + bs->second;
Address delta = bs->first.dest_ - loc;
if (delta + (1 << 25) < 2 << 25)
write_insn<big_endian>(p, b | (delta & 0x3fffffc));
else
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Address brlt_addr
= this->targ_->find_branch_lookup_table(bs->first.dest_);
gold_assert(brlt_addr != invalid_address);
brlt_addr += this->targ_->brlt_section()->address();
Address got_addr = got_os_addr + bs->first.toc_base_off_;
Address brltoff = brlt_addr - got_addr;
if (ha(brltoff) == 0)
{
write_insn<big_endian>(p, ld_11_2 + l(brltoff)), p += 4;
}
else
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
write_insn<big_endian>(p, addis_12_2 + ha(brltoff)), p += 4;
write_insn<big_endian>(p, ld_11_12 + l(brltoff)), p += 4;
}
write_insn<big_endian>(p, mtctr_11), p += 4;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
write_insn<big_endian>(p, bctr);
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
}
}
else
{
if (!this->plt_call_stubs_.empty())
{
// The base address of the .plt section.
Address plt_base = this->targ_->plt_section()->address();
Address iplt_base = invalid_address;
// The address of _GLOBAL_OFFSET_TABLE_.
Address g_o_t = invalid_address;
// Write out plt call stubs.
typename Plt_stub_entries::const_iterator cs;
for (cs = this->plt_call_stubs_.begin();
cs != this->plt_call_stubs_.end();
++cs)
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Address plt_addr;
bool is_ifunc;
const Symbol* gsym = cs->first.sym_;
if (gsym != NULL)
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
is_ifunc = (gsym->type() == elfcpp::STT_GNU_IFUNC
&& gsym->can_use_relative_reloc(false));
plt_addr = gsym->plt_offset();
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
else
{
is_ifunc = true;
const Sized_relobj_file<size, big_endian>* relobj
= cs->first.object_;
unsigned int local_sym_index = cs->first.locsym_;
plt_addr = relobj->local_plt_offset(local_sym_index);
}
if (is_ifunc)
{
if (iplt_base == invalid_address)
iplt_base = this->targ_->iplt_section()->address();
plt_addr += iplt_base;
}
else
plt_addr += plt_base;
p = oview + cs->second;
if (parameters->options().output_is_position_independent())
{
Address got_addr;
const Powerpc_relobj<size, big_endian>* ppcobj
= (static_cast<const Powerpc_relobj<size, big_endian>*>
(cs->first.object_));
if (ppcobj != NULL && cs->first.addend_ >= 32768)
{
unsigned int got2 = ppcobj->got2_shndx();
got_addr = ppcobj->get_output_section_offset(got2);
gold_assert(got_addr != invalid_address);
got_addr += (ppcobj->output_section(got2)->address()
+ cs->first.addend_);
}
else
{
if (g_o_t == invalid_address)
{
const Output_data_got_powerpc<size, big_endian>* got
= this->targ_->got_section();
g_o_t = got->address() + got->g_o_t();
}
got_addr = g_o_t;
}
Address off = plt_addr - got_addr;
if (ha(off) == 0)
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
{
write_insn<big_endian>(p + 0, lwz_11_30 + l(off));
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
write_insn<big_endian>(p + 4, mtctr_11);
write_insn<big_endian>(p + 8, bctr);
}
else
{
write_insn<big_endian>(p + 0, addis_11_30 + ha(off));
write_insn<big_endian>(p + 4, lwz_11_11 + l(off));
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
write_insn<big_endian>(p + 8, mtctr_11);
write_insn<big_endian>(p + 12, bctr);
}
}
else
{
write_insn<big_endian>(p + 0, lis_11 + ha(plt_addr));
write_insn<big_endian>(p + 4, lwz_11_11 + l(plt_addr));
write_insn<big_endian>(p + 8, mtctr_11);
write_insn<big_endian>(p + 12, bctr);
}
}
}
// Write out long branch stubs.
typename Branch_stub_entries::const_iterator bs;
for (bs = this->long_branch_stubs_.begin();
bs != this->long_branch_stubs_.end();
++bs)
{
p = oview + this->plt_size_ + bs->second;
Address loc = this->stub_address() + this->plt_size_ + bs->second;
Address delta = bs->first.dest_ - loc;
if (delta + (1 << 25) < 2 << 25)
write_insn<big_endian>(p, b | (delta & 0x3fffffc));
else if (!parameters->options().output_is_position_independent())
{
write_insn<big_endian>(p + 0, lis_12 + ha(bs->first.dest_));
write_insn<big_endian>(p + 4, addi_12_12 + l(bs->first.dest_));
write_insn<big_endian>(p + 8, mtctr_12);
write_insn<big_endian>(p + 12, bctr);
}
else
{
delta -= 8;
write_insn<big_endian>(p + 0, mflr_0);
write_insn<big_endian>(p + 4, bcl_20_31);
write_insn<big_endian>(p + 8, mflr_12);
write_insn<big_endian>(p + 12, addis_12_12 + ha(delta));
write_insn<big_endian>(p + 16, addi_12_12 + l(delta));
write_insn<big_endian>(p + 20, mtlr_0);
write_insn<big_endian>(p + 24, mtctr_12);
write_insn<big_endian>(p + 28, bctr);
}
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
}
}
// Write out .glink.
template<int size, bool big_endian>
void
Output_data_glink<size, big_endian>::do_write(Output_file* of)
{
const section_size_type off = this->offset();
const section_size_type oview_size =
convert_to_section_size_type(this->data_size());
unsigned char* const oview = of->get_output_view(off, oview_size);
unsigned char* p;
// The base address of the .plt section.
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
Address plt_base = this->targ_->plt_section()->address();
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
if (size == 64)
{
// Write pltresolve stub.
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
p = oview;
Address after_bcl = this->address() + 16;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Address pltoff = plt_base - after_bcl;
elfcpp::Swap<64, big_endian>::writeval(p, pltoff), p += 8;
write_insn<big_endian>(p, mflr_12), p += 4;
write_insn<big_endian>(p, bcl_20_31), p += 4;
write_insn<big_endian>(p, mflr_11), p += 4;
write_insn<big_endian>(p, ld_2_11 + l(-16)), p += 4;
write_insn<big_endian>(p, mtlr_12), p += 4;
write_insn<big_endian>(p, add_12_2_11), p += 4;
write_insn<big_endian>(p, ld_11_12 + 0), p += 4;
write_insn<big_endian>(p, ld_2_12 + 8), p += 4;
write_insn<big_endian>(p, mtctr_11), p += 4;
write_insn<big_endian>(p, ld_11_12 + 16), p += 4;
write_insn<big_endian>(p, bctr), p += 4;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
while (p < oview + this->pltresolve_size)
write_insn<big_endian>(p, nop), p += 4;
// Write lazy link call stubs.
uint32_t indx = 0;
while (p < oview + oview_size)
{
if (indx < 0x8000)
{
write_insn<big_endian>(p, li_0_0 + indx), p += 4;
}
else
{
write_insn<big_endian>(p, lis_0_0 + hi(indx)), p += 4;
write_insn<big_endian>(p, ori_0_0_0 + l(indx)), p += 4;
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
uint32_t branch_off = 8 - (p - oview);
write_insn<big_endian>(p, b + (branch_off & 0x3fffffc)), p += 4;
indx++;
}
}
else
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
const Output_data_got_powerpc<size, big_endian>* got
= this->targ_->got_section();
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// The address of _GLOBAL_OFFSET_TABLE_.
Address g_o_t = got->address() + got->g_o_t();
// Write out pltresolve branch table.
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
p = oview;
unsigned int the_end = oview_size - this->pltresolve_size;
unsigned char* end_p = oview + the_end;
while (p < end_p - 8 * 4)
write_insn<big_endian>(p, b + end_p - p), p += 4;
while (p < end_p)
write_insn<big_endian>(p, nop), p += 4;
// Write out pltresolve call stub.
if (parameters->options().output_is_position_independent())
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Address res0_off = 0;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Address after_bcl_off = the_end + 12;
Address bcl_res0 = after_bcl_off - res0_off;
write_insn<big_endian>(p + 0, addis_11_11 + ha(bcl_res0));
write_insn<big_endian>(p + 4, mflr_0);
write_insn<big_endian>(p + 8, bcl_20_31);
write_insn<big_endian>(p + 12, addi_11_11 + l(bcl_res0));
write_insn<big_endian>(p + 16, mflr_12);
write_insn<big_endian>(p + 20, mtlr_0);
write_insn<big_endian>(p + 24, sub_11_11_12);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Address got_bcl = g_o_t + 4 - (after_bcl_off + this->address());
write_insn<big_endian>(p + 28, addis_12_12 + ha(got_bcl));
if (ha(got_bcl) == ha(got_bcl + 4))
{
write_insn<big_endian>(p + 32, lwz_0_12 + l(got_bcl));
write_insn<big_endian>(p + 36, lwz_12_12 + l(got_bcl + 4));
}
else
{
write_insn<big_endian>(p + 32, lwzu_0_12 + l(got_bcl));
write_insn<big_endian>(p + 36, lwz_12_12 + 4);
}
write_insn<big_endian>(p + 40, mtctr_0);
write_insn<big_endian>(p + 44, add_0_11_11);
write_insn<big_endian>(p + 48, add_11_0_11);
write_insn<big_endian>(p + 52, bctr);
write_insn<big_endian>(p + 56, nop);
write_insn<big_endian>(p + 60, nop);
}
else
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Address res0 = this->address();
write_insn<big_endian>(p + 0, lis_12 + ha(g_o_t + 4));
write_insn<big_endian>(p + 4, addis_11_11 + ha(-res0));
if (ha(g_o_t + 4) == ha(g_o_t + 8))
write_insn<big_endian>(p + 8, lwz_0_12 + l(g_o_t + 4));
else
write_insn<big_endian>(p + 8, lwzu_0_12 + l(g_o_t + 4));
write_insn<big_endian>(p + 12, addi_11_11 + l(-res0));
write_insn<big_endian>(p + 16, mtctr_0);
write_insn<big_endian>(p + 20, add_0_11_11);
if (ha(g_o_t + 4) == ha(g_o_t + 8))
write_insn<big_endian>(p + 24, lwz_12_12 + l(g_o_t + 8));
else
write_insn<big_endian>(p + 24, lwz_12_12 + 4);
write_insn<big_endian>(p + 28, add_11_0_11);
write_insn<big_endian>(p + 32, bctr);
write_insn<big_endian>(p + 36, nop);
write_insn<big_endian>(p + 40, nop);
write_insn<big_endian>(p + 44, nop);
write_insn<big_endian>(p + 48, nop);
write_insn<big_endian>(p + 52, nop);
write_insn<big_endian>(p + 56, nop);
write_insn<big_endian>(p + 60, nop);
}
p += 64;
}
of->write_output_view(off, oview_size, oview);
}
// A class to handle linker generated save/restore functions.
template<int size, bool big_endian>
class Output_data_save_res : public Output_section_data_build
{
public:
Output_data_save_res(Symbol_table* symtab);
protected:
// Write to a map file.
void
do_print_to_mapfile(Mapfile* mapfile) const
{ mapfile->print_output_data(this, _("** save/restore")); }
void
do_write(Output_file*);
private:
// The maximum size of save/restore contents.
static const unsigned int savres_max = 218*4;
void
savres_define(Symbol_table* symtab,
const char *name,
unsigned int lo, unsigned int hi,
unsigned char* write_ent(unsigned char*, int),
unsigned char* write_tail(unsigned char*, int));
unsigned char *contents_;
};
template<bool big_endian>
static unsigned char*
savegpr0(unsigned char* p, int r)
{
uint32_t insn = std_0_1 + (r << 21) + (1 << 16) - (32 - r) * 8;
write_insn<big_endian>(p, insn);
return p + 4;
}
template<bool big_endian>
static unsigned char*
savegpr0_tail(unsigned char* p, int r)
{
p = savegpr0<big_endian>(p, r);
uint32_t insn = std_0_1 + 16;
write_insn<big_endian>(p, insn);
p = p + 4;
write_insn<big_endian>(p, blr);
return p + 4;
}
template<bool big_endian>
static unsigned char*
restgpr0(unsigned char* p, int r)
{
uint32_t insn = ld_0_1 + (r << 21) + (1 << 16) - (32 - r) * 8;
write_insn<big_endian>(p, insn);
return p + 4;
}
template<bool big_endian>
static unsigned char*
restgpr0_tail(unsigned char* p, int r)
{
uint32_t insn = ld_0_1 + 16;
write_insn<big_endian>(p, insn);
p = p + 4;
p = restgpr0<big_endian>(p, r);
write_insn<big_endian>(p, mtlr_0);
p = p + 4;
if (r == 29)
{
p = restgpr0<big_endian>(p, 30);
p = restgpr0<big_endian>(p, 31);
}
write_insn<big_endian>(p, blr);
return p + 4;
}
template<bool big_endian>
static unsigned char*
savegpr1(unsigned char* p, int r)
{
uint32_t insn = std_0_12 + (r << 21) + (1 << 16) - (32 - r) * 8;
write_insn<big_endian>(p, insn);
return p + 4;
}
template<bool big_endian>
static unsigned char*
savegpr1_tail(unsigned char* p, int r)
{
p = savegpr1<big_endian>(p, r);
write_insn<big_endian>(p, blr);
return p + 4;
}
template<bool big_endian>
static unsigned char*
restgpr1(unsigned char* p, int r)
{
uint32_t insn = ld_0_12 + (r << 21) + (1 << 16) - (32 - r) * 8;
write_insn<big_endian>(p, insn);
return p + 4;
}
template<bool big_endian>
static unsigned char*
restgpr1_tail(unsigned char* p, int r)
{
p = restgpr1<big_endian>(p, r);
write_insn<big_endian>(p, blr);
return p + 4;
}
template<bool big_endian>
static unsigned char*
savefpr(unsigned char* p, int r)
{
uint32_t insn = stfd_0_1 + (r << 21) + (1 << 16) - (32 - r) * 8;
write_insn<big_endian>(p, insn);
return p + 4;
}
template<bool big_endian>
static unsigned char*
savefpr0_tail(unsigned char* p, int r)
{
p = savefpr<big_endian>(p, r);
write_insn<big_endian>(p, std_0_1 + 16);
p = p + 4;
write_insn<big_endian>(p, blr);
return p + 4;
}
template<bool big_endian>
static unsigned char*
restfpr(unsigned char* p, int r)
{
uint32_t insn = lfd_0_1 + (r << 21) + (1 << 16) - (32 - r) * 8;
write_insn<big_endian>(p, insn);
return p + 4;
}
template<bool big_endian>
static unsigned char*
restfpr0_tail(unsigned char* p, int r)
{
write_insn<big_endian>(p, ld_0_1 + 16);
p = p + 4;
p = restfpr<big_endian>(p, r);
write_insn<big_endian>(p, mtlr_0);
p = p + 4;
if (r == 29)
{
p = restfpr<big_endian>(p, 30);
p = restfpr<big_endian>(p, 31);
}
write_insn<big_endian>(p, blr);
return p + 4;
}
template<bool big_endian>
static unsigned char*
savefpr1_tail(unsigned char* p, int r)
{
p = savefpr<big_endian>(p, r);
write_insn<big_endian>(p, blr);
return p + 4;
}
template<bool big_endian>
static unsigned char*
restfpr1_tail(unsigned char* p, int r)
{
p = restfpr<big_endian>(p, r);
write_insn<big_endian>(p, blr);
return p + 4;
}
template<bool big_endian>
static unsigned char*
savevr(unsigned char* p, int r)
{
uint32_t insn = li_12_0 + (1 << 16) - (32 - r) * 16;
write_insn<big_endian>(p, insn);
p = p + 4;
insn = stvx_0_12_0 + (r << 21);
write_insn<big_endian>(p, insn);
return p + 4;
}
template<bool big_endian>
static unsigned char*
savevr_tail(unsigned char* p, int r)
{
p = savevr<big_endian>(p, r);
write_insn<big_endian>(p, blr);
return p + 4;
}
template<bool big_endian>
static unsigned char*
restvr(unsigned char* p, int r)
{
uint32_t insn = li_12_0 + (1 << 16) - (32 - r) * 16;
write_insn<big_endian>(p, insn);
p = p + 4;
insn = lvx_0_12_0 + (r << 21);
write_insn<big_endian>(p, insn);
return p + 4;
}
template<bool big_endian>
static unsigned char*
restvr_tail(unsigned char* p, int r)
{
p = restvr<big_endian>(p, r);
write_insn<big_endian>(p, blr);
return p + 4;
}
template<int size, bool big_endian>
Output_data_save_res<size, big_endian>::Output_data_save_res(
Symbol_table* symtab)
: Output_section_data_build(4),
contents_(NULL)
{
this->savres_define(symtab,
"_savegpr0_", 14, 31,
savegpr0<big_endian>, savegpr0_tail<big_endian>);
this->savres_define(symtab,
"_restgpr0_", 14, 29,
restgpr0<big_endian>, restgpr0_tail<big_endian>);
this->savres_define(symtab,
"_restgpr0_", 30, 31,
restgpr0<big_endian>, restgpr0_tail<big_endian>);
this->savres_define(symtab,
"_savegpr1_", 14, 31,
savegpr1<big_endian>, savegpr1_tail<big_endian>);
this->savres_define(symtab,
"_restgpr1_", 14, 31,
restgpr1<big_endian>, restgpr1_tail<big_endian>);
this->savres_define(symtab,
"_savefpr_", 14, 31,
savefpr<big_endian>, savefpr0_tail<big_endian>);
this->savres_define(symtab,
"_restfpr_", 14, 29,
restfpr<big_endian>, restfpr0_tail<big_endian>);
this->savres_define(symtab,
"_restfpr_", 30, 31,
restfpr<big_endian>, restfpr0_tail<big_endian>);
this->savres_define(symtab,
"._savef", 14, 31,
savefpr<big_endian>, savefpr1_tail<big_endian>);
this->savres_define(symtab,
"._restf", 14, 31,
restfpr<big_endian>, restfpr1_tail<big_endian>);
this->savres_define(symtab,
"_savevr_", 20, 31,
savevr<big_endian>, savevr_tail<big_endian>);
this->savres_define(symtab,
"_restvr_", 20, 31,
restvr<big_endian>, restvr_tail<big_endian>);
}
template<int size, bool big_endian>
void
Output_data_save_res<size, big_endian>::savres_define(
Symbol_table* symtab,
const char *name,
unsigned int lo, unsigned int hi,
unsigned char* write_ent(unsigned char*, int),
unsigned char* write_tail(unsigned char*, int))
{
size_t len = strlen(name);
bool writing = false;
char sym[16];
memcpy(sym, name, len);
sym[len + 2] = 0;
for (unsigned int i = lo; i <= hi; i++)
{
sym[len + 0] = i / 10 + '0';
sym[len + 1] = i % 10 + '0';
Symbol* gsym = symtab->lookup(sym);
bool refd = gsym != NULL && gsym->is_undefined();
writing = writing || refd;
if (writing)
{
if (this->contents_ == NULL)
this->contents_ = new unsigned char[this->savres_max];
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
section_size_type value = this->current_data_size();
unsigned char* p = this->contents_ + value;
if (i != hi)
p = write_ent(p, i);
else
p = write_tail(p, i);
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
section_size_type cur_size = p - this->contents_;
this->set_current_data_size(cur_size);
if (refd)
symtab->define_in_output_data(sym, NULL, Symbol_table::PREDEFINED,
this, value, cur_size - value,
elfcpp::STT_FUNC, elfcpp::STB_GLOBAL,
elfcpp::STV_HIDDEN, 0, false, false);
}
}
}
// Write out save/restore.
template<int size, bool big_endian>
void
Output_data_save_res<size, big_endian>::do_write(Output_file* of)
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
const section_size_type off = this->offset();
const section_size_type oview_size =
convert_to_section_size_type(this->data_size());
unsigned char* const oview = of->get_output_view(off, oview_size);
memcpy(oview, this->contents_, oview_size);
of->write_output_view(off, oview_size, oview);
}
// Create the glink section.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::make_glink_section(Layout* layout)
{
if (this->glink_ == NULL)
{
this->glink_ = new Output_data_glink<size, big_endian>(this);
layout->add_output_section_data(".text", elfcpp::SHT_PROGBITS,
elfcpp::SHF_ALLOC | elfcpp::SHF_EXECINSTR,
this->glink_, ORDER_TEXT, false);
}
}
// Create a PLT entry for a global symbol.
template<int size, bool big_endian>
void
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Target_powerpc<size, big_endian>::make_plt_entry(Symbol_table* symtab,
Layout* layout,
Symbol* gsym)
{
if (gsym->type() == elfcpp::STT_GNU_IFUNC
&& gsym->can_use_relative_reloc(false))
{
if (this->iplt_ == NULL)
this->make_iplt_section(symtab, layout);
this->iplt_->add_ifunc_entry(gsym);
}
else
{
if (this->plt_ == NULL)
this->make_plt_section(symtab, layout);
this->plt_->add_entry(gsym);
}
}
// Make a PLT entry for a local STT_GNU_IFUNC symbol.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::make_local_ifunc_plt_entry(
Symbol_table* symtab,
Layout* layout,
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Sized_relobj_file<size, big_endian>* relobj,
unsigned int r_sym)
{
if (this->iplt_ == NULL)
this->make_iplt_section(symtab, layout);
this->iplt_->add_local_ifunc_entry(relobj, r_sym);
}
elfcpp/ChangeLog: * 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.
2010-08-13 00:15:00 +02:00
// Return the number of entries in the PLT.
template<int size, bool big_endian>
unsigned int
Target_powerpc<size, big_endian>::plt_entry_count() const
{
if (this->plt_ == NULL)
return 0;
unsigned int count = this->plt_->entry_count();
if (this->iplt_ != NULL)
count += this->iplt_->entry_count();
return count;
elfcpp/ChangeLog: * 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.
2010-08-13 00:15:00 +02:00
}
// Return the offset of the first non-reserved PLT entry.
template<int size, bool big_endian>
unsigned int
Target_powerpc<size, big_endian>::first_plt_entry_offset() const
{
return this->plt_->first_plt_entry_offset();
elfcpp/ChangeLog: * 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.
2010-08-13 00:15:00 +02:00
}
// Return the size of each PLT entry.
template<int size, bool big_endian>
unsigned int
Target_powerpc<size, big_endian>::plt_entry_size() const
{
return Output_data_plt_powerpc<size, big_endian>::get_plt_entry_size();
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// Create a GOT entry for local dynamic __tls_get_addr calls.
template<int size, bool big_endian>
unsigned int
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Target_powerpc<size, big_endian>::tlsld_got_offset(
* incremental-dump.cc (dump_incremental_inputs): Print dynamic reloc 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.
2011-05-24 23:41:10 +02:00
Symbol_table* symtab,
Layout* layout,
Sized_relobj_file<size, big_endian>* object)
{
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
if (this->tlsld_got_offset_ == -1U)
{
gold_assert(symtab != NULL && layout != NULL && object != NULL);
Reloc_section* rela_dyn = this->rela_dyn_section(layout);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Output_data_got_powerpc<size, big_endian>* got
= this->got_section(symtab, layout);
unsigned int got_offset = got->add_constant_pair(0, 0);
rela_dyn->add_local(object, 0, elfcpp::R_POWERPC_DTPMOD, got,
got_offset, 0);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
this->tlsld_got_offset_ = got_offset;
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
return this->tlsld_got_offset_;
}
gold/ * 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.
2010-11-11 11:43:30 +01:00
// Get the Reference_flags for a particular relocation.
template<int size, bool big_endian>
int
Target_powerpc<size, big_endian>::Scan::get_reference_flags(unsigned int r_type)
gold/ * 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.
2010-11-11 11:43:30 +01:00
{
switch (r_type)
{
case elfcpp::R_POWERPC_NONE:
case elfcpp::R_POWERPC_GNU_VTINHERIT:
case elfcpp::R_POWERPC_GNU_VTENTRY:
case elfcpp::R_PPC64_TOC:
// No symbol reference.
return 0;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_PPC64_ADDR64:
case elfcpp::R_PPC64_UADDR64:
case elfcpp::R_POWERPC_ADDR32:
case elfcpp::R_POWERPC_UADDR32:
gold/ * 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.
2010-11-11 11:43:30 +01:00
case elfcpp::R_POWERPC_ADDR16:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_UADDR16:
gold/ * 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.
2010-11-11 11:43:30 +01:00
case elfcpp::R_POWERPC_ADDR16_LO:
case elfcpp::R_POWERPC_ADDR16_HI:
case elfcpp::R_POWERPC_ADDR16_HA:
return Symbol::ABSOLUTE_REF;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_ADDR24:
case elfcpp::R_POWERPC_ADDR14:
case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
return Symbol::FUNCTION_CALL | Symbol::ABSOLUTE_REF;
case elfcpp::R_PPC64_REL64:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_REL32:
gold/ * 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.
2010-11-11 11:43:30 +01:00
case elfcpp::R_PPC_LOCAL24PC:
case elfcpp::R_POWERPC_REL16:
case elfcpp::R_POWERPC_REL16_LO:
case elfcpp::R_POWERPC_REL16_HI:
case elfcpp::R_POWERPC_REL16_HA:
gold/ * 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.
2010-11-11 11:43:30 +01:00
return Symbol::RELATIVE_REF;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_REL24:
gold/ * 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.
2010-11-11 11:43:30 +01:00
case elfcpp::R_PPC_PLTREL24:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_REL14:
case elfcpp::R_POWERPC_REL14_BRTAKEN:
case elfcpp::R_POWERPC_REL14_BRNTAKEN:
gold/ * 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.
2010-11-11 11:43:30 +01:00
return Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;
case elfcpp::R_POWERPC_GOT16:
case elfcpp::R_POWERPC_GOT16_LO:
case elfcpp::R_POWERPC_GOT16_HI:
case elfcpp::R_POWERPC_GOT16_HA:
case elfcpp::R_PPC64_GOT16_DS:
case elfcpp::R_PPC64_GOT16_LO_DS:
gold/ * 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.
2010-11-11 11:43:30 +01:00
case elfcpp::R_PPC64_TOC16:
case elfcpp::R_PPC64_TOC16_LO:
case elfcpp::R_PPC64_TOC16_HI:
case elfcpp::R_PPC64_TOC16_HA:
case elfcpp::R_PPC64_TOC16_DS:
case elfcpp::R_PPC64_TOC16_LO_DS:
// Absolute in GOT.
return Symbol::ABSOLUTE_REF;
case elfcpp::R_POWERPC_GOT_TPREL16:
case elfcpp::R_POWERPC_TLS:
return Symbol::TLS_REF;
case elfcpp::R_POWERPC_COPY:
case elfcpp::R_POWERPC_GLOB_DAT:
case elfcpp::R_POWERPC_JMP_SLOT:
case elfcpp::R_POWERPC_RELATIVE:
case elfcpp::R_POWERPC_DTPMOD:
default:
// Not expected. We will give an error later.
return 0;
}
}
// Report an unsupported relocation against a local symbol.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::Scan::unsupported_reloc_local(
Sized_relobj_file<size, big_endian>* object,
unsigned int r_type)
{
gold_error(_("%s: unsupported reloc %u against local symbol"),
object->name().c_str(), r_type);
}
// We are about to emit a dynamic relocation of type R_TYPE. If the
// dynamic linker does not support it, issue an error.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::Scan::check_non_pic(Relobj* object,
unsigned int r_type)
{
gold_assert(r_type != elfcpp::R_POWERPC_NONE);
// These are the relocation types supported by glibc for both 32-bit
// and 64-bit powerpc.
switch (r_type)
{
case elfcpp::R_POWERPC_NONE:
case elfcpp::R_POWERPC_RELATIVE:
case elfcpp::R_POWERPC_GLOB_DAT:
case elfcpp::R_POWERPC_DTPMOD:
case elfcpp::R_POWERPC_DTPREL:
case elfcpp::R_POWERPC_TPREL:
case elfcpp::R_POWERPC_JMP_SLOT:
case elfcpp::R_POWERPC_COPY:
case elfcpp::R_POWERPC_IRELATIVE:
case elfcpp::R_POWERPC_ADDR32:
case elfcpp::R_POWERPC_UADDR32:
case elfcpp::R_POWERPC_ADDR24:
case elfcpp::R_POWERPC_ADDR16:
case elfcpp::R_POWERPC_UADDR16:
case elfcpp::R_POWERPC_ADDR16_LO:
case elfcpp::R_POWERPC_ADDR16_HI:
case elfcpp::R_POWERPC_ADDR16_HA:
case elfcpp::R_POWERPC_ADDR14:
case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
case elfcpp::R_POWERPC_REL32:
case elfcpp::R_POWERPC_REL24:
case elfcpp::R_POWERPC_TPREL16:
case elfcpp::R_POWERPC_TPREL16_LO:
case elfcpp::R_POWERPC_TPREL16_HI:
case elfcpp::R_POWERPC_TPREL16_HA:
return;
default:
break;
}
if (size == 64)
{
switch (r_type)
{
// These are the relocation types supported only on 64-bit.
case elfcpp::R_PPC64_ADDR64:
case elfcpp::R_PPC64_UADDR64:
case elfcpp::R_PPC64_JMP_IREL:
case elfcpp::R_PPC64_ADDR16_DS:
case elfcpp::R_PPC64_ADDR16_LO_DS:
case elfcpp::R_PPC64_ADDR16_HIGHER:
case elfcpp::R_PPC64_ADDR16_HIGHEST:
case elfcpp::R_PPC64_ADDR16_HIGHERA:
case elfcpp::R_PPC64_ADDR16_HIGHESTA:
case elfcpp::R_PPC64_REL64:
case elfcpp::R_POWERPC_ADDR30:
case elfcpp::R_PPC64_TPREL16_DS:
case elfcpp::R_PPC64_TPREL16_LO_DS:
case elfcpp::R_PPC64_TPREL16_HIGHER:
case elfcpp::R_PPC64_TPREL16_HIGHEST:
case elfcpp::R_PPC64_TPREL16_HIGHERA:
case elfcpp::R_PPC64_TPREL16_HIGHESTA:
return;
default:
break;
}
}
else
{
switch (r_type)
{
// These are the relocation types supported only on 32-bit.
// ??? glibc ld.so doesn't need to support these.
case elfcpp::R_POWERPC_DTPREL16:
case elfcpp::R_POWERPC_DTPREL16_LO:
case elfcpp::R_POWERPC_DTPREL16_HI:
case elfcpp::R_POWERPC_DTPREL16_HA:
return;
default:
break;
}
}
// This prevents us from issuing more than one error per reloc
// section. But we can still wind up issuing more than one
// error per object file.
if (this->issued_non_pic_error_)
return;
gold_assert(parameters->options().output_is_position_independent());
object->error(_("requires unsupported dynamic reloc; "
"recompile with -fPIC"));
this->issued_non_pic_error_ = true;
return;
}
// Return whether we need to make a PLT entry for a relocation of the
// given type against a STT_GNU_IFUNC symbol.
template<int size, bool big_endian>
bool
Target_powerpc<size, big_endian>::Scan::reloc_needs_plt_for_ifunc(
Sized_relobj_file<size, big_endian>* object,
unsigned int r_type)
{
// In non-pic code any reference will resolve to the plt call stub
// for the ifunc symbol.
if (size == 32 && !parameters->options().output_is_position_independent())
return true;
switch (r_type)
{
// Word size refs from data sections are OK.
case elfcpp::R_POWERPC_ADDR32:
case elfcpp::R_POWERPC_UADDR32:
if (size == 32)
return true;
break;
case elfcpp::R_PPC64_ADDR64:
case elfcpp::R_PPC64_UADDR64:
if (size == 64)
return true;
break;
// GOT refs are good.
case elfcpp::R_POWERPC_GOT16:
case elfcpp::R_POWERPC_GOT16_LO:
case elfcpp::R_POWERPC_GOT16_HI:
case elfcpp::R_POWERPC_GOT16_HA:
case elfcpp::R_PPC64_GOT16_DS:
case elfcpp::R_PPC64_GOT16_LO_DS:
return true;
// So are function calls.
case elfcpp::R_POWERPC_ADDR24:
case elfcpp::R_POWERPC_ADDR14:
case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
case elfcpp::R_POWERPC_REL24:
case elfcpp::R_PPC_PLTREL24:
case elfcpp::R_POWERPC_REL14:
case elfcpp::R_POWERPC_REL14_BRTAKEN:
case elfcpp::R_POWERPC_REL14_BRNTAKEN:
return true;
default:
break;
}
// Anything else is a problem.
// If we are building a static executable, the libc startup function
// responsible for applying indirect function relocations is going
// to complain about the reloc type.
// If we are building a dynamic executable, we will have a text
// relocation. The dynamic loader will set the text segment
// writable and non-executable to apply text relocations. So we'll
// segfault when trying to run the indirection function to resolve
// the reloc.
gold_error(_("%s: unsupported reloc %u for IFUNC symbol"),
object->name().c_str(), r_type);
return false;
}
// Scan a relocation for a local symbol.
template<int size, bool big_endian>
inline void
Target_powerpc<size, big_endian>::Scan::local(
Symbol_table* symtab,
Layout* layout,
Target_powerpc<size, big_endian>* target,
Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
Output_section* output_section,
const elfcpp::Rela<size, big_endian>& reloc,
unsigned int r_type,
const elfcpp::Sym<size, big_endian>& lsym,
bool is_discarded)
{
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Powerpc_relobj<size, big_endian>* ppc_object
= static_cast<Powerpc_relobj<size, big_endian>*>(object);
if (is_discarded)
{
if (size == 64
&& data_shndx == ppc_object->opd_shndx()
&& r_type == elfcpp::R_PPC64_ADDR64)
ppc_object->set_opd_discard(reloc.get_r_offset());
return;
}
// A local STT_GNU_IFUNC symbol may require a PLT entry.
bool is_ifunc = lsym.get_st_type() == elfcpp::STT_GNU_IFUNC;
if (is_ifunc && this->reloc_needs_plt_for_ifunc(object, r_type))
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
target->push_branch(ppc_object, data_shndx, reloc.get_r_offset(),
r_type, r_sym, reloc.get_r_addend());
target->make_local_ifunc_plt_entry(symtab, layout, object, r_sym);
}
switch (r_type)
{
case elfcpp::R_POWERPC_NONE:
case elfcpp::R_POWERPC_GNU_VTINHERIT:
case elfcpp::R_POWERPC_GNU_VTENTRY:
case elfcpp::R_PPC64_TOCSAVE:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_PPC_EMB_MRKREF:
case elfcpp::R_POWERPC_TLS:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
break;
case elfcpp::R_PPC64_TOC:
{
Output_data_got_powerpc<size, big_endian>* got
= target->got_section(symtab, layout);
if (parameters->options().output_is_position_independent())
{
Address off = reloc.get_r_offset();
if (size == 64
&& data_shndx == ppc_object->opd_shndx()
&& ppc_object->get_opd_discard(off - 8))
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
Powerpc_relobj<size, big_endian>* symobj = ppc_object;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
rela_dyn->add_output_section_relative(got->output_section(),
elfcpp::R_POWERPC_RELATIVE,
output_section,
object, data_shndx, off,
symobj->toc_base_offset());
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
}
break;
case elfcpp::R_PPC64_ADDR64:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_PPC64_UADDR64:
case elfcpp::R_POWERPC_ADDR32:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_UADDR32:
case elfcpp::R_POWERPC_ADDR24:
case elfcpp::R_POWERPC_ADDR16:
case elfcpp::R_POWERPC_ADDR16_LO:
case elfcpp::R_POWERPC_ADDR16_HI:
case elfcpp::R_POWERPC_ADDR16_HA:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_UADDR16:
case elfcpp::R_PPC64_ADDR16_HIGHER:
case elfcpp::R_PPC64_ADDR16_HIGHERA:
case elfcpp::R_PPC64_ADDR16_HIGHEST:
case elfcpp::R_PPC64_ADDR16_HIGHESTA:
case elfcpp::R_PPC64_ADDR16_DS:
case elfcpp::R_PPC64_ADDR16_LO_DS:
case elfcpp::R_POWERPC_ADDR14:
case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
// If building a shared library (or a position-independent
// executable), we need to create a dynamic relocation for
// this location.
if (parameters->options().output_is_position_independent()
|| (size == 64 && is_ifunc))
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
{
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
if ((size == 32 && r_type == elfcpp::R_POWERPC_ADDR32)
|| (size == 64 && r_type == elfcpp::R_PPC64_ADDR64))
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
{
unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
unsigned int dynrel = elfcpp::R_POWERPC_RELATIVE;
if (is_ifunc)
{
rela_dyn = target->iplt_section()->rel_plt();
dynrel = elfcpp::R_POWERPC_IRELATIVE;
}
rela_dyn->add_local_relative(object, r_sym, dynrel,
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
output_section, data_shndx,
reloc.get_r_offset(),
reloc.get_r_addend(), false);
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
}
else
{
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
check_non_pic(object, r_type);
unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
rela_dyn->add_local(object, r_sym, r_type, output_section,
data_shndx, reloc.get_r_offset(),
reloc.get_r_addend());
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
}
}
break;
case elfcpp::R_POWERPC_REL24:
case elfcpp::R_PPC_PLTREL24:
case elfcpp::R_PPC_LOCAL24PC:
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
target->push_branch(ppc_object, data_shndx, reloc.get_r_offset(),
r_type, elfcpp::elf_r_sym<size>(reloc.get_r_info()),
reloc.get_r_addend());
break;
case elfcpp::R_POWERPC_REL14:
case elfcpp::R_POWERPC_REL14_BRTAKEN:
case elfcpp::R_POWERPC_REL14_BRNTAKEN:
target->push_branch(ppc_object, data_shndx, reloc.get_r_offset(),
r_type, elfcpp::elf_r_sym<size>(reloc.get_r_info()),
reloc.get_r_addend());
break;
case elfcpp::R_PPC64_REL64:
case elfcpp::R_POWERPC_REL32:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_REL16:
case elfcpp::R_POWERPC_REL16_LO:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_REL16_HI:
case elfcpp::R_POWERPC_REL16_HA:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_SECTOFF:
case elfcpp::R_POWERPC_TPREL16:
case elfcpp::R_POWERPC_DTPREL16:
case elfcpp::R_POWERPC_SECTOFF_LO:
case elfcpp::R_POWERPC_TPREL16_LO:
case elfcpp::R_POWERPC_DTPREL16_LO:
case elfcpp::R_POWERPC_SECTOFF_HI:
case elfcpp::R_POWERPC_TPREL16_HI:
case elfcpp::R_POWERPC_DTPREL16_HI:
case elfcpp::R_POWERPC_SECTOFF_HA:
case elfcpp::R_POWERPC_TPREL16_HA:
case elfcpp::R_POWERPC_DTPREL16_HA:
case elfcpp::R_PPC64_DTPREL16_HIGHER:
case elfcpp::R_PPC64_TPREL16_HIGHER:
case elfcpp::R_PPC64_DTPREL16_HIGHERA:
case elfcpp::R_PPC64_TPREL16_HIGHERA:
case elfcpp::R_PPC64_DTPREL16_HIGHEST:
case elfcpp::R_PPC64_TPREL16_HIGHEST:
case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
case elfcpp::R_PPC64_TPREL16_HIGHESTA:
case elfcpp::R_PPC64_TPREL16_DS:
case elfcpp::R_PPC64_TPREL16_LO_DS:
case elfcpp::R_PPC64_DTPREL16_DS:
case elfcpp::R_PPC64_DTPREL16_LO_DS:
case elfcpp::R_PPC64_SECTOFF_DS:
case elfcpp::R_PPC64_SECTOFF_LO_DS:
case elfcpp::R_PPC64_TLSGD:
case elfcpp::R_PPC64_TLSLD:
break;
case elfcpp::R_POWERPC_GOT16:
case elfcpp::R_POWERPC_GOT16_LO:
case elfcpp::R_POWERPC_GOT16_HI:
case elfcpp::R_POWERPC_GOT16_HA:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_PPC64_GOT16_DS:
case elfcpp::R_PPC64_GOT16_LO_DS:
{
// The symbol requires a GOT entry.
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Output_data_got_powerpc<size, big_endian>* got
= target->got_section(symtab, layout);
unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
if (!parameters->options().output_is_position_independent())
{
if (size == 32 && is_ifunc)
got->add_local_plt(object, r_sym, GOT_TYPE_STANDARD);
else
got->add_local(object, r_sym, GOT_TYPE_STANDARD);
}
else if (!object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD))
{
// If we are generating a shared object or a pie, this
// symbol's GOT entry will be set by a dynamic relocation.
unsigned int off;
off = got->add_constant(0);
object->set_local_got_offset(r_sym, GOT_TYPE_STANDARD, off);
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
unsigned int dynrel = elfcpp::R_POWERPC_RELATIVE;
if (is_ifunc)
{
rela_dyn = target->iplt_section()->rel_plt();
dynrel = elfcpp::R_POWERPC_IRELATIVE;
}
rela_dyn->add_local_relative(object, r_sym, dynrel,
got, off, 0, false);
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
}
}
break;
case elfcpp::R_PPC64_TOC16:
case elfcpp::R_PPC64_TOC16_LO:
case elfcpp::R_PPC64_TOC16_HI:
case elfcpp::R_PPC64_TOC16_HA:
case elfcpp::R_PPC64_TOC16_DS:
case elfcpp::R_PPC64_TOC16_LO_DS:
// We need a GOT section.
target->got_section(symtab, layout);
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_GOT_TLSGD16:
case elfcpp::R_POWERPC_GOT_TLSGD16_LO:
case elfcpp::R_POWERPC_GOT_TLSGD16_HI:
case elfcpp::R_POWERPC_GOT_TLSGD16_HA:
{
const tls::Tls_optimization tls_type = target->optimize_tls_gd(true);
if (tls_type == tls::TLSOPT_NONE)
{
Output_data_got_powerpc<size, big_endian>* got
= target->got_section(symtab, layout);
unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
got->add_local_tls_pair(object, r_sym, GOT_TYPE_TLSGD,
rela_dyn, elfcpp::R_POWERPC_DTPMOD);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
else if (tls_type == tls::TLSOPT_TO_LE)
{
// no GOT relocs needed for Local Exec.
}
else
gold_unreachable();
}
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_GOT_TLSLD16:
case elfcpp::R_POWERPC_GOT_TLSLD16_LO:
case elfcpp::R_POWERPC_GOT_TLSLD16_HI:
case elfcpp::R_POWERPC_GOT_TLSLD16_HA:
{
const tls::Tls_optimization tls_type = target->optimize_tls_ld();
if (tls_type == tls::TLSOPT_NONE)
target->tlsld_got_offset(symtab, layout, object);
else if (tls_type == tls::TLSOPT_TO_LE)
{
// no GOT relocs needed for Local Exec.
if (parameters->options().emit_relocs())
{
Output_section* os = layout->tls_segment()->first_section();
gold_assert(os != NULL);
os->set_needs_symtab_index();
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
else
gold_unreachable();
}
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_GOT_DTPREL16:
case elfcpp::R_POWERPC_GOT_DTPREL16_LO:
case elfcpp::R_POWERPC_GOT_DTPREL16_HI:
case elfcpp::R_POWERPC_GOT_DTPREL16_HA:
{
Output_data_got_powerpc<size, big_endian>* got
= target->got_section(symtab, layout);
unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
got->add_local_tls(object, r_sym, GOT_TYPE_DTPREL);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_GOT_TPREL16:
case elfcpp::R_POWERPC_GOT_TPREL16_LO:
case elfcpp::R_POWERPC_GOT_TPREL16_HI:
case elfcpp::R_POWERPC_GOT_TPREL16_HA:
{
const tls::Tls_optimization tls_type = target->optimize_tls_ie(true);
if (tls_type == tls::TLSOPT_NONE)
{
unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
if (!object->local_has_got_offset(r_sym, GOT_TYPE_TPREL))
{
Output_data_got_powerpc<size, big_endian>* got
= target->got_section(symtab, layout);
unsigned int off = got->add_constant(0);
object->set_local_got_offset(r_sym, GOT_TYPE_TPREL, off);
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
rela_dyn->add_symbolless_local_addend(object, r_sym,
elfcpp::R_POWERPC_TPREL,
got, off, 0);
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
else if (tls_type == tls::TLSOPT_TO_LE)
{
// no GOT relocs needed for Local Exec.
}
else
gold_unreachable();
}
break;
default:
unsupported_reloc_local(object, r_type);
break;
}
}
// Report an unsupported relocation against a global symbol.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::Scan::unsupported_reloc_global(
Sized_relobj_file<size, big_endian>* object,
unsigned int r_type,
Symbol* gsym)
{
gold_error(_("%s: unsupported reloc %u against global symbol %s"),
object->name().c_str(), r_type, gsym->demangled_name().c_str());
}
// Scan a relocation for a global symbol.
template<int size, bool big_endian>
inline void
Target_powerpc<size, big_endian>::Scan::global(
Symbol_table* symtab,
Layout* layout,
Target_powerpc<size, big_endian>* target,
Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
Output_section* output_section,
const elfcpp::Rela<size, big_endian>& reloc,
unsigned int r_type,
Symbol* gsym)
{
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Powerpc_relobj<size, big_endian>* ppc_object
= static_cast<Powerpc_relobj<size, big_endian>*>(object);
// A STT_GNU_IFUNC symbol may require a PLT entry.
if (gsym->type() == elfcpp::STT_GNU_IFUNC
&& this->reloc_needs_plt_for_ifunc(object, r_type))
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
{
target->push_branch(ppc_object, data_shndx, reloc.get_r_offset(),
r_type, elfcpp::elf_r_sym<size>(reloc.get_r_info()),
reloc.get_r_addend());
target->make_plt_entry(symtab, layout, gsym);
}
switch (r_type)
{
case elfcpp::R_POWERPC_NONE:
case elfcpp::R_POWERPC_GNU_VTINHERIT:
case elfcpp::R_POWERPC_GNU_VTENTRY:
case elfcpp::R_PPC_LOCAL24PC:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_PPC_EMB_MRKREF:
case elfcpp::R_POWERPC_TLS:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
break;
case elfcpp::R_PPC64_TOC:
{
Output_data_got_powerpc<size, big_endian>* got
= target->got_section(symtab, layout);
if (parameters->options().output_is_position_independent())
{
Address off = reloc.get_r_offset();
if (size == 64
&& data_shndx == ppc_object->opd_shndx()
&& ppc_object->get_opd_discard(off - 8))
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
Powerpc_relobj<size, big_endian>* symobj = ppc_object;
if (data_shndx != ppc_object->opd_shndx())
symobj = static_cast
<Powerpc_relobj<size, big_endian>*>(gsym->object());
rela_dyn->add_output_section_relative(got->output_section(),
elfcpp::R_POWERPC_RELATIVE,
output_section,
object, data_shndx, off,
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
symobj->toc_base_offset());
}
}
break;
case elfcpp::R_PPC64_ADDR64:
if (size == 64
&& data_shndx == ppc_object->opd_shndx()
&& (gsym->is_defined_in_discarded_section()
|| gsym->object() != object))
{
ppc_object->set_opd_discard(reloc.get_r_offset());
break;
}
// Fall thru
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_PPC64_UADDR64:
case elfcpp::R_POWERPC_ADDR32:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_UADDR32:
case elfcpp::R_POWERPC_ADDR24:
case elfcpp::R_POWERPC_ADDR16:
case elfcpp::R_POWERPC_ADDR16_LO:
case elfcpp::R_POWERPC_ADDR16_HI:
case elfcpp::R_POWERPC_ADDR16_HA:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_UADDR16:
case elfcpp::R_PPC64_ADDR16_HIGHER:
case elfcpp::R_PPC64_ADDR16_HIGHERA:
case elfcpp::R_PPC64_ADDR16_HIGHEST:
case elfcpp::R_PPC64_ADDR16_HIGHESTA:
case elfcpp::R_PPC64_ADDR16_DS:
case elfcpp::R_PPC64_ADDR16_LO_DS:
case elfcpp::R_POWERPC_ADDR14:
case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
{
// Make a PLT entry if necessary.
if (gsym->needs_plt_entry())
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
target->push_branch(ppc_object, data_shndx, reloc.get_r_offset(),
r_type,
elfcpp::elf_r_sym<size>(reloc.get_r_info()),
reloc.get_r_addend());
target->make_plt_entry(symtab, layout, gsym);
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
// Since this is not a PC-relative relocation, we may be
// taking the address of a function. In that case we need to
// set the entry in the dynamic symbol table to the address of
// the PLT call stub.
if (size == 32
&& gsym->is_from_dynobj()
&& !parameters->options().output_is_position_independent())
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
gsym->set_needs_dynsym_value();
}
// Make a dynamic relocation if necessary.
if (needs_dynamic_reloc<size>(gsym, Scan::get_reference_flags(r_type))
|| (size == 64 && gsym->type() == elfcpp::STT_GNU_IFUNC))
{
if (gsym->may_need_copy_reloc())
{
target->copy_reloc(symtab, layout, object,
data_shndx, output_section, gsym, reloc);
}
else if ((size == 32
&& r_type == elfcpp::R_POWERPC_ADDR32
&& gsym->can_use_relative_reloc(false)
&& !(gsym->visibility() == elfcpp::STV_PROTECTED
&& parameters->options().shared()))
|| (size == 64
&& r_type == elfcpp::R_PPC64_ADDR64
&& (gsym->can_use_relative_reloc(false)
|| data_shndx == ppc_object->opd_shndx())))
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
{
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
unsigned int dynrel = elfcpp::R_POWERPC_RELATIVE;
if (gsym->type() == elfcpp::STT_GNU_IFUNC)
{
rela_dyn = target->iplt_section()->rel_plt();
dynrel = elfcpp::R_POWERPC_IRELATIVE;
}
rela_dyn->add_symbolless_global_addend(
gsym, dynrel, output_section, object, data_shndx,
reloc.get_r_offset(), reloc.get_r_addend());
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
}
else
{
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
check_non_pic(object, r_type);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
rela_dyn->add_global(gsym, r_type, output_section,
object, data_shndx,
reloc.get_r_offset(),
reloc.get_r_addend());
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
}
}
}
break;
case elfcpp::R_PPC_PLTREL24:
case elfcpp::R_POWERPC_REL24:
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
target->push_branch(ppc_object, data_shndx, reloc.get_r_offset(),
r_type, elfcpp::elf_r_sym<size>(reloc.get_r_info()),
reloc.get_r_addend());
if (gsym->needs_plt_entry()
|| (!gsym->final_value_is_known()
&& (gsym->is_undefined()
|| gsym->is_from_dynobj()
|| gsym->is_preemptible())))
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
target->make_plt_entry(symtab, layout, gsym);
// Fall thru
case elfcpp::R_PPC64_REL64:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_REL32:
// Make a dynamic relocation if necessary.
if (needs_dynamic_reloc<size>(gsym, Scan::get_reference_flags(r_type)))
{
if (gsym->may_need_copy_reloc())
{
target->copy_reloc(symtab, layout, object,
data_shndx, output_section, gsym,
reloc);
}
else
{
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
check_non_pic(object, r_type);
rela_dyn->add_global(gsym, r_type, output_section, object,
data_shndx, reloc.get_r_offset(),
reloc.get_r_addend());
}
}
break;
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
case elfcpp::R_POWERPC_REL14:
case elfcpp::R_POWERPC_REL14_BRTAKEN:
case elfcpp::R_POWERPC_REL14_BRNTAKEN:
target->push_branch(ppc_object, data_shndx, reloc.get_r_offset(),
r_type, elfcpp::elf_r_sym<size>(reloc.get_r_info()),
reloc.get_r_addend());
break;
case elfcpp::R_POWERPC_REL16:
case elfcpp::R_POWERPC_REL16_LO:
case elfcpp::R_POWERPC_REL16_HI:
case elfcpp::R_POWERPC_REL16_HA:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_SECTOFF:
case elfcpp::R_POWERPC_TPREL16:
case elfcpp::R_POWERPC_DTPREL16:
case elfcpp::R_POWERPC_SECTOFF_LO:
case elfcpp::R_POWERPC_TPREL16_LO:
case elfcpp::R_POWERPC_DTPREL16_LO:
case elfcpp::R_POWERPC_SECTOFF_HI:
case elfcpp::R_POWERPC_TPREL16_HI:
case elfcpp::R_POWERPC_DTPREL16_HI:
case elfcpp::R_POWERPC_SECTOFF_HA:
case elfcpp::R_POWERPC_TPREL16_HA:
case elfcpp::R_POWERPC_DTPREL16_HA:
case elfcpp::R_PPC64_DTPREL16_HIGHER:
case elfcpp::R_PPC64_TPREL16_HIGHER:
case elfcpp::R_PPC64_DTPREL16_HIGHERA:
case elfcpp::R_PPC64_TPREL16_HIGHERA:
case elfcpp::R_PPC64_DTPREL16_HIGHEST:
case elfcpp::R_PPC64_TPREL16_HIGHEST:
case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
case elfcpp::R_PPC64_TPREL16_HIGHESTA:
case elfcpp::R_PPC64_TPREL16_DS:
case elfcpp::R_PPC64_TPREL16_LO_DS:
case elfcpp::R_PPC64_DTPREL16_DS:
case elfcpp::R_PPC64_DTPREL16_LO_DS:
case elfcpp::R_PPC64_SECTOFF_DS:
case elfcpp::R_PPC64_SECTOFF_LO_DS:
case elfcpp::R_PPC64_TLSGD:
case elfcpp::R_PPC64_TLSLD:
break;
case elfcpp::R_POWERPC_GOT16:
case elfcpp::R_POWERPC_GOT16_LO:
case elfcpp::R_POWERPC_GOT16_HI:
case elfcpp::R_POWERPC_GOT16_HA:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_PPC64_GOT16_DS:
case elfcpp::R_PPC64_GOT16_LO_DS:
{
// The symbol requires a GOT entry.
Output_data_got_powerpc<size, big_endian>* got;
got = target->got_section(symtab, layout);
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
if (gsym->final_value_is_known())
{
if (size == 32 && gsym->type() == elfcpp::STT_GNU_IFUNC)
got->add_global_plt(gsym, GOT_TYPE_STANDARD);
else
got->add_global(gsym, GOT_TYPE_STANDARD);
}
else if (!gsym->has_got_offset(GOT_TYPE_STANDARD))
{
// If we are generating a shared object or a pie, this
// symbol's GOT entry will be set by a dynamic relocation.
unsigned int off = got->add_constant(0);
gsym->set_got_offset(GOT_TYPE_STANDARD, off);
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
if (gsym->can_use_relative_reloc(false)
&& !(size == 32
&& gsym->visibility() == elfcpp::STV_PROTECTED
&& parameters->options().shared()))
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
{
unsigned int dynrel = elfcpp::R_POWERPC_RELATIVE;
if (gsym->type() == elfcpp::STT_GNU_IFUNC)
{
rela_dyn = target->iplt_section()->rel_plt();
dynrel = elfcpp::R_POWERPC_IRELATIVE;
}
rela_dyn->add_global_relative(gsym, dynrel, got, off, 0, false);
}
else
{
unsigned int dynrel = elfcpp::R_POWERPC_GLOB_DAT;
rela_dyn->add_global(gsym, dynrel, got, off, 0);
}
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
}
}
break;
case elfcpp::R_PPC64_TOC16:
case elfcpp::R_PPC64_TOC16_LO:
case elfcpp::R_PPC64_TOC16_HI:
case elfcpp::R_PPC64_TOC16_HA:
case elfcpp::R_PPC64_TOC16_DS:
case elfcpp::R_PPC64_TOC16_LO_DS:
// We need a GOT section.
target->got_section(symtab, layout);
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_GOT_TLSGD16:
case elfcpp::R_POWERPC_GOT_TLSGD16_LO:
case elfcpp::R_POWERPC_GOT_TLSGD16_HI:
case elfcpp::R_POWERPC_GOT_TLSGD16_HA:
{
const bool final = gsym->final_value_is_known();
const tls::Tls_optimization tls_type = target->optimize_tls_gd(final);
if (tls_type == tls::TLSOPT_NONE)
{
Output_data_got_powerpc<size, big_endian>* got
= target->got_section(symtab, layout);
got->add_global_pair_with_rel(gsym, GOT_TYPE_TLSGD,
target->rela_dyn_section(layout),
elfcpp::R_POWERPC_DTPMOD,
elfcpp::R_POWERPC_DTPREL);
}
else if (tls_type == tls::TLSOPT_TO_IE)
{
if (!gsym->has_got_offset(GOT_TYPE_TPREL))
{
Output_data_got_powerpc<size, big_endian>* got
= target->got_section(symtab, layout);
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
if (gsym->is_undefined()
|| gsym->is_from_dynobj())
{
got->add_global_with_rel(gsym, GOT_TYPE_TPREL, rela_dyn,
elfcpp::R_POWERPC_TPREL);
}
else
{
unsigned int off = got->add_constant(0);
gsym->set_got_offset(GOT_TYPE_TPREL, off);
unsigned int dynrel = elfcpp::R_POWERPC_TPREL;
rela_dyn->add_symbolless_global_addend(gsym, dynrel,
got, off, 0);
}
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
else if (tls_type == tls::TLSOPT_TO_LE)
{
// no GOT relocs needed for Local Exec.
}
else
gold_unreachable();
}
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_GOT_TLSLD16:
case elfcpp::R_POWERPC_GOT_TLSLD16_LO:
case elfcpp::R_POWERPC_GOT_TLSLD16_HI:
case elfcpp::R_POWERPC_GOT_TLSLD16_HA:
{
const tls::Tls_optimization tls_type = target->optimize_tls_ld();
if (tls_type == tls::TLSOPT_NONE)
target->tlsld_got_offset(symtab, layout, object);
else if (tls_type == tls::TLSOPT_TO_LE)
{
// no GOT relocs needed for Local Exec.
if (parameters->options().emit_relocs())
{
Output_section* os = layout->tls_segment()->first_section();
gold_assert(os != NULL);
os->set_needs_symtab_index();
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
else
gold_unreachable();
}
break;
case elfcpp::R_POWERPC_GOT_DTPREL16:
case elfcpp::R_POWERPC_GOT_DTPREL16_LO:
case elfcpp::R_POWERPC_GOT_DTPREL16_HI:
case elfcpp::R_POWERPC_GOT_DTPREL16_HA:
{
Output_data_got_powerpc<size, big_endian>* got
= target->got_section(symtab, layout);
if (!gsym->final_value_is_known()
&& (gsym->is_from_dynobj()
|| gsym->is_undefined()
|| gsym->is_preemptible()))
got->add_global_with_rel(gsym, GOT_TYPE_DTPREL,
target->rela_dyn_section(layout),
elfcpp::R_POWERPC_DTPREL);
else
got->add_global_tls(gsym, GOT_TYPE_DTPREL);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
break;
case elfcpp::R_POWERPC_GOT_TPREL16:
case elfcpp::R_POWERPC_GOT_TPREL16_LO:
case elfcpp::R_POWERPC_GOT_TPREL16_HI:
case elfcpp::R_POWERPC_GOT_TPREL16_HA:
{
const bool final = gsym->final_value_is_known();
const tls::Tls_optimization tls_type = target->optimize_tls_ie(final);
if (tls_type == tls::TLSOPT_NONE)
{
if (!gsym->has_got_offset(GOT_TYPE_TPREL))
{
Output_data_got_powerpc<size, big_endian>* got
= target->got_section(symtab, layout);
Reloc_section* rela_dyn = target->rela_dyn_section(layout);
if (gsym->is_undefined()
|| gsym->is_from_dynobj())
{
got->add_global_with_rel(gsym, GOT_TYPE_TPREL, rela_dyn,
elfcpp::R_POWERPC_TPREL);
}
else
{
unsigned int off = got->add_constant(0);
gsym->set_got_offset(GOT_TYPE_TPREL, off);
unsigned int dynrel = elfcpp::R_POWERPC_TPREL;
rela_dyn->add_symbolless_global_addend(gsym, dynrel,
got, off, 0);
}
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
else if (tls_type == tls::TLSOPT_TO_LE)
{
// no GOT relocs needed for Local Exec.
}
else
gold_unreachable();
}
break;
default:
unsupported_reloc_global(object, r_type, gsym);
break;
}
}
2009-01-20 Sriraman Tallam <tmsriram@google.com> * Makefile.am (CCFILES): Add gc.cc. (HFILES): Add gc.h. * Makefile.in: Regenerate. * gold.cc (Gc_runner): New class. (queue_initial_tasks): Call garbage collection related tasks when corresponding options are invoked. (queue_middle_gc_tasks): New function. (queue_middle_tasks): Reorder tasks to allow relocs to be read and processed early before laying out sections during garbage collection. * gold.h (queue_middle_gc_tasks): New function. (is_prefix_of): Move from "layout.cc". * i386.cc (Target_i386::gc_process_relocs): New function. * layout.cc (is_prefix_of): Remove. Move to "gold.h" * main.cc (main): Create object of class "Garbage_collection". * object.cc (Relobj::copy_symbols_data): New function. (Relobj::is_section_name_included): New function. (Sized_relobj::do_layout): Allow this function to be called twice during garbage collection and defer layout of section during the first call. * object.h (Relobj::get_symbols_data): New function. (Relobj::is_section_name_included): New function. (Relobj::copy_symbols_data): New function. (Relobj::set_symbols_data): New function. (Relobj::get_relocs_data): New function. (Relobj::set_relocs_data): New function. (Relobj::is_output_section_offset_invalid): New pure virtual function. (Relobj::gc_process_relocs): New function. (Relobj::do_gc_process_relocs): New pure virtual function. (Relobj::sd_): New data member. (Sized_relobj::is_output_section_offset_invalid): New function. (Sized_relobj::do_gc_process_relocs): New function. * options.h (General_options::gc_sections): Modify to not be a no-op. (General_options::print_gc_sections): New option. * plugin.cc (Plugin_finish::run): Remove function call to Plugin_manager::layout_deferred_objects. Move it to "gold.cc". * powerpc.cc (Target_powerpc::gc_process_relocs): New function. * reloc.cc (Read_relocs::run): Add task to process relocs and determine unreferenced sections when doing garbage collection. (Gc_process_relocs): New class. (Sized_relobj::do_gc_process_relocs): New function. (Sized_relobj::do_scan_relocs): Don't try to scan the relocs for sections that are garbage collected. * reloc.h (Gc_process_relocs): New class. * sparc.cc (Target_sparc::gc_process_relocs): New function. * symtab.cc (Symbol::should_add_dynsym_entry): Do not add entries for symbols whose corresponding sections are garbage collected. (Symbol_table::Symbol_table): Add new parameter for the garbage collection object. (Symbol_table::gc_mark_undef_symbols): New function. (Symbol_table::gc_mark_symbol_for_shlib): New function. (Symbol_table::gc_mark_dyn_syms): New function. (Symbol_table::resolve): Do not treat symbols seen in dynamic objects as garbage. (Symbol_table::add_from_object): Likewise. (Symbol_table::add_from_relobj): When building shared objects, do not treat externally visible symbols as garbage. (Symbol_table::sized_finalize_symbol): Do not check dynamic symbol table information for static and relocatable links. * symtab.h (Symbol_table::set_gc): New function. (Symbol_table::gc): New function. (Symbol_table::gc_mark_undef_symbols): New function. (Symbol_table::gc_mark_symbol_for_shlib): New function. (Symbol_table::gc_mark_dyn_syms): New function. (Symbol_table::gc_): New data member. * target.h (Sized_target::gc_process_relocs): New pure virtual function. * x86_64.cc (Target_x86_64::gc_process_relocs): New function. * testsuite/testfile.cc (Target_test::gc_process_relocs): New function.
2009-01-28 03:25:33 +01:00
// Process relocations for gc.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::gc_process_relocs(
Symbol_table* symtab,
Layout* layout,
Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
unsigned int,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
bool needs_special_offset_handling,
size_t local_symbol_count,
const unsigned char* plocal_symbols)
2009-01-20 Sriraman Tallam <tmsriram@google.com> * Makefile.am (CCFILES): Add gc.cc. (HFILES): Add gc.h. * Makefile.in: Regenerate. * gold.cc (Gc_runner): New class. (queue_initial_tasks): Call garbage collection related tasks when corresponding options are invoked. (queue_middle_gc_tasks): New function. (queue_middle_tasks): Reorder tasks to allow relocs to be read and processed early before laying out sections during garbage collection. * gold.h (queue_middle_gc_tasks): New function. (is_prefix_of): Move from "layout.cc". * i386.cc (Target_i386::gc_process_relocs): New function. * layout.cc (is_prefix_of): Remove. Move to "gold.h" * main.cc (main): Create object of class "Garbage_collection". * object.cc (Relobj::copy_symbols_data): New function. (Relobj::is_section_name_included): New function. (Sized_relobj::do_layout): Allow this function to be called twice during garbage collection and defer layout of section during the first call. * object.h (Relobj::get_symbols_data): New function. (Relobj::is_section_name_included): New function. (Relobj::copy_symbols_data): New function. (Relobj::set_symbols_data): New function. (Relobj::get_relocs_data): New function. (Relobj::set_relocs_data): New function. (Relobj::is_output_section_offset_invalid): New pure virtual function. (Relobj::gc_process_relocs): New function. (Relobj::do_gc_process_relocs): New pure virtual function. (Relobj::sd_): New data member. (Sized_relobj::is_output_section_offset_invalid): New function. (Sized_relobj::do_gc_process_relocs): New function. * options.h (General_options::gc_sections): Modify to not be a no-op. (General_options::print_gc_sections): New option. * plugin.cc (Plugin_finish::run): Remove function call to Plugin_manager::layout_deferred_objects. Move it to "gold.cc". * powerpc.cc (Target_powerpc::gc_process_relocs): New function. * reloc.cc (Read_relocs::run): Add task to process relocs and determine unreferenced sections when doing garbage collection. (Gc_process_relocs): New class. (Sized_relobj::do_gc_process_relocs): New function. (Sized_relobj::do_scan_relocs): Don't try to scan the relocs for sections that are garbage collected. * reloc.h (Gc_process_relocs): New class. * sparc.cc (Target_sparc::gc_process_relocs): New function. * symtab.cc (Symbol::should_add_dynsym_entry): Do not add entries for symbols whose corresponding sections are garbage collected. (Symbol_table::Symbol_table): Add new parameter for the garbage collection object. (Symbol_table::gc_mark_undef_symbols): New function. (Symbol_table::gc_mark_symbol_for_shlib): New function. (Symbol_table::gc_mark_dyn_syms): New function. (Symbol_table::resolve): Do not treat symbols seen in dynamic objects as garbage. (Symbol_table::add_from_object): Likewise. (Symbol_table::add_from_relobj): When building shared objects, do not treat externally visible symbols as garbage. (Symbol_table::sized_finalize_symbol): Do not check dynamic symbol table information for static and relocatable links. * symtab.h (Symbol_table::set_gc): New function. (Symbol_table::gc): New function. (Symbol_table::gc_mark_undef_symbols): New function. (Symbol_table::gc_mark_symbol_for_shlib): New function. (Symbol_table::gc_mark_dyn_syms): New function. (Symbol_table::gc_): New data member. * target.h (Sized_target::gc_process_relocs): New pure virtual function. * x86_64.cc (Target_x86_64::gc_process_relocs): New function. * testsuite/testfile.cc (Target_test::gc_process_relocs): New function.
2009-01-28 03:25:33 +01:00
{
typedef Target_powerpc<size, big_endian> Powerpc;
typedef typename Target_powerpc<size, big_endian>::Scan Scan;
Powerpc_relobj<size, big_endian>* ppc_object
= static_cast<Powerpc_relobj<size, big_endian>*>(object);
if (size == 64)
ppc_object->set_opd_valid();
if (size == 64 && data_shndx == ppc_object->opd_shndx())
{
typename Powerpc_relobj<size, big_endian>::Access_from::iterator p;
for (p = ppc_object->access_from_map()->begin();
p != ppc_object->access_from_map()->end();
++p)
{
Address dst_off = p->first;
unsigned int dst_indx = ppc_object->get_opd_ent(dst_off);
typename Powerpc_relobj<size, big_endian>::Section_refs::iterator s;
for (s = p->second.begin(); s != p->second.end(); ++s)
{
Object* src_obj = s->first;
unsigned int src_indx = s->second;
symtab->gc()->add_reference(src_obj, src_indx,
ppc_object, dst_indx);
}
p->second.clear();
}
ppc_object->access_from_map()->clear();
ppc_object->process_gc_mark(symtab);
// Don't look at .opd relocs as .opd will reference everything.
return;
}
2009-01-20 Sriraman Tallam <tmsriram@google.com> * Makefile.am (CCFILES): Add gc.cc. (HFILES): Add gc.h. * Makefile.in: Regenerate. * gold.cc (Gc_runner): New class. (queue_initial_tasks): Call garbage collection related tasks when corresponding options are invoked. (queue_middle_gc_tasks): New function. (queue_middle_tasks): Reorder tasks to allow relocs to be read and processed early before laying out sections during garbage collection. * gold.h (queue_middle_gc_tasks): New function. (is_prefix_of): Move from "layout.cc". * i386.cc (Target_i386::gc_process_relocs): New function. * layout.cc (is_prefix_of): Remove. Move to "gold.h" * main.cc (main): Create object of class "Garbage_collection". * object.cc (Relobj::copy_symbols_data): New function. (Relobj::is_section_name_included): New function. (Sized_relobj::do_layout): Allow this function to be called twice during garbage collection and defer layout of section during the first call. * object.h (Relobj::get_symbols_data): New function. (Relobj::is_section_name_included): New function. (Relobj::copy_symbols_data): New function. (Relobj::set_symbols_data): New function. (Relobj::get_relocs_data): New function. (Relobj::set_relocs_data): New function. (Relobj::is_output_section_offset_invalid): New pure virtual function. (Relobj::gc_process_relocs): New function. (Relobj::do_gc_process_relocs): New pure virtual function. (Relobj::sd_): New data member. (Sized_relobj::is_output_section_offset_invalid): New function. (Sized_relobj::do_gc_process_relocs): New function. * options.h (General_options::gc_sections): Modify to not be a no-op. (General_options::print_gc_sections): New option. * plugin.cc (Plugin_finish::run): Remove function call to Plugin_manager::layout_deferred_objects. Move it to "gold.cc". * powerpc.cc (Target_powerpc::gc_process_relocs): New function. * reloc.cc (Read_relocs::run): Add task to process relocs and determine unreferenced sections when doing garbage collection. (Gc_process_relocs): New class. (Sized_relobj::do_gc_process_relocs): New function. (Sized_relobj::do_scan_relocs): Don't try to scan the relocs for sections that are garbage collected. * reloc.h (Gc_process_relocs): New class. * sparc.cc (Target_sparc::gc_process_relocs): New function. * symtab.cc (Symbol::should_add_dynsym_entry): Do not add entries for symbols whose corresponding sections are garbage collected. (Symbol_table::Symbol_table): Add new parameter for the garbage collection object. (Symbol_table::gc_mark_undef_symbols): New function. (Symbol_table::gc_mark_symbol_for_shlib): New function. (Symbol_table::gc_mark_dyn_syms): New function. (Symbol_table::resolve): Do not treat symbols seen in dynamic objects as garbage. (Symbol_table::add_from_object): Likewise. (Symbol_table::add_from_relobj): When building shared objects, do not treat externally visible symbols as garbage. (Symbol_table::sized_finalize_symbol): Do not check dynamic symbol table information for static and relocatable links. * symtab.h (Symbol_table::set_gc): New function. (Symbol_table::gc): New function. (Symbol_table::gc_mark_undef_symbols): New function. (Symbol_table::gc_mark_symbol_for_shlib): New function. (Symbol_table::gc_mark_dyn_syms): New function. (Symbol_table::gc_): New data member. * target.h (Sized_target::gc_process_relocs): New pure virtual function. * x86_64.cc (Target_x86_64::gc_process_relocs): New function. * testsuite/testfile.cc (Target_test::gc_process_relocs): New function.
2009-01-28 03:25:33 +01:00
gold::gc_process_relocs<size, big_endian, Powerpc, elfcpp::SHT_RELA, Scan,
typename Target_powerpc::Relocatable_size_for_reloc>(
2009-01-20 Sriraman Tallam <tmsriram@google.com> * Makefile.am (CCFILES): Add gc.cc. (HFILES): Add gc.h. * Makefile.in: Regenerate. * gold.cc (Gc_runner): New class. (queue_initial_tasks): Call garbage collection related tasks when corresponding options are invoked. (queue_middle_gc_tasks): New function. (queue_middle_tasks): Reorder tasks to allow relocs to be read and processed early before laying out sections during garbage collection. * gold.h (queue_middle_gc_tasks): New function. (is_prefix_of): Move from "layout.cc". * i386.cc (Target_i386::gc_process_relocs): New function. * layout.cc (is_prefix_of): Remove. Move to "gold.h" * main.cc (main): Create object of class "Garbage_collection". * object.cc (Relobj::copy_symbols_data): New function. (Relobj::is_section_name_included): New function. (Sized_relobj::do_layout): Allow this function to be called twice during garbage collection and defer layout of section during the first call. * object.h (Relobj::get_symbols_data): New function. (Relobj::is_section_name_included): New function. (Relobj::copy_symbols_data): New function. (Relobj::set_symbols_data): New function. (Relobj::get_relocs_data): New function. (Relobj::set_relocs_data): New function. (Relobj::is_output_section_offset_invalid): New pure virtual function. (Relobj::gc_process_relocs): New function. (Relobj::do_gc_process_relocs): New pure virtual function. (Relobj::sd_): New data member. (Sized_relobj::is_output_section_offset_invalid): New function. (Sized_relobj::do_gc_process_relocs): New function. * options.h (General_options::gc_sections): Modify to not be a no-op. (General_options::print_gc_sections): New option. * plugin.cc (Plugin_finish::run): Remove function call to Plugin_manager::layout_deferred_objects. Move it to "gold.cc". * powerpc.cc (Target_powerpc::gc_process_relocs): New function. * reloc.cc (Read_relocs::run): Add task to process relocs and determine unreferenced sections when doing garbage collection. (Gc_process_relocs): New class. (Sized_relobj::do_gc_process_relocs): New function. (Sized_relobj::do_scan_relocs): Don't try to scan the relocs for sections that are garbage collected. * reloc.h (Gc_process_relocs): New class. * sparc.cc (Target_sparc::gc_process_relocs): New function. * symtab.cc (Symbol::should_add_dynsym_entry): Do not add entries for symbols whose corresponding sections are garbage collected. (Symbol_table::Symbol_table): Add new parameter for the garbage collection object. (Symbol_table::gc_mark_undef_symbols): New function. (Symbol_table::gc_mark_symbol_for_shlib): New function. (Symbol_table::gc_mark_dyn_syms): New function. (Symbol_table::resolve): Do not treat symbols seen in dynamic objects as garbage. (Symbol_table::add_from_object): Likewise. (Symbol_table::add_from_relobj): When building shared objects, do not treat externally visible symbols as garbage. (Symbol_table::sized_finalize_symbol): Do not check dynamic symbol table information for static and relocatable links. * symtab.h (Symbol_table::set_gc): New function. (Symbol_table::gc): New function. (Symbol_table::gc_mark_undef_symbols): New function. (Symbol_table::gc_mark_symbol_for_shlib): New function. (Symbol_table::gc_mark_dyn_syms): New function. (Symbol_table::gc_): New data member. * target.h (Sized_target::gc_process_relocs): New pure virtual function. * x86_64.cc (Target_x86_64::gc_process_relocs): New function. * testsuite/testfile.cc (Target_test::gc_process_relocs): New function.
2009-01-28 03:25:33 +01:00
symtab,
layout,
this,
object,
data_shndx,
prelocs,
reloc_count,
output_section,
needs_special_offset_handling,
local_symbol_count,
plocal_symbols);
}
// Handle target specific gc actions when adding a gc reference from
// SRC_OBJ, SRC_SHNDX to a location specified by DST_OBJ, DST_SHNDX
// and DST_OFF. For powerpc64, this adds a referenc to the code
// section of a function descriptor.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::do_gc_add_reference(
Symbol_table* symtab,
Object* src_obj,
unsigned int src_shndx,
Object* dst_obj,
unsigned int dst_shndx,
Address dst_off) const
{
Powerpc_relobj<size, big_endian>* ppc_object
= static_cast<Powerpc_relobj<size, big_endian>*>(dst_obj);
if (size == 64
&& !ppc_object->is_dynamic()
&& dst_shndx == ppc_object->opd_shndx())
{
if (ppc_object->opd_valid())
{
dst_shndx = ppc_object->get_opd_ent(dst_off);
symtab->gc()->add_reference(src_obj, src_shndx, dst_obj, dst_shndx);
}
else
{
// If we haven't run scan_opd_relocs, we must delay
// processing this function descriptor reference.
ppc_object->add_reference(src_obj, src_shndx, dst_off);
}
}
}
// Add any special sections for this symbol to the gc work list.
// For powerpc64, this adds the code section of a function
// descriptor.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::do_gc_mark_symbol(
Symbol_table* symtab,
Symbol* sym) const
{
if (size == 64)
{
Powerpc_relobj<size, big_endian>* ppc_object
= static_cast<Powerpc_relobj<size, big_endian>*>(sym->object());
bool is_ordinary;
unsigned int shndx = sym->shndx(&is_ordinary);
if (is_ordinary && shndx == ppc_object->opd_shndx())
{
Sized_symbol<size>* gsym = symtab->get_sized_symbol<size>(sym);
Address dst_off = gsym->value();
if (ppc_object->opd_valid())
{
unsigned int dst_indx = ppc_object->get_opd_ent(dst_off);
symtab->gc()->worklist().push(Section_id(ppc_object, dst_indx));
}
else
ppc_object->add_gc_mark(dst_off);
}
}
}
// Scan relocations for a section.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::scan_relocs(
Symbol_table* symtab,
Layout* layout,
Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
bool needs_special_offset_handling,
size_t local_symbol_count,
const unsigned char* plocal_symbols)
{
typedef Target_powerpc<size, big_endian> Powerpc;
typedef typename Target_powerpc<size, big_endian>::Scan Scan;
if (sh_type == elfcpp::SHT_REL)
{
gold_error(_("%s: unsupported REL reloc section"),
object->name().c_str());
return;
}
gold::scan_relocs<size, big_endian, Powerpc, elfcpp::SHT_RELA, Scan>(
symtab,
layout,
this,
object,
data_shndx,
prelocs,
reloc_count,
output_section,
needs_special_offset_handling,
local_symbol_count,
plocal_symbols);
}
// Functor class for processing the global symbol table.
// Removes symbols defined on discarded opd entries.
template<bool big_endian>
class Global_symbol_visitor_opd
{
public:
Global_symbol_visitor_opd()
{ }
void
operator()(Sized_symbol<64>* sym)
{
if (sym->has_symtab_index()
|| sym->source() != Symbol::FROM_OBJECT
|| !sym->in_real_elf())
return;
Powerpc_relobj<64, big_endian>* symobj
= static_cast<Powerpc_relobj<64, big_endian>*>(sym->object());
if (symobj->is_dynamic()
|| symobj->opd_shndx() == 0)
return;
bool is_ordinary;
unsigned int shndx = sym->shndx(&is_ordinary);
if (shndx == symobj->opd_shndx()
&& symobj->get_opd_discard(sym->value()))
sym->set_symtab_index(-1U);
}
};
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::define_save_restore_funcs(
Layout* layout,
Symbol_table* symtab)
{
if (size == 64)
{
Output_data_save_res<64, big_endian>* savres
= new Output_data_save_res<64, big_endian>(symtab);
layout->add_output_section_data(".text", elfcpp::SHT_PROGBITS,
elfcpp::SHF_ALLOC | elfcpp::SHF_EXECINSTR,
savres, ORDER_TEXT, false);
}
}
// Finalize the sections.
template<int size, bool big_endian>
void
2009-10-30 Doug Kwan <dougkwan@google.com> elfcpp/ChangeLog: * arm.h (EF_ARM_BE8, EF_ARM_EABIMASK, EF_ARM_EABI_UNKNOWN, EF_ARM_EABI_VER1, EF_ARM_EABI_VER2, EF_ARM_EABI_VER3, EF_ARM_EABI_VER4, EF_ARM_EABI_VER5): New enums for processor-specific flags. (arm_eabi_version): New inline function. * elfcpp.h: Add a comment about DT_ENCODING. gold/ChangeLog: * arm.cc (Arm_relobj::processor_specific_flags): New method definition. (Arm_relobj::do_read_symbols): New method declaration. (Arm_relobj::processor_specific_flags_): New data member declaration. (Arm_dynobj): New class definition. (Target_arm::do_finalize_sections): Add input_objects parameter. (Target_arm::do_adjust_elf_header): New method declaration. (Target_arm::are_eabi_versions_compatible, (Target_arm::merge_processor_specific_flags): New method declaration. (Target_arm::do_make_elf_object): New overloaded method definitions and declaration. (Arm_relobj::do_read_symbols): New method definition. (Arm_dynobj::do_read_symbols): Ditto. (Target_arm::do_finalize_sections): Add input_objects parameters. Merge processor-specific flags from all input objects. (Target_arm::are_eabi_versions_compatible, Target_arm::merge_processor_specific_flags, Target_arm::do_adjust_elf_header, Target_arm::do_make_elf_object): New method definitions. * i386.cc (Target_i386::do_finalize_sections): Add unnamed Input_objects pointer type parameter. * layout.cc (Layout::finalize): Pass input objects to target's. finalize_sections function. * output.cc (Output_file_header::do_sized_write): Set ELF file header's processor-specific flags. * powerpc.cc (Target_powerpc::do_finalize_sections): Add unnamed Input_objects pointer type parameter. * sparc.cc (Target_sparc::do_finalize_sections): Same. * target.h (Input_objects): New forward class declaration. (Target::processor_specific_flags, Target::are_processor_specific_flags_sect): New method definitions. (Target::finalize_sections): Add input_objects parameter. (Target::Target): Initialize processor_specific_flags_ and are_processor_specific_flags_set_. (Target::do_finalize_sections): Add unnamed Input_objects pointer type parameter. (Target::set_processor_specific_flags): New method definition. (Target::processor_specific_flags_, Target::are_processor_specific_flags_set_): New data member declarations. * x86_64.cc (Target_x86_64::do_finalize_sections): Add unnamed Input_objects pointer type parameter.
2009-10-30 19:49:59 +01:00
Target_powerpc<size, big_endian>::do_finalize_sections(
Layout* layout,
const Input_objects*,
Symbol_table* symtab)
{
if (parameters->doing_static_link())
{
// At least some versions of glibc elf-init.o have a strong
// reference to __rela_iplt marker syms. A weak ref would be
// better..
if (this->iplt_ != NULL)
{
Reloc_section* rel = this->iplt_->rel_plt();
symtab->define_in_output_data("__rela_iplt_start", NULL,
Symbol_table::PREDEFINED, rel, 0, 0,
elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
elfcpp::STV_HIDDEN, 0, false, true);
symtab->define_in_output_data("__rela_iplt_end", NULL,
Symbol_table::PREDEFINED, rel, 0, 0,
elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
elfcpp::STV_HIDDEN, 0, true, true);
}
else
{
symtab->define_as_constant("__rela_iplt_start", NULL,
Symbol_table::PREDEFINED, 0, 0,
elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
elfcpp::STV_HIDDEN, 0, true, false);
symtab->define_as_constant("__rela_iplt_end", NULL,
Symbol_table::PREDEFINED, 0, 0,
elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
elfcpp::STV_HIDDEN, 0, true, false);
}
}
if (size == 64)
{
typedef Global_symbol_visitor_opd<big_endian> Symbol_visitor;
symtab->for_all_symbols<64, Symbol_visitor>(Symbol_visitor());
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
if (!parameters->options().relocatable())
{
this->define_save_restore_funcs(layout, symtab);
// Annoyingly, we need to make these sections now whether or
// not we need them. If we delay until do_relax then we
// need to mess with the relaxation machinery checkpointing.
this->got_section(symtab, layout);
this->make_brlt_section(layout);
}
}
// Fill in some more dynamic tags.
Output_data_dynamic* odyn = layout->dynamic_data();
if (odyn != NULL)
{
const Reloc_section* rel_plt = (this->plt_ == NULL
? NULL
: this->plt_->rel_plt());
layout->add_target_dynamic_tags(false, this->plt_, rel_plt,
this->rela_dyn_, true, size == 32);
if (size == 32)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{
if (this->got_ != NULL)
{
this->got_->finalize_data_size();
odyn->add_section_plus_offset(elfcpp::DT_PPC_GOT,
this->got_, this->got_->g_o_t());
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
else
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{
if (this->glink_ != NULL)
{
this->glink_->finalize_data_size();
odyn->add_section_plus_offset(elfcpp::DT_PPC64_GLINK,
this->glink_,
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
(this->glink_->pltresolve_size
- 32));
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
}
// Emit any relocs we saved in an attempt to avoid generating COPY
// relocs.
if (this->copy_relocs_.any_saved_relocs())
this->copy_relocs_.emit(this->rela_dyn_section(layout));
}
// Return the value to use for a branch relocation.
template<int size, bool big_endian>
typename elfcpp::Elf_types<size>::Elf_Addr
Target_powerpc<size, big_endian>::symval_for_branch(
Address value,
const Sized_symbol<size>* gsym,
Powerpc_relobj<size, big_endian>* object,
unsigned int *dest_shndx)
{
*dest_shndx = 0;
if (size == 32)
return value;
// If the symbol is defined in an opd section, ie. is a function
// descriptor, use the function descriptor code entry address
Powerpc_relobj<size, big_endian>* symobj = object;
if (gsym != NULL
&& gsym->source() != Symbol::FROM_OBJECT)
return value;
if (gsym != NULL)
symobj = static_cast<Powerpc_relobj<size, big_endian>*>(gsym->object());
unsigned int shndx = symobj->opd_shndx();
if (shndx == 0)
return value;
Address opd_addr = symobj->get_output_section_offset(shndx);
gold_assert(opd_addr != invalid_address);
opd_addr += symobj->output_section(shndx)->address();
if (value >= opd_addr && value < opd_addr + symobj->section_size(shndx))
{
Address sec_off;
*dest_shndx = symobj->get_opd_ent(value - opd_addr, &sec_off);
Address sec_addr = symobj->get_output_section_offset(*dest_shndx);
gold_assert(sec_addr != invalid_address);
sec_addr += symobj->output_section(*dest_shndx)->address();
value = sec_addr + sec_off;
}
return value;
}
// Perform a relocation.
template<int size, bool big_endian>
inline bool
Target_powerpc<size, big_endian>::Relocate::relocate(
const Relocate_info<size, big_endian>* relinfo,
Target_powerpc* target,
Output_section* os,
size_t relnum,
const elfcpp::Rela<size, big_endian>& rela,
unsigned int r_type,
const Sized_symbol<size>* gsym,
const Symbol_value<size>* psymval,
unsigned char* view,
Address address,
section_size_type view_size)
{
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
bool is_tls_call = ((r_type == elfcpp::R_POWERPC_REL24
|| r_type == elfcpp::R_PPC_PLTREL24)
&& gsym != NULL
&& strcmp(gsym->name(), "__tls_get_addr") == 0);
enum skip_tls last_tls = this->call_tls_get_addr_;
this->call_tls_get_addr_ = CALL_NOT_EXPECTED;
if (is_tls_call)
{
if (last_tls == CALL_NOT_EXPECTED)
gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
_("__tls_get_addr call lacks marker reloc"));
else if (last_tls == CALL_SKIP)
return false;
}
else if (last_tls != CALL_NOT_EXPECTED)
gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
_("missing expected __tls_get_addr call"));
typedef Powerpc_relocate_functions<size, big_endian> Reloc;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
typedef typename elfcpp::Swap<32, big_endian>::Valtype Insn;
Powerpc_relobj<size, big_endian>* const object
= static_cast<Powerpc_relobj<size, big_endian>*>(relinfo->object);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Address value = 0;
bool has_plt_value = false;
unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
if (gsym != NULL
? use_plt_offset<size>(gsym, Scan::get_reference_flags(r_type))
: object->local_has_plt_offset(r_sym))
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
Stub_table<size, big_endian>* stub_table
= object->stub_table(relinfo->data_shndx);
if (stub_table == NULL)
{
// This is a ref from a data section to an ifunc symbol.
if (target->stub_tables().size() != 0)
stub_table = target->stub_tables()[0];
}
gold_assert(stub_table != NULL);
Address off;
if (gsym != NULL)
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
off = stub_table->find_plt_call_entry(object, gsym, r_type,
rela.get_r_addend());
else
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
off = stub_table->find_plt_call_entry(object, r_sym, r_type,
rela.get_r_addend());
gold_assert(off != invalid_address);
value = stub_table->stub_address() + off;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
has_plt_value = true;
}
if (r_type == elfcpp::R_POWERPC_GOT16
|| r_type == elfcpp::R_POWERPC_GOT16_LO
|| r_type == elfcpp::R_POWERPC_GOT16_HI
|| r_type == elfcpp::R_POWERPC_GOT16_HA
|| r_type == elfcpp::R_PPC64_GOT16_DS
|| r_type == elfcpp::R_PPC64_GOT16_LO_DS)
{
if (gsym != NULL)
{
gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD));
value = gsym->got_offset(GOT_TYPE_STANDARD);
}
else
{
unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
gold_assert(object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD));
value = object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
value -= target->got_section()->got_base_offset(object);
}
else if (r_type == elfcpp::R_PPC64_TOC)
{
value = (target->got_section()->output_section()->address()
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
+ object->toc_base_offset());
}
else if (gsym != NULL
&& (r_type == elfcpp::R_POWERPC_REL24
|| r_type == elfcpp::R_PPC_PLTREL24)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
&& has_plt_value)
{
if (size == 64)
{
typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
Valtype* wv = reinterpret_cast<Valtype*>(view);
bool can_plt_call = false;
if (rela.get_r_offset() + 8 <= view_size)
{
Valtype insn = elfcpp::Swap<32, big_endian>::readval(wv);
Valtype insn2 = elfcpp::Swap<32, big_endian>::readval(wv + 1);
if ((insn & 1) != 0
&& (insn2 == nop
|| insn2 == cror_15_15_15 || insn2 == cror_31_31_31))
{
elfcpp::Swap<32, big_endian>::writeval(wv + 1, ld_2_1 + 40);
can_plt_call = true;
}
}
if (!can_plt_call)
{
// If we don't have a branch and link followed by a nop,
// we can't go via the plt because there is no place to
// put a toc restoring instruction.
// Unless we know we won't be returning.
if (strcmp(gsym->name(), "__libc_start_main") == 0)
can_plt_call = true;
}
if (!can_plt_call)
{
// This is not an error in one special case: A self
// call. It isn't possible to cheaply verify we have
// such a call so just check for a call to the same
// section.
bool ok = false;
Address code = value;
if (gsym->source() == Symbol::FROM_OBJECT
&& gsym->object() == object)
{
Address addend = rela.get_r_addend();
unsigned int dest_shndx;
Address opdent = psymval->value(object, addend);
code = target->symval_for_branch(opdent, gsym, object,
&dest_shndx);
bool is_ordinary;
if (dest_shndx == 0)
dest_shndx = gsym->shndx(&is_ordinary);
ok = dest_shndx == relinfo->data_shndx;
}
if (!ok)
{
gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
_("call lacks nop, can't restore toc; "
"recompile with -fPIC"));
value = code;
}
}
}
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
else if (r_type == elfcpp::R_POWERPC_GOT_TLSGD16
|| r_type == elfcpp::R_POWERPC_GOT_TLSGD16_LO
|| r_type == elfcpp::R_POWERPC_GOT_TLSGD16_HI
|| r_type == elfcpp::R_POWERPC_GOT_TLSGD16_HA)
{
// First instruction of a global dynamic sequence, arg setup insn.
const bool final = gsym == NULL || gsym->final_value_is_known();
const tls::Tls_optimization tls_type = target->optimize_tls_gd(final);
enum Got_type got_type = GOT_TYPE_STANDARD;
if (tls_type == tls::TLSOPT_NONE)
got_type = GOT_TYPE_TLSGD;
else if (tls_type == tls::TLSOPT_TO_IE)
got_type = GOT_TYPE_TPREL;
if (got_type != GOT_TYPE_STANDARD)
{
if (gsym != NULL)
{
gold_assert(gsym->has_got_offset(got_type));
value = gsym->got_offset(got_type);
}
else
{
unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
gold_assert(object->local_has_got_offset(r_sym, got_type));
value = object->local_got_offset(r_sym, got_type);
}
value -= target->got_section()->got_base_offset(object);
}
if (tls_type == tls::TLSOPT_TO_IE)
{
if (r_type == elfcpp::R_POWERPC_GOT_TLSGD16
|| r_type == elfcpp::R_POWERPC_GOT_TLSGD16_LO)
{
Insn* iview = reinterpret_cast<Insn*>(view - 2 * big_endian);
Insn insn = elfcpp::Swap<32, big_endian>::readval(iview);
insn &= (1 << 26) - (1 << 16); // extract rt,ra from addi
if (size == 32)
insn |= 32 << 26; // lwz
else
insn |= 58 << 26; // ld
elfcpp::Swap<32, big_endian>::writeval(iview, insn);
}
r_type += (elfcpp::R_POWERPC_GOT_TPREL16
- elfcpp::R_POWERPC_GOT_TLSGD16);
}
else if (tls_type == tls::TLSOPT_TO_LE)
{
if (r_type == elfcpp::R_POWERPC_GOT_TLSGD16
|| r_type == elfcpp::R_POWERPC_GOT_TLSGD16_LO)
{
Insn* iview = reinterpret_cast<Insn*>(view - 2 * big_endian);
Insn insn = addis_3_13;
if (size == 32)
insn = addis_3_2;
elfcpp::Swap<32, big_endian>::writeval(iview, insn);
r_type = elfcpp::R_POWERPC_TPREL16_HA;
value = psymval->value(object, rela.get_r_addend());
}
else
{
Insn* iview = reinterpret_cast<Insn*>(view - 2 * big_endian);
Insn insn = nop;
elfcpp::Swap<32, big_endian>::writeval(iview, insn);
r_type = elfcpp::R_POWERPC_NONE;
}
}
}
else if (r_type == elfcpp::R_POWERPC_GOT_TLSLD16
|| r_type == elfcpp::R_POWERPC_GOT_TLSLD16_LO
|| r_type == elfcpp::R_POWERPC_GOT_TLSLD16_HI
|| r_type == elfcpp::R_POWERPC_GOT_TLSLD16_HA)
{
// First instruction of a local dynamic sequence, arg setup insn.
const tls::Tls_optimization tls_type = target->optimize_tls_ld();
if (tls_type == tls::TLSOPT_NONE)
{
value = target->tlsld_got_offset();
value -= target->got_section()->got_base_offset(object);
}
else
{
gold_assert(tls_type == tls::TLSOPT_TO_LE);
if (r_type == elfcpp::R_POWERPC_GOT_TLSLD16
|| r_type == elfcpp::R_POWERPC_GOT_TLSLD16_LO)
{
Insn* iview = reinterpret_cast<Insn*>(view - 2 * big_endian);
Insn insn = addis_3_13;
if (size == 32)
insn = addis_3_2;
elfcpp::Swap<32, big_endian>::writeval(iview, insn);
r_type = elfcpp::R_POWERPC_TPREL16_HA;
value = dtp_offset;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
else
{
Insn* iview = reinterpret_cast<Insn*>(view - 2 * big_endian);
Insn insn = nop;
elfcpp::Swap<32, big_endian>::writeval(iview, insn);
r_type = elfcpp::R_POWERPC_NONE;
}
}
}
else if (r_type == elfcpp::R_POWERPC_GOT_DTPREL16
|| r_type == elfcpp::R_POWERPC_GOT_DTPREL16_LO
|| r_type == elfcpp::R_POWERPC_GOT_DTPREL16_HI
|| r_type == elfcpp::R_POWERPC_GOT_DTPREL16_HA)
{
// Accesses relative to a local dynamic sequence address,
// no optimisation here.
if (gsym != NULL)
{
gold_assert(gsym->has_got_offset(GOT_TYPE_DTPREL));
value = gsym->got_offset(GOT_TYPE_DTPREL);
}
else
{
unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
gold_assert(object->local_has_got_offset(r_sym, GOT_TYPE_DTPREL));
value = object->local_got_offset(r_sym, GOT_TYPE_DTPREL);
}
value -= target->got_section()->got_base_offset(object);
}
else if (r_type == elfcpp::R_POWERPC_GOT_TPREL16
|| r_type == elfcpp::R_POWERPC_GOT_TPREL16_LO
|| r_type == elfcpp::R_POWERPC_GOT_TPREL16_HI
|| r_type == elfcpp::R_POWERPC_GOT_TPREL16_HA)
{
// First instruction of initial exec sequence.
const bool final = gsym == NULL || gsym->final_value_is_known();
const tls::Tls_optimization tls_type = target->optimize_tls_ie(final);
if (tls_type == tls::TLSOPT_NONE)
{
if (gsym != NULL)
{
gold_assert(gsym->has_got_offset(GOT_TYPE_TPREL));
value = gsym->got_offset(GOT_TYPE_TPREL);
}
else
{
unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
gold_assert(object->local_has_got_offset(r_sym, GOT_TYPE_TPREL));
value = object->local_got_offset(r_sym, GOT_TYPE_TPREL);
}
value -= target->got_section()->got_base_offset(object);
}
else
{
gold_assert(tls_type == tls::TLSOPT_TO_LE);
if (r_type == elfcpp::R_POWERPC_GOT_TPREL16
|| r_type == elfcpp::R_POWERPC_GOT_TPREL16_LO)
{
Insn* iview = reinterpret_cast<Insn*>(view - 2 * big_endian);
Insn insn = elfcpp::Swap<32, big_endian>::readval(iview);
insn &= (1 << 26) - (1 << 21); // extract rt from ld
if (size == 32)
insn |= addis_0_2;
else
insn |= addis_0_13;
elfcpp::Swap<32, big_endian>::writeval(iview, insn);
r_type = elfcpp::R_POWERPC_TPREL16_HA;
value = psymval->value(object, rela.get_r_addend());
}
else
{
Insn* iview = reinterpret_cast<Insn*>(view - 2 * big_endian);
Insn insn = nop;
elfcpp::Swap<32, big_endian>::writeval(iview, insn);
r_type = elfcpp::R_POWERPC_NONE;
}
}
}
else if ((size == 64 && r_type == elfcpp::R_PPC64_TLSGD)
|| (size == 32 && r_type == elfcpp::R_PPC_TLSGD))
{
// Second instruction of a global dynamic sequence,
// the __tls_get_addr call
this->call_tls_get_addr_ = CALL_EXPECTED;
const bool final = gsym == NULL || gsym->final_value_is_known();
const tls::Tls_optimization tls_type = target->optimize_tls_gd(final);
if (tls_type != tls::TLSOPT_NONE)
{
if (tls_type == tls::TLSOPT_TO_IE)
{
Insn* iview = reinterpret_cast<Insn*>(view);
Insn insn = add_3_3_13;
if (size == 32)
insn = add_3_3_2;
elfcpp::Swap<32, big_endian>::writeval(iview, insn);
r_type = elfcpp::R_POWERPC_NONE;
}
else
{
Insn* iview = reinterpret_cast<Insn*>(view);
Insn insn = addi_3_3;
elfcpp::Swap<32, big_endian>::writeval(iview, insn);
r_type = elfcpp::R_POWERPC_TPREL16_LO;
view += 2 * big_endian;
value = psymval->value(object, rela.get_r_addend());
}
this->call_tls_get_addr_ = CALL_SKIP;
}
}
else if ((size == 64 && r_type == elfcpp::R_PPC64_TLSLD)
|| (size == 32 && r_type == elfcpp::R_PPC_TLSLD))
{
// Second instruction of a local dynamic sequence,
// the __tls_get_addr call
this->call_tls_get_addr_ = CALL_EXPECTED;
const tls::Tls_optimization tls_type = target->optimize_tls_ld();
if (tls_type == tls::TLSOPT_TO_LE)
{
Insn* iview = reinterpret_cast<Insn*>(view);
Insn insn = addi_3_3;
elfcpp::Swap<32, big_endian>::writeval(iview, insn);
this->call_tls_get_addr_ = CALL_SKIP;
r_type = elfcpp::R_POWERPC_TPREL16_LO;
view += 2 * big_endian;
value = dtp_offset;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
}
else if (r_type == elfcpp::R_POWERPC_TLS)
{
// Second instruction of an initial exec sequence
const bool final = gsym == NULL || gsym->final_value_is_known();
const tls::Tls_optimization tls_type = target->optimize_tls_ie(final);
if (tls_type == tls::TLSOPT_TO_LE)
{
Insn* iview = reinterpret_cast<Insn*>(view);
Insn insn = elfcpp::Swap<32, big_endian>::readval(iview);
unsigned int reg = size == 32 ? 2 : 13;
insn = at_tls_transform(insn, reg);
gold_assert(insn != 0);
elfcpp::Swap<32, big_endian>::writeval(iview, insn);
r_type = elfcpp::R_POWERPC_TPREL16_LO;
view += 2 * big_endian;
value = psymval->value(object, rela.get_r_addend());
}
}
else if (!has_plt_value)
{
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Address addend = 0;
unsigned int dest_shndx;
if (r_type != elfcpp::R_PPC_PLTREL24)
addend = rela.get_r_addend();
value = psymval->value(object, addend);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
if (size == 64 && is_branch_reloc(r_type))
value = target->symval_for_branch(value, gsym, object, &dest_shndx);
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
unsigned int max_branch_offset = 0;
if (r_type == elfcpp::R_POWERPC_REL24
|| r_type == elfcpp::R_PPC_PLTREL24
|| r_type == elfcpp::R_PPC_LOCAL24PC)
max_branch_offset = 1 << 25;
else if (r_type == elfcpp::R_POWERPC_REL14
|| r_type == elfcpp::R_POWERPC_REL14_BRTAKEN
|| r_type == elfcpp::R_POWERPC_REL14_BRNTAKEN)
max_branch_offset = 1 << 15;
if (max_branch_offset != 0
&& value - address + max_branch_offset >= 2 * max_branch_offset)
{
Stub_table<size, big_endian>* stub_table
= object->stub_table(relinfo->data_shndx);
gold_assert(stub_table != NULL);
Address off = stub_table->find_long_branch_entry(object, value);
if (off != invalid_address)
value = stub_table->stub_address() + stub_table->plt_size() + off;
}
}
switch (r_type)
{
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_PPC64_REL64:
case elfcpp::R_POWERPC_REL32:
case elfcpp::R_POWERPC_REL24:
case elfcpp::R_PPC_PLTREL24:
case elfcpp::R_PPC_LOCAL24PC:
case elfcpp::R_POWERPC_REL16:
case elfcpp::R_POWERPC_REL16_LO:
case elfcpp::R_POWERPC_REL16_HI:
case elfcpp::R_POWERPC_REL16_HA:
case elfcpp::R_POWERPC_REL14:
case elfcpp::R_POWERPC_REL14_BRTAKEN:
case elfcpp::R_POWERPC_REL14_BRNTAKEN:
value -= address;
break;
case elfcpp::R_PPC64_TOC16:
case elfcpp::R_PPC64_TOC16_LO:
case elfcpp::R_PPC64_TOC16_HI:
case elfcpp::R_PPC64_TOC16_HA:
case elfcpp::R_PPC64_TOC16_DS:
case elfcpp::R_PPC64_TOC16_LO_DS:
// Subtract the TOC base address.
value -= (target->got_section()->output_section()->address()
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
+ object->toc_base_offset());
break;
case elfcpp::R_POWERPC_SECTOFF:
case elfcpp::R_POWERPC_SECTOFF_LO:
case elfcpp::R_POWERPC_SECTOFF_HI:
case elfcpp::R_POWERPC_SECTOFF_HA:
case elfcpp::R_PPC64_SECTOFF_DS:
case elfcpp::R_PPC64_SECTOFF_LO_DS:
if (os != NULL)
value -= os->address();
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_PPC64_TPREL16_DS:
case elfcpp::R_PPC64_TPREL16_LO_DS:
if (size != 64)
// R_PPC_TLSGD and R_PPC_TLSLD
break;
case elfcpp::R_POWERPC_TPREL16:
case elfcpp::R_POWERPC_TPREL16_LO:
case elfcpp::R_POWERPC_TPREL16_HI:
case elfcpp::R_POWERPC_TPREL16_HA:
case elfcpp::R_POWERPC_TPREL:
case elfcpp::R_PPC64_TPREL16_HIGHER:
case elfcpp::R_PPC64_TPREL16_HIGHERA:
case elfcpp::R_PPC64_TPREL16_HIGHEST:
case elfcpp::R_PPC64_TPREL16_HIGHESTA:
// tls symbol values are relative to tls_segment()->vaddr()
value -= tp_offset;
break;
case elfcpp::R_PPC64_DTPREL16_DS:
case elfcpp::R_PPC64_DTPREL16_LO_DS:
case elfcpp::R_PPC64_DTPREL16_HIGHER:
case elfcpp::R_PPC64_DTPREL16_HIGHERA:
case elfcpp::R_PPC64_DTPREL16_HIGHEST:
case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
if (size != 64)
// R_PPC_EMB_NADDR32, R_PPC_EMB_NADDR16, R_PPC_EMB_NADDR16_LO
// R_PPC_EMB_NADDR16_HI, R_PPC_EMB_NADDR16_HA, R_PPC_EMB_SDAI16
break;
case elfcpp::R_POWERPC_DTPREL16:
case elfcpp::R_POWERPC_DTPREL16_LO:
case elfcpp::R_POWERPC_DTPREL16_HI:
case elfcpp::R_POWERPC_DTPREL16_HA:
case elfcpp::R_POWERPC_DTPREL:
// tls symbol values are relative to tls_segment()->vaddr()
value -= dtp_offset;
break;
default:
break;
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Insn branch_bit = 0;
switch (r_type)
{
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
case elfcpp::R_POWERPC_REL14_BRTAKEN:
branch_bit = 1 << 21;
case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
case elfcpp::R_POWERPC_REL14_BRNTAKEN:
{
Insn* iview = reinterpret_cast<Insn*>(view);
Insn insn = elfcpp::Swap<32, big_endian>::readval(iview);
insn &= ~(1 << 21);
insn |= branch_bit;
if (this->is_isa_v2)
{
// Set 'a' bit. This is 0b00010 in BO field for branch
// on CR(BI) insns (BO == 001at or 011at), and 0b01000
// for branch on CTR insns (BO == 1a00t or 1a01t).
if ((insn & (0x14 << 21)) == (0x04 << 21))
insn |= 0x02 << 21;
else if ((insn & (0x14 << 21)) == (0x10 << 21))
insn |= 0x08 << 21;
else
break;
}
else
{
// Invert 'y' bit if not the default.
if (static_cast<Signed_address>(value) < 0)
insn ^= 1 << 21;
}
elfcpp::Swap<32, big_endian>::writeval(iview, insn);
}
break;
default:
break;
}
typename Reloc::Overflow_check overflow = Reloc::CHECK_NONE;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
switch (r_type)
{
case elfcpp::R_POWERPC_ADDR32:
case elfcpp::R_POWERPC_UADDR32:
if (size == 64)
overflow = Reloc::CHECK_BITFIELD;
break;
case elfcpp::R_POWERPC_REL32:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
if (size == 64)
overflow = Reloc::CHECK_SIGNED;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
break;
case elfcpp::R_POWERPC_ADDR24:
case elfcpp::R_POWERPC_ADDR16:
case elfcpp::R_POWERPC_UADDR16:
case elfcpp::R_PPC64_ADDR16_DS:
case elfcpp::R_POWERPC_ADDR14:
case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
overflow = Reloc::CHECK_BITFIELD;
break;
case elfcpp::R_POWERPC_REL24:
case elfcpp::R_PPC_PLTREL24:
case elfcpp::R_PPC_LOCAL24PC:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_REL16:
case elfcpp::R_PPC64_TOC16:
case elfcpp::R_POWERPC_GOT16:
case elfcpp::R_POWERPC_SECTOFF:
case elfcpp::R_POWERPC_TPREL16:
case elfcpp::R_POWERPC_DTPREL16:
case elfcpp::R_PPC64_TPREL16_DS:
case elfcpp::R_PPC64_DTPREL16_DS:
case elfcpp::R_PPC64_TOC16_DS:
case elfcpp::R_PPC64_GOT16_DS:
case elfcpp::R_PPC64_SECTOFF_DS:
case elfcpp::R_POWERPC_REL14:
case elfcpp::R_POWERPC_REL14_BRTAKEN:
case elfcpp::R_POWERPC_REL14_BRNTAKEN:
case elfcpp::R_POWERPC_GOT_TLSGD16:
case elfcpp::R_POWERPC_GOT_TLSLD16:
case elfcpp::R_POWERPC_GOT_TPREL16:
case elfcpp::R_POWERPC_GOT_DTPREL16:
overflow = Reloc::CHECK_SIGNED;
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
typename Powerpc_relocate_functions<size, big_endian>::Status status
= Powerpc_relocate_functions<size, big_endian>::STATUS_OK;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
switch (r_type)
{
case elfcpp::R_POWERPC_NONE:
case elfcpp::R_POWERPC_TLS:
case elfcpp::R_POWERPC_GNU_VTINHERIT:
case elfcpp::R_POWERPC_GNU_VTENTRY:
case elfcpp::R_PPC_EMB_MRKREF:
break;
case elfcpp::R_PPC64_ADDR64:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_PPC64_REL64:
case elfcpp::R_PPC64_TOC:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Reloc::addr64(view, value);
break;
case elfcpp::R_POWERPC_TPREL:
case elfcpp::R_POWERPC_DTPREL:
if (size == 64)
Reloc::addr64(view, value);
else
status = Reloc::addr32(view, value, overflow);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
break;
case elfcpp::R_PPC64_UADDR64:
Reloc::addr64_u(view, value);
break;
case elfcpp::R_POWERPC_ADDR32:
status = Reloc::addr32(view, value, overflow);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
break;
case elfcpp::R_POWERPC_REL32:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_UADDR32:
status = Reloc::addr32_u(view, value, overflow);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
break;
case elfcpp::R_POWERPC_ADDR24:
case elfcpp::R_POWERPC_REL24:
case elfcpp::R_PPC_PLTREL24:
case elfcpp::R_PPC_LOCAL24PC:
status = Reloc::addr24(view, value, overflow);
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_GOT_DTPREL16:
case elfcpp::R_POWERPC_GOT_DTPREL16_LO:
if (size == 64)
{
status = Reloc::addr16_ds(view, value, overflow);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
break;
}
case elfcpp::R_POWERPC_ADDR16:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_REL16:
case elfcpp::R_PPC64_TOC16:
case elfcpp::R_POWERPC_GOT16:
case elfcpp::R_POWERPC_SECTOFF:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_TPREL16:
case elfcpp::R_POWERPC_DTPREL16:
case elfcpp::R_POWERPC_GOT_TLSGD16:
case elfcpp::R_POWERPC_GOT_TLSLD16:
case elfcpp::R_POWERPC_GOT_TPREL16:
case elfcpp::R_POWERPC_ADDR16_LO:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_REL16_LO:
case elfcpp::R_PPC64_TOC16_LO:
case elfcpp::R_POWERPC_GOT16_LO:
case elfcpp::R_POWERPC_SECTOFF_LO:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_TPREL16_LO:
case elfcpp::R_POWERPC_DTPREL16_LO:
case elfcpp::R_POWERPC_GOT_TLSGD16_LO:
case elfcpp::R_POWERPC_GOT_TLSLD16_LO:
case elfcpp::R_POWERPC_GOT_TPREL16_LO:
status = Reloc::addr16(view, value, overflow);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
break;
case elfcpp::R_POWERPC_UADDR16:
status = Reloc::addr16_u(view, value, overflow);
break;
case elfcpp::R_POWERPC_ADDR16_HI:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_REL16_HI:
case elfcpp::R_PPC64_TOC16_HI:
case elfcpp::R_POWERPC_GOT16_HI:
case elfcpp::R_POWERPC_SECTOFF_HI:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_TPREL16_HI:
case elfcpp::R_POWERPC_DTPREL16_HI:
case elfcpp::R_POWERPC_GOT_TLSGD16_HI:
case elfcpp::R_POWERPC_GOT_TLSLD16_HI:
case elfcpp::R_POWERPC_GOT_TPREL16_HI:
case elfcpp::R_POWERPC_GOT_DTPREL16_HI:
Reloc::addr16_hi(view, value);
break;
case elfcpp::R_POWERPC_ADDR16_HA:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_REL16_HA:
case elfcpp::R_PPC64_TOC16_HA:
case elfcpp::R_POWERPC_GOT16_HA:
case elfcpp::R_POWERPC_SECTOFF_HA:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_TPREL16_HA:
case elfcpp::R_POWERPC_DTPREL16_HA:
case elfcpp::R_POWERPC_GOT_TLSGD16_HA:
case elfcpp::R_POWERPC_GOT_TLSLD16_HA:
case elfcpp::R_POWERPC_GOT_TPREL16_HA:
case elfcpp::R_POWERPC_GOT_DTPREL16_HA:
Reloc::addr16_ha(view, value);
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_PPC64_DTPREL16_HIGHER:
if (size == 32)
// R_PPC_EMB_NADDR16_LO
goto unsupp;
case elfcpp::R_PPC64_ADDR16_HIGHER:
case elfcpp::R_PPC64_TPREL16_HIGHER:
Reloc::addr16_hi2(view, value);
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_PPC64_DTPREL16_HIGHERA:
if (size == 32)
// R_PPC_EMB_NADDR16_HI
goto unsupp;
case elfcpp::R_PPC64_ADDR16_HIGHERA:
case elfcpp::R_PPC64_TPREL16_HIGHERA:
Reloc::addr16_ha2(view, value);
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_PPC64_DTPREL16_HIGHEST:
if (size == 32)
// R_PPC_EMB_NADDR16_HA
goto unsupp;
case elfcpp::R_PPC64_ADDR16_HIGHEST:
case elfcpp::R_PPC64_TPREL16_HIGHEST:
Reloc::addr16_hi3(view, value);
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
if (size == 32)
// R_PPC_EMB_SDAI16
goto unsupp;
case elfcpp::R_PPC64_ADDR16_HIGHESTA:
case elfcpp::R_PPC64_TPREL16_HIGHESTA:
Reloc::addr16_ha3(view, value);
break;
case elfcpp::R_PPC64_DTPREL16_DS:
case elfcpp::R_PPC64_DTPREL16_LO_DS:
if (size == 32)
// R_PPC_EMB_NADDR32, R_PPC_EMB_NADDR16
goto unsupp;
case elfcpp::R_PPC64_TPREL16_DS:
case elfcpp::R_PPC64_TPREL16_LO_DS:
if (size == 32)
// R_PPC_TLSGD, R_PPC_TLSLD
break;
case elfcpp::R_PPC64_ADDR16_DS:
case elfcpp::R_PPC64_ADDR16_LO_DS:
case elfcpp::R_PPC64_TOC16_DS:
case elfcpp::R_PPC64_TOC16_LO_DS:
case elfcpp::R_PPC64_GOT16_DS:
case elfcpp::R_PPC64_GOT16_LO_DS:
case elfcpp::R_PPC64_SECTOFF_DS:
case elfcpp::R_PPC64_SECTOFF_LO_DS:
status = Reloc::addr16_ds(view, value, overflow);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
break;
case elfcpp::R_POWERPC_ADDR14:
case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
case elfcpp::R_POWERPC_REL14:
case elfcpp::R_POWERPC_REL14_BRTAKEN:
case elfcpp::R_POWERPC_REL14_BRNTAKEN:
status = Reloc::addr14(view, value, overflow);
break;
case elfcpp::R_POWERPC_COPY:
case elfcpp::R_POWERPC_GLOB_DAT:
case elfcpp::R_POWERPC_JMP_SLOT:
case elfcpp::R_POWERPC_RELATIVE:
case elfcpp::R_POWERPC_DTPMOD:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_PPC64_JMP_IREL:
case elfcpp::R_POWERPC_IRELATIVE:
gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
_("unexpected reloc %u in object file"),
r_type);
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_PPC_EMB_SDA21:
if (size == 32)
goto unsupp;
else
{
// R_PPC64_TOCSAVE. For the time being this can be ignored.
}
break;
case elfcpp::R_PPC_EMB_SDA2I16:
case elfcpp::R_PPC_EMB_SDA2REL:
if (size == 32)
goto unsupp;
// R_PPC64_TLSGD, R_PPC64_TLSLD
break;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
case elfcpp::R_POWERPC_PLT32:
case elfcpp::R_POWERPC_PLTREL32:
case elfcpp::R_POWERPC_PLT16_LO:
case elfcpp::R_POWERPC_PLT16_HI:
case elfcpp::R_POWERPC_PLT16_HA:
case elfcpp::R_PPC_SDAREL16:
case elfcpp::R_POWERPC_ADDR30:
case elfcpp::R_PPC64_PLT64:
case elfcpp::R_PPC64_PLTREL64:
case elfcpp::R_PPC64_PLTGOT16:
case elfcpp::R_PPC64_PLTGOT16_LO:
case elfcpp::R_PPC64_PLTGOT16_HI:
case elfcpp::R_PPC64_PLTGOT16_HA:
case elfcpp::R_PPC64_PLT16_LO_DS:
case elfcpp::R_PPC64_PLTGOT16_DS:
case elfcpp::R_PPC64_PLTGOT16_LO_DS:
case elfcpp::R_PPC_EMB_RELSEC16:
case elfcpp::R_PPC_EMB_RELST_LO:
case elfcpp::R_PPC_EMB_RELST_HI:
case elfcpp::R_PPC_EMB_RELST_HA:
case elfcpp::R_PPC_EMB_BIT_FLD:
case elfcpp::R_PPC_EMB_RELSDA:
case elfcpp::R_PPC_TOC16:
default:
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
unsupp:
gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
_("unsupported reloc %u"),
r_type);
break;
}
if (status != Powerpc_relocate_functions<size, big_endian>::STATUS_OK)
gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
_("relocation overflow"));
return true;
}
// Relocate section data.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::relocate_section(
const Relocate_info<size, big_endian>* relinfo,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
bool needs_special_offset_handling,
unsigned char* view,
Address address,
section_size_type view_size,
const Reloc_symbol_changes* reloc_symbol_changes)
{
typedef Target_powerpc<size, big_endian> Powerpc;
typedef typename Target_powerpc<size, big_endian>::Relocate Powerpc_relocate;
typedef typename Target_powerpc<size, big_endian>::Relocate_comdat_behavior
Powerpc_comdat_behavior;
gold_assert(sh_type == elfcpp::SHT_RELA);
gold::relocate_section<size, big_endian, Powerpc, elfcpp::SHT_RELA,
Powerpc_relocate, Powerpc_comdat_behavior>(
relinfo,
this,
prelocs,
reloc_count,
output_section,
needs_special_offset_handling,
view,
address,
* options.h (class General_options): Define split_stack_adjust_size parameter. * object.h (class Object): Add uses_split_stack_ and has_no_split_stack_ fields. Add uses_split_stack and has_no_split_stack accessor functions. Declare handle_split_stack_section. (class Reloc_symbol_changes): Define. (class Sized_relobj): Define Function_offsets. Declare split_stack_adjust, split_stack_adjust_reltype, and find_functions. * object.cc (Object::handle_split_stack_section): New function. (Sized_relobj::do_layout): Call handle_split_stack_section. * dynobj.cc (Sized_dynobj::do_layout): Call handle_split_stack_section. * reloc.cc (Sized_relobj::relocate_sections): Call split_stack_adjust for executable sections in split_stack objects. Pass reloc_map to relocate_section. (Sized_relobj::split_stack_adjust): New function. (Sized_relobj::split_stack_adjust_reltype): New function. (Sized_relobj::find_functions): New function. * target-reloc.h: Include "object.h". (relocate_section): Add reloc_symbol_changes parameter. Change all callers. * target.h (class Target): Add calls_non_split method. Declare do_calls_non_split virtual method. Declare match_view and set_view_to_nop. * target.cc: Include "elfcpp.h". (Target::do_calls_non_split): New function. (Target::match_view): New function. (Target::set_view_to_nop): New function. * gold.cc (queue_middle_tasks): Give an error if mixing split-stack and non-split-stack objects with -r. * i386.cc (Target_i386::relocate_section): Add reloc_symbol_changes parameter. (Target_i386::do_calls_non_split): New function. * x86_64.cc (Target_x86_64::relocate_section): Add reloc_symbol_changes parameter. (Target_x86_64::do_calls_non_split): New function. * arm.cc (Target_arm::relocate_section): Add reloc_symbol_changes parameter. * powerpc.cc (Target_powerpc::relocate_section): Add reloc_symbol_changes parameter. * sparc.cc (Target_sparc::relocate_section): Add reloc_symbol_changes parameter. * configure.ac: Call AM_CONDITIONAL for the default target. * configure: Rebuild. * testsuite/Makefile.am (TEST_AS): New variable. (check_SCRIPTS): Add split_i386.sh and split_x86_64.sh. (check_DATA): Add split_i386 and split_x86_64 files. (SPLIT_DEFSYMS): Define. (split_i386_[1234n].o): New targets. (split_i386_[124]): New targets. (split_i386_[1234r].stdout): New targets. (split_x86_64_[1234n].o): New targets. (split_x86_64_[124]): New targets. (split_x86_64_[1234r].stdout): New targets. (MOSTLYCLEANFILES): Add new executables. * testsuite/split_i386.sh: New file. * testsuite/split_x86_64.sh: New file. * testsuite/split_i386_1.s: New file. * testsuite/split_i386_2.s: New file. * testsuite/split_i386_3.s: New file. * testsuite/split_i386_4.s: New file. * testsuite/split_i386_n.s: New file. * testsuite/split_x86_64_1.s: New file. * testsuite/split_x86_64_2.s: New file. * testsuite/split_x86_64_3.s: New file. * testsuite/split_x86_64_4.s: New file. * testsuite/split_x86_64_n.s: New file. * testsuite/testfile.cc (Target_test): Update relocation_section function. * testsuite/Makefile.in: Rebuild.
2009-10-07 00:58:27 +02:00
view_size,
reloc_symbol_changes);
}
class Powerpc_scan_relocatable_reloc
{
public:
// Return the strategy to use for a local symbol which is not a
// section symbol, given the relocation type.
inline Relocatable_relocs::Reloc_strategy
local_non_section_strategy(unsigned int r_type, Relobj*, unsigned int r_sym)
{
if (r_type == 0 && r_sym == 0)
return Relocatable_relocs::RELOC_DISCARD;
return Relocatable_relocs::RELOC_COPY;
}
// Return the strategy to use for a local symbol which is a section
// symbol, given the relocation type.
inline Relocatable_relocs::Reloc_strategy
local_section_strategy(unsigned int, Relobj*)
{
return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA;
}
// Return the strategy to use for a global symbol, given the
// relocation type, the object, and the symbol index.
inline Relocatable_relocs::Reloc_strategy
global_strategy(unsigned int r_type, Relobj*, unsigned int)
{
if (r_type == elfcpp::R_PPC_PLTREL24)
return Relocatable_relocs::RELOC_SPECIAL;
return Relocatable_relocs::RELOC_COPY;
}
};
// Scan the relocs during a relocatable link.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::scan_relocatable_relocs(
Symbol_table* symtab,
Layout* layout,
Sized_relobj_file<size, big_endian>* object,
unsigned int data_shndx,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
bool needs_special_offset_handling,
size_t local_symbol_count,
const unsigned char* plocal_symbols,
Relocatable_relocs* rr)
{
gold_assert(sh_type == elfcpp::SHT_RELA);
gold::scan_relocatable_relocs<size, big_endian, elfcpp::SHT_RELA,
Powerpc_scan_relocatable_reloc>(
symtab,
layout,
object,
data_shndx,
prelocs,
reloc_count,
output_section,
needs_special_offset_handling,
local_symbol_count,
plocal_symbols,
rr);
}
// Emit relocations for a section.
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// This is a modified version of the function by the same name in
// target-reloc.h. Using relocate_special_relocatable for
// R_PPC_PLTREL24 would require duplication of the entire body of the
// loop, so we may as well duplicate the whole thing.
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::relocate_relocs(
const Relocate_info<size, big_endian>* relinfo,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
const Relocatable_relocs* rr,
unsigned char*,
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
Address view_address,
section_size_type,
unsigned char* reloc_view,
section_size_type reloc_view_size)
{
gold_assert(sh_type == elfcpp::SHT_RELA);
typedef typename Reloc_types<elfcpp::SHT_RELA, size, big_endian>::Reloc
Reltype;
typedef typename Reloc_types<elfcpp::SHT_RELA, size, big_endian>::Reloc_write
Reltype_write;
const int reloc_size
= Reloc_types<elfcpp::SHT_RELA, size, big_endian>::reloc_size;
Powerpc_relobj<size, big_endian>* const object
= static_cast<Powerpc_relobj<size, big_endian>*>(relinfo->object);
const unsigned int local_count = object->local_symbol_count();
unsigned int got2_shndx = object->got2_shndx();
Address got2_addend = 0;
if (got2_shndx != 0)
{
got2_addend = object->get_output_section_offset(got2_shndx);
gold_assert(got2_addend != invalid_address);
}
unsigned char* pwrite = reloc_view;
bool zap_next = false;
for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
{
Relocatable_relocs::Reloc_strategy strategy = rr->strategy(i);
if (strategy == Relocatable_relocs::RELOC_DISCARD)
continue;
Reltype reloc(prelocs);
Reltype_write reloc_write(pwrite);
Address offset = reloc.get_r_offset();
typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info();
unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
const unsigned int orig_r_sym = r_sym;
typename elfcpp::Elf_types<size>::Elf_Swxword addend
= reloc.get_r_addend();
const Symbol* gsym = NULL;
if (zap_next)
{
// We could arrange to discard these and other relocs for
// tls optimised sequences in the strategy methods, but for
// now do as BFD ld does.
r_type = elfcpp::R_POWERPC_NONE;
zap_next = false;
}
// Get the new symbol index.
if (r_sym < local_count)
{
switch (strategy)
{
case Relocatable_relocs::RELOC_COPY:
case Relocatable_relocs::RELOC_SPECIAL:
if (r_sym != 0)
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{
r_sym = object->symtab_index(r_sym);
gold_assert(r_sym != -1U);
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
break;
case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA:
{
// We are adjusting a section symbol. We need to find
// the symbol table index of the section symbol for
// the output section corresponding to input section
// in which this symbol is defined.
gold_assert(r_sym < local_count);
bool is_ordinary;
unsigned int shndx =
object->local_symbol_input_shndx(r_sym, &is_ordinary);
gold_assert(is_ordinary);
Output_section* os = object->output_section(shndx);
gold_assert(os != NULL);
gold_assert(os->needs_symtab_index());
r_sym = os->symtab_index();
}
break;
default:
gold_unreachable();
}
}
else
{
gsym = object->global_symbol(r_sym);
gold_assert(gsym != NULL);
if (gsym->is_forwarder())
gsym = relinfo->symtab->resolve_forwards(gsym);
gold_assert(gsym->has_symtab_index());
r_sym = gsym->symtab_index();
}
// Get the new offset--the location in the output section where
// this relocation should be applied.
if (static_cast<Address>(offset_in_output_section) != invalid_address)
offset += offset_in_output_section;
else
{
section_offset_type sot_offset =
convert_types<section_offset_type, Address>(offset);
section_offset_type new_sot_offset =
output_section->output_offset(object, relinfo->data_shndx,
sot_offset);
gold_assert(new_sot_offset != -1);
offset = new_sot_offset;
}
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
// In an object file, r_offset is an offset within the section.
// In an executable or dynamic object, generated by
// --emit-relocs, r_offset is an absolute address.
if (!parameters->options().relocatable())
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
{
offset += view_address;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
if (static_cast<Address>(offset_in_output_section) != invalid_address)
offset -= offset_in_output_section;
* powerpc.cc (Powerpc_relobj): Add and use Address typedef. (Powerpc_relobj::toc_base_offset): New stub function. (Target_powerpc): Add tp_offset, dtp_offset. Rename got_mod_index_offset to tlsld_got_offset. Update all refs. (Target_powerpc::Relocate::enum skip_tls): New. (Target_powerpc::call_tls_get_addr_): New var. (Target_powerpc::is_branch_reloc): Move to file scope. (Target_powerpc::relocate_tls, optimize_tls_reloc): Delete. (Target_powerpc::optimize_tls_gd, optimize_tls_ld, optimize_tls_ie): New functions. (Target_powerpc::enum Got_type): Delete old values, add new ones. (powerpc_info): Correct common_pagesize for ppc64. (at_tls_transform, needs_dynamic_reloc, use_plt_offset): New functions. (Powerpc_relocate_functions): Add overflow check enums and functions. Add non-shift version of rela, rela_ua. Delete all rel public functions. Delete addr16_lo. Add addr64, addr64_u, addr32, addr32_u, addr24, addr16_u, addr16_hi2, addr16_ha2, addr16_hi3, addr16_ha3, addr14 functions. (Output_data_got_powerpc::add_constant_pair): New function. (Output_data_got_powerpc::got_base_offset): Likewise. (Output_data_got_powerpc::do_write): Correct 64-bit got header. (instruction constants): Sort, add some more. (Output_data_glink::do_write): Add and use Address typedef. Use object->toc_base_offset() stub for 64-bit. (Target_powerpc::tlsld_got_offset): Use add_constant_pair. (Target_powerpc::Scan::get_reference_flags): Handle more relocs. (Target_powerpc::Scan::local, global): Emit relative dynamic reloc for R_PPC64_TOC. Handle more relocs. Generate got entries for TLS. Always treat .opd relocs as against locally defined symbol. Correct condition for RELATIVE relocs. (Target_powerpc::do_finalize_sections): Test for NULL sections. (Target_powerpc::Relocate::relocate): Use plt call stub as value for 32-bit syms with a plt entry. Correct ppc64 toc base calculations. Handle TLS relocs, and more. Add overflow checking and adjust for Powerpc_relocate_functions changes. (Target_powerpc::relocate_for_relocatable): Handle zero r_sym. Reinstate --emit-relocs code with FIXME.
2012-08-31 03:09:52 +02:00
}
// Handle the reloc addend based on the strategy.
if (strategy == Relocatable_relocs::RELOC_COPY)
;
else if (strategy == Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA)
{
const Symbol_value<size>* psymval = object->local_symbol(orig_r_sym);
addend = psymval->value(object, addend);
}
else if (strategy == Relocatable_relocs::RELOC_SPECIAL)
{
if (addend >= 32768)
addend += got2_addend;
}
else
gold_unreachable();
if (!parameters->options().relocatable())
{
if (r_type == elfcpp::R_POWERPC_GOT_TLSGD16
|| r_type == elfcpp::R_POWERPC_GOT_TLSGD16_LO
|| r_type == elfcpp::R_POWERPC_GOT_TLSGD16_HI
|| r_type == elfcpp::R_POWERPC_GOT_TLSGD16_HA)
{
// First instruction of a global dynamic sequence,
// arg setup insn.
const bool final = gsym == NULL || gsym->final_value_is_known();
switch (this->optimize_tls_gd(final))
{
case tls::TLSOPT_TO_IE:
r_type += (elfcpp::R_POWERPC_GOT_TPREL16
- elfcpp::R_POWERPC_GOT_TLSGD16);
break;
case tls::TLSOPT_TO_LE:
if (r_type == elfcpp::R_POWERPC_GOT_TLSGD16
|| r_type == elfcpp::R_POWERPC_GOT_TLSGD16_LO)
r_type = elfcpp::R_POWERPC_TPREL16_HA;
else
{
r_type = elfcpp::R_POWERPC_NONE;
offset -= 2 * big_endian;
}
break;
default:
break;
}
}
else if (r_type == elfcpp::R_POWERPC_GOT_TLSLD16
|| r_type == elfcpp::R_POWERPC_GOT_TLSLD16_LO
|| r_type == elfcpp::R_POWERPC_GOT_TLSLD16_HI
|| r_type == elfcpp::R_POWERPC_GOT_TLSLD16_HA)
{
// First instruction of a local dynamic sequence,
// arg setup insn.
if (this->optimize_tls_ld() == tls::TLSOPT_TO_LE)
{
if (r_type == elfcpp::R_POWERPC_GOT_TLSLD16
|| r_type == elfcpp::R_POWERPC_GOT_TLSLD16_LO)
{
r_type = elfcpp::R_POWERPC_TPREL16_HA;
const Output_section* os = relinfo->layout->tls_segment()
->first_section();
gold_assert(os != NULL);
gold_assert(os->needs_symtab_index());
r_sym = os->symtab_index();
addend = dtp_offset;
}
else
{
r_type = elfcpp::R_POWERPC_NONE;
offset -= 2 * big_endian;
}
}
}
else if (r_type == elfcpp::R_POWERPC_GOT_TPREL16
|| r_type == elfcpp::R_POWERPC_GOT_TPREL16_LO
|| r_type == elfcpp::R_POWERPC_GOT_TPREL16_HI
|| r_type == elfcpp::R_POWERPC_GOT_TPREL16_HA)
{
// First instruction of initial exec sequence.
const bool final = gsym == NULL || gsym->final_value_is_known();
if (this->optimize_tls_ie(final) == tls::TLSOPT_TO_LE)
{
if (r_type == elfcpp::R_POWERPC_GOT_TPREL16
|| r_type == elfcpp::R_POWERPC_GOT_TPREL16_LO)
r_type = elfcpp::R_POWERPC_TPREL16_HA;
else
{
r_type = elfcpp::R_POWERPC_NONE;
offset -= 2 * big_endian;
}
}
}
else if ((size == 64 && r_type == elfcpp::R_PPC64_TLSGD)
|| (size == 32 && r_type == elfcpp::R_PPC_TLSGD))
{
// Second instruction of a global dynamic sequence,
// the __tls_get_addr call
const bool final = gsym == NULL || gsym->final_value_is_known();
switch (this->optimize_tls_gd(final))
{
case tls::TLSOPT_TO_IE:
r_type = elfcpp::R_POWERPC_NONE;
zap_next = true;
break;
case tls::TLSOPT_TO_LE:
r_type = elfcpp::R_POWERPC_TPREL16_LO;
offset += 2 * big_endian;
zap_next = true;
break;
default:
break;
}
}
else if ((size == 64 && r_type == elfcpp::R_PPC64_TLSLD)
|| (size == 32 && r_type == elfcpp::R_PPC_TLSLD))
{
// Second instruction of a local dynamic sequence,
// the __tls_get_addr call
if (this->optimize_tls_ld() == tls::TLSOPT_TO_LE)
{
const Output_section* os = relinfo->layout->tls_segment()
->first_section();
gold_assert(os != NULL);
gold_assert(os->needs_symtab_index());
r_sym = os->symtab_index();
addend = dtp_offset;
r_type = elfcpp::R_POWERPC_TPREL16_LO;
offset += 2 * big_endian;
zap_next = true;
}
}
else if (r_type == elfcpp::R_POWERPC_TLS)
{
// Second instruction of an initial exec sequence
const bool final = gsym == NULL || gsym->final_value_is_known();
if (this->optimize_tls_ie(final) == tls::TLSOPT_TO_LE)
{
r_type = elfcpp::R_POWERPC_TPREL16_LO;
offset += 2 * big_endian;
}
}
}
reloc_write.put_r_offset(offset);
reloc_write.put_r_info(elfcpp::elf_r_info<size>(r_sym, r_type));
reloc_write.put_r_addend(addend);
pwrite += reloc_size;
}
gold_assert(static_cast<section_size_type>(pwrite - reloc_view)
== reloc_view_size);
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
// Return the value to use for a dynamic symbol which requires special
// treatment. This is how we support equality comparisons of function
// pointers across shared library boundaries, as described in the
// processor specific ABI supplement.
template<int size, bool big_endian>
uint64_t
Target_powerpc<size, big_endian>::do_dynsym_value(const Symbol* gsym) const
{
if (size == 32)
{
gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
for (typename Stub_tables::const_iterator p = this->stub_tables_.begin();
p != this->stub_tables_.end();
++p)
{
Address off = (*p)->find_plt_call_entry(gsym);
if (off != invalid_address)
return (*p)->stub_address() + off;
}
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
gold_unreachable();
}
// Return the PLT address to use for a local symbol.
template<int size, bool big_endian>
uint64_t
Target_powerpc<size, big_endian>::do_plt_address_for_local(
const Relobj* object,
unsigned int symndx) const
{
if (size == 32)
{
const Sized_relobj<size, big_endian>* relobj
= static_cast<const Sized_relobj<size, big_endian>*>(object);
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
for (typename Stub_tables::const_iterator p = this->stub_tables_.begin();
p != this->stub_tables_.end();
++p)
{
Address off = (*p)->find_plt_call_entry(relobj->sized_relobj(),
symndx);
if (off != invalid_address)
return (*p)->stub_address() + off;
}
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
gold_unreachable();
}
// Return the PLT address to use for a global symbol.
template<int size, bool big_endian>
uint64_t
Target_powerpc<size, big_endian>::do_plt_address_for_global(
const Symbol* gsym) const
{
if (size == 32)
{
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
for (typename Stub_tables::const_iterator p = this->stub_tables_.begin();
p != this->stub_tables_.end();
++p)
{
Address off = (*p)->find_plt_call_entry(gsym);
if (off != invalid_address)
return (*p)->stub_address() + off;
}
}
* layout.h (Layout::get_executable_sections): Declare. * layout.cc (Layout::get_executable_sections): New function. * arm.cc (Target_arm::group_sections): Use it. (Arm_output_section::group_sections): Delete now redundant test. * output.cc (Output_reloc::Output_reloc): Add is_relative. param to handle relative relocs. * output.h (Output_reloc::Output_reloc <absolute reloc>): Likewise. (Output_data_reloc::add_absolute): Adjust. (Output_data_reloc::add_relative): New function. (Output_data::reset_data_size): New function. (Output_relaxed_input_section::set_relobj, set_shndx): New functions. (Output_section::set_addralign): New function. (Output_section::checkpoint_set_addralign): New function. (Output_section::clear_section_offsets_need_adjustment): New function. (Output_section::input_sections): Make public. * powerpc.cc (class Output_data_brlt_powerpc): New. (class Stub_table, class Stub_control): New. (Powerpc_relobj::has14_, set_has_14bit_branch, has_14bit_branch, stub_table_, set_stub_table, stub_table): New vectors and accessor functions. (Target_powerpc::do_may_relax, do_relax, push_branch, new_stub_table, stub_tables, brlt_section, group_sections, add_branch_lookup_table, find_branch_lookup_table, write_branch_lookup_table, make_brlt_section): New functions. (Target_powerpc::struct Sort_sections, class Branch_info): New. (Target_powerpc::brlt_section_, stub_tables_, branch_lookup_table_, branch_info_): New vars. (Target_powerpc::make_plt_entry, make_local_ifunc_plt_entry): Don't make call stubs here. (Output_data_glink): Remove all call stub handling from this class. (Target_powerpc::Scan::local, global): Save interesting branch relocs and relocs for ifunc. Adjust calls to plt entry functions. (Target_powerpc::do_finalize_sections): Only make reg save/restore functions on final link. (Target_powerpc::Relocate::relocate): Adjust lookup of call stubs. Handle long branch destinations too. (Target_powerpc::do_dynsym_value, do_plt_address_for_global, do_plt_address_for_local): Adjust lookup of plt call stubs.
2012-12-03 06:30:59 +01:00
gold_unreachable();
}
// Return the offset to use for the GOT_INDX'th got entry which is
// for a local tls symbol specified by OBJECT, SYMNDX.
template<int size, bool big_endian>
int64_t
Target_powerpc<size, big_endian>::do_tls_offset_for_local(
const Relobj* object,
unsigned int symndx,
unsigned int got_indx) const
{
const Powerpc_relobj<size, big_endian>* ppc_object
= static_cast<const Powerpc_relobj<size, big_endian>*>(object);
if (ppc_object->local_symbol(symndx)->is_tls_symbol())
{
for (Got_type got_type = GOT_TYPE_TLSGD;
got_type <= GOT_TYPE_TPREL;
got_type = Got_type(got_type + 1))
if (ppc_object->local_has_got_offset(symndx, got_type))
{
unsigned int off = ppc_object->local_got_offset(symndx, got_type);
if (got_type == GOT_TYPE_TLSGD)
off += size / 8;
if (off == got_indx * (size / 8))
{
if (got_type == GOT_TYPE_TPREL)
return -tp_offset;
else
return -dtp_offset;
}
}
}
gold_unreachable();
}
// Return the offset to use for the GOT_INDX'th got entry which is
// for global tls symbol GSYM.
template<int size, bool big_endian>
int64_t
Target_powerpc<size, big_endian>::do_tls_offset_for_global(
Symbol* gsym,
unsigned int got_indx) const
{
if (gsym->type() == elfcpp::STT_TLS)
{
for (Got_type got_type = GOT_TYPE_TLSGD;
got_type <= GOT_TYPE_TPREL;
got_type = Got_type(got_type + 1))
if (gsym->has_got_offset(got_type))
{
unsigned int off = gsym->got_offset(got_type);
if (got_type == GOT_TYPE_TLSGD)
off += size / 8;
if (off == got_indx * (size / 8))
{
if (got_type == GOT_TYPE_TPREL)
return -tp_offset;
else
return -dtp_offset;
}
}
}
gold_unreachable();
}
// The selector for powerpc object files.
template<int size, bool big_endian>
class Target_selector_powerpc : public Target_selector
{
public:
Target_selector_powerpc()
: Target_selector(elfcpp::EM_NONE, size, big_endian,
PR gold/12934 * 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.
2011-06-29 01:12:31 +02:00
(size == 64
? (big_endian ? "elf64-powerpc" : "elf64-powerpcle")
: (big_endian ? "elf32-powerpc" : "elf32-powerpcle")),
(size == 64
? (big_endian ? "elf64ppc" : "elf64lppc")
: (big_endian ? "elf32ppc" : "elf32lppc")))
{ }
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
virtual Target*
do_recognize(Input_file*, off_t, int machine, int, int)
{
switch (size)
{
case 64:
if (machine != elfcpp::EM_PPC64)
return NULL;
break;
case 32:
if (machine != elfcpp::EM_PPC)
return NULL;
break;
default:
return NULL;
}
return this->instantiate_target();
}
* configure.ac (ENABLE_GOLD): Consider *-*-nacl* targets ELF. * 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
2012-05-02 23:37:24 +02:00
virtual Target*
do_instantiate_target()
{ return new Target_powerpc<size, big_endian>(); }
};
Target_selector_powerpc<32, true> target_selector_ppc32;
Target_selector_powerpc<32, false> target_selector_ppc32le;
Target_selector_powerpc<64, true> target_selector_ppc64;
Target_selector_powerpc<64, false> target_selector_ppc64le;
} // End anonymous namespace.