* object.h (Sized_relobj_file::emit_relocs): Delete.

(Sized_relobj_file::emit_relocs_reltype): Delete.
	* reloc.cc (Sized_relobj_file::do_relocate_sections): Call target
	relocate_relocs for --emit-relocs.
	(Sized_relobj_file::emit_relocs, emit_relocs_reltype): Delete.
	* output.h: Update comment.
	(Output_segment::first_section): New function.
	(Output_segment::first_section_load_address): Use first_section.
	* output.cc (Output_segment::first_section): New function extracted..
	(Output_segment::first_section_load_address): ..from here.  Delete.
	* target-reloc.h (relocate_for_relocatable): Rename to relocate_relocs.
	* target.h (Sized_target::relocate_for_relocatable): Likewise.
	* arm.cc (Target_arm::relocate_for_relocatable): Likewise, and
	adjust call to target.h function.
	* i386.cc (Target_i386): Likewise.
	* sparc.cc (Target_sparc): Likewise.
	* x86_64.cc (Target_x86_64): Likewise.
	* powerpc.cc (Target_powerpc): Likewise.
	(Target_powerpc::Scan::local, global): Handle R_POWERPC_TLS.  Ensure
	first tls section has section symbol for optimised local dynamic
	output relocs.
	(Target_powerpc::Relocate::relocate): Correct local dynamic value.
	(Target_powerpc::relocate_relocs): Adjust relocs emitted for
	optimised tls code.
	* testsuite/testfile.cc (Target_test::relocate_for_relocatable):
	Rename to relocate_relocs.  Update error message.
This commit is contained in:
Alan Modra 2012-09-05 00:34:20 +00:00
parent f54ae065b8
commit 7404fe1b8d
13 changed files with 325 additions and 235 deletions

View file

@ -1,3 +1,32 @@
2012-09-05 Alan Modra <amodra@gmail.com>
* object.h (Sized_relobj_file::emit_relocs): Delete.
(Sized_relobj_file::emit_relocs_reltype): Delete.
* reloc.cc (Sized_relobj_file::do_relocate_sections): Call target
relocate_relocs for --emit-relocs.
(Sized_relobj_file::emit_relocs, emit_relocs_reltype): Delete.
* output.h: Update comment.
(Output_segment::first_section): New function.
(Output_segment::first_section_load_address): Use first_section.
* output.cc (Output_segment::first_section): New function extracted..
(Output_segment::first_section_load_address): ..from here. Delete.
* target-reloc.h (relocate_for_relocatable): Rename to relocate_relocs.
* target.h (Sized_target::relocate_for_relocatable): Likewise.
* arm.cc (Target_arm::relocate_for_relocatable): Likewise, and
adjust call to target.h function.
* i386.cc (Target_i386): Likewise.
* sparc.cc (Target_sparc): Likewise.
* x86_64.cc (Target_x86_64): Likewise.
* powerpc.cc (Target_powerpc): Likewise.
(Target_powerpc::Scan::local, global): Handle R_POWERPC_TLS. Ensure
first tls section has section symbol for optimised local dynamic
output relocs.
(Target_powerpc::Relocate::relocate): Correct local dynamic value.
(Target_powerpc::relocate_relocs): Adjust relocs emitted for
optimised tls code.
* testsuite/testfile.cc (Target_test::relocate_for_relocatable):
Rename to relocate_relocs. Update error message.
2012-09-04 Andreas Schwab <schwab@linux-m68k.org>
* powerpc.cc (do_make_elf_object): Allow ET_EXEC files with

View file

@ -2286,20 +2286,20 @@ class Target_arm : public Sized_target<32, big_endian>
const unsigned char* plocal_symbols,
Relocatable_relocs*);
// Relocate a section during a relocatable link.
// Emit relocations for a section.
void
relocate_for_relocatable(const Relocate_info<32, big_endian>*,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
off_t offset_in_output_section,
const Relocatable_relocs*,
unsigned char* view,
Arm_address view_address,
section_size_type view_size,
unsigned char* reloc_view,
section_size_type reloc_view_size);
relocate_relocs(const Relocate_info<32, big_endian>*,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
off_t offset_in_output_section,
const Relocatable_relocs*,
unsigned char* view,
Arm_address view_address,
section_size_type view_size,
unsigned char* reloc_view,
section_size_type reloc_view_size);
// Perform target-specific processing in a relocatable link. This is
// only used if we use the relocation strategy RELOC_SPECIAL.
@ -9588,11 +9588,11 @@ Target_arm<big_endian>::scan_relocatable_relocs(
rr);
}
// Relocate a section during a relocatable link.
// Emit relocations for a section.
template<bool big_endian>
void
Target_arm<big_endian>::relocate_for_relocatable(
Target_arm<big_endian>::relocate_relocs(
const Relocate_info<32, big_endian>* relinfo,
unsigned int sh_type,
const unsigned char* prelocs,
@ -9608,7 +9608,7 @@ Target_arm<big_endian>::relocate_for_relocatable(
{
gold_assert(sh_type == elfcpp::SHT_REL);
gold::relocate_for_relocatable<32, big_endian, elfcpp::SHT_REL>(
gold::relocate_relocs<32, big_endian, elfcpp::SHT_REL>(
relinfo,
prelocs,
reloc_count,

View file

@ -407,20 +407,20 @@ class Target_i386 : public Sized_target<32, false>
const unsigned char* plocal_symbols,
Relocatable_relocs*);
// Relocate a section during a relocatable link.
// Emit relocations for a section.
void
relocate_for_relocatable(const Relocate_info<32, false>*,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
off_t offset_in_output_section,
const Relocatable_relocs*,
unsigned char* view,
elfcpp::Elf_types<32>::Elf_Addr view_address,
section_size_type view_size,
unsigned char* reloc_view,
section_size_type reloc_view_size);
relocate_relocs(const Relocate_info<32, false>*,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
off_t offset_in_output_section,
const Relocatable_relocs*,
unsigned char* view,
elfcpp::Elf_types<32>::Elf_Addr view_address,
section_size_type view_size,
unsigned char* reloc_view,
section_size_type reloc_view_size);
// Return a string used to fill a code section with nops.
std::string
@ -3602,10 +3602,10 @@ Target_i386::scan_relocatable_relocs(Symbol_table* symtab,
rr);
}
// Relocate a section during a relocatable link.
// Emit relocations for a section.
void
Target_i386::relocate_for_relocatable(
Target_i386::relocate_relocs(
const Relocate_info<32, false>* relinfo,
unsigned int sh_type,
const unsigned char* prelocs,
@ -3621,7 +3621,7 @@ Target_i386::relocate_for_relocatable(
{
gold_assert(sh_type == elfcpp::SHT_REL);
gold::relocate_for_relocatable<32, false, elfcpp::SHT_REL>(
gold::relocate_relocs<32, false, elfcpp::SHT_REL>(
relinfo,
prelocs,
reloc_count,

View file

@ -2499,27 +2499,6 @@ class Sized_relobj_file : public Sized_relobj<size, big_endian>
const Read_relocs_data::Relocs_list::iterator&,
Relocatable_relocs*);
// Emit the relocs for --emit-relocs.
void
emit_relocs(const Relocate_info<size, big_endian>*, unsigned int,
unsigned int sh_type, const unsigned char* prelocs,
size_t reloc_count, Output_section*, Address output_offset,
unsigned char* view, Address address,
section_size_type view_size,
unsigned char* reloc_view, section_size_type reloc_view_size);
// Emit the relocs for --emit-relocs, templatized on the type of the
// relocation section.
template<int sh_type>
void
emit_relocs_reltype(const Relocate_info<size, big_endian>*, unsigned int,
const unsigned char* prelocs, size_t reloc_count,
Output_section*, Address output_offset,
unsigned char* view, Address address,
section_size_type view_size,
unsigned char* reloc_view,
section_size_type reloc_view_size);
// Scan the input relocations for --incremental.
void
incremental_relocs_scan(const Read_relocs_data::Relocs_list::iterator&);

View file

@ -4613,10 +4613,10 @@ Output_segment::set_tls_offsets()
(*p)->set_tls_offset(this->vaddr_);
}
// Return the load address of the first section.
// Return the first section.
uint64_t
Output_segment::first_section_load_address() const
Output_section*
Output_segment::first_section() const
{
for (int i = 0; i < static_cast<int>(ORDER_MAX); ++i)
{
@ -4626,9 +4626,7 @@ Output_segment::first_section_load_address() const
++p)
{
if ((*p)->is_section())
return ((*p)->has_load_address()
? (*p)->load_address()
: (*p)->address());
return (*p)->output_section();
}
}
gold_unreachable();

View file

@ -2123,7 +2123,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
// Output_relocatable_relocs represents a relocation section in a
// relocatable link. The actual data is written out in the target
// hook relocate_for_relocatable. This just saves space for it.
// hook relocate_relocs. This just saves space for it.
template<int sh_type, int size, bool big_endian>
class Output_relocatable_relocs : public Output_section_data
@ -4406,9 +4406,17 @@ class Output_segment
bool
has_dynamic_reloc() const;
// Return the first section.
Output_section*
first_section() const;
// Return the address of the first section.
uint64_t
first_section_load_address() const;
first_section_load_address() const
{
const Output_section* os = this->first_section();
return os->has_load_address() ? os->load_address() : os->address();
}
// Return whether the addresses have been set already.
bool

View file

@ -261,20 +261,20 @@ class Target_powerpc : public Sized_target<size, big_endian>
const unsigned char* plocal_symbols,
Relocatable_relocs*);
// Relocate a section during a relocatable link.
// Emit relocations for a section.
void
relocate_for_relocatable(const Relocate_info<size, big_endian>*,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
off_t 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);
relocate_relocs(const Relocate_info<size, big_endian>*,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
off_t 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
@ -2294,6 +2294,7 @@ Target_powerpc<size, big_endian>::Scan::local(
case elfcpp::R_POWERPC_GNU_VTENTRY:
case elfcpp::R_PPC64_TOCSAVE:
case elfcpp::R_PPC_EMB_MRKREF:
case elfcpp::R_POWERPC_TLS:
break;
case elfcpp::R_PPC64_TOC:
@ -2485,6 +2486,12 @@ Target_powerpc<size, big_endian>::Scan::local(
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();
}
}
else
gold_unreachable();
@ -2573,6 +2580,7 @@ Target_powerpc<size, big_endian>::Scan::global(
case elfcpp::R_POWERPC_GNU_VTENTRY:
case elfcpp::R_PPC_LOCAL24PC:
case elfcpp::R_PPC_EMB_MRKREF:
case elfcpp::R_POWERPC_TLS:
break;
case elfcpp::R_PPC64_TOC:
@ -2817,6 +2825,12 @@ Target_powerpc<size, big_endian>::Scan::global(
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();
}
}
else
gold_unreachable();
@ -3201,7 +3215,7 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
insn = addis_3_2;
elfcpp::Swap<32, big_endian>::writeval(iview, insn);
r_type = elfcpp::R_POWERPC_TPREL16_HA;
value = relinfo->layout->tls_segment()->vaddr() + dtp_offset;
value = dtp_offset;
}
else
{
@ -3327,7 +3341,7 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
this->call_tls_get_addr_ = CALL_SKIP;
r_type = elfcpp::R_POWERPC_TPREL16_LO;
view += 2 * big_endian;
value = relinfo->layout->tls_segment()->vaddr() + dtp_offset;
value = dtp_offset;
}
}
else if (r_type == elfcpp::R_POWERPC_TLS)
@ -3883,7 +3897,7 @@ Target_powerpc<size, big_endian>::scan_relocatable_relocs(
rr);
}
// Relocate a section during a relocatable link.
// Emit relocations for a section.
// 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
@ -3891,7 +3905,7 @@ Target_powerpc<size, big_endian>::scan_relocatable_relocs(
template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::relocate_for_relocatable(
Target_powerpc<size, big_endian>::relocate_relocs(
const Relocate_info<size, big_endian>* relinfo,
unsigned int sh_type,
const unsigned char* prelocs,
@ -3926,7 +3940,7 @@ Target_powerpc<size, big_endian>::relocate_for_relocatable(
}
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);
@ -3936,25 +3950,35 @@ Target_powerpc<size, big_endian>::relocate_for_relocatable(
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();
const unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
const unsigned int r_type = elfcpp::elf_r_type<size>(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.
unsigned int new_symndx;
if (r_sym < local_count)
{
switch (strategy)
{
case Relocatable_relocs::RELOC_COPY:
case Relocatable_relocs::RELOC_SPECIAL:
if (r_sym == 0)
new_symndx = 0;
else
if (r_sym != 0)
{
new_symndx = object->symtab_index(r_sym);
gold_assert(new_symndx != -1U);
r_sym = object->symtab_index(r_sym);
gold_assert(r_sym != -1U);
}
break;
@ -3972,7 +3996,7 @@ Target_powerpc<size, big_endian>::relocate_for_relocatable(
Output_section* os = object->output_section(shndx);
gold_assert(os != NULL);
gold_assert(os->needs_symtab_index());
new_symndx = os->symtab_index();
r_sym = os->symtab_index();
}
break;
@ -3982,22 +4006,19 @@ Target_powerpc<size, big_endian>::relocate_for_relocatable(
}
else
{
const Symbol* gsym = object->global_symbol(r_sym);
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());
new_symndx = gsym->symtab_index();
r_sym = gsym->symtab_index();
}
// Get the new offset--the location in the output section where
// this relocation should be applied.
Address offset = reloc.get_r_offset();
Address new_offset;
if (static_cast<Address>(offset_in_output_section) != invalid_address)
new_offset = offset + offset_in_output_section;
offset += offset_in_output_section;
else
{
section_offset_type sot_offset =
@ -4006,34 +4027,25 @@ Target_powerpc<size, big_endian>::relocate_for_relocatable(
output_section->output_offset(object, relinfo->data_shndx,
sot_offset);
gold_assert(new_sot_offset != -1);
new_offset = new_sot_offset;
offset = new_sot_offset;
}
// 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.
// FIXME: Arrange to call this function for --emit-relocs too,
// so that we can make emitted relocs match edited TLS code.
if (0 && !parameters->options().relocatable())
if (!parameters->options().relocatable())
{
new_offset += view_address;
offset += view_address;
if (static_cast<Address>(offset_in_output_section) != invalid_address)
new_offset -= offset_in_output_section;
offset -= offset_in_output_section;
}
reloc_write.put_r_offset(new_offset);
reloc_write.put_r_info(elfcpp::elf_r_info<size>(new_symndx, r_type));
// Handle the reloc addend based on the strategy.
typename elfcpp::Elf_types<size>::Elf_Swxword addend;
addend = Reloc_types<elfcpp::SHT_RELA, size, big_endian>::
get_reloc_addend(&reloc);
if (strategy == Relocatable_relocs::RELOC_COPY)
;
else if (strategy == Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA)
{
const Symbol_value<size>* psymval = object->local_symbol(r_sym);
const Symbol_value<size>* psymval = object->local_symbol(orig_r_sym);
addend = psymval->value(object, addend);
}
else if (strategy == Relocatable_relocs::RELOC_SPECIAL)
@ -4044,8 +4056,136 @@ Target_powerpc<size, big_endian>::relocate_for_relocatable(
else
gold_unreachable();
Reloc_types<elfcpp::SHT_RELA, size, big_endian>::
set_reloc_addend(&reloc_write, addend);
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;
}

View file

@ -1014,9 +1014,14 @@ Sized_relobj_file<size, big_endian>::do_relocate_sections(
output_offset == invalid_address,
view, address, view_size, reloc_map);
if (parameters->options().emit_relocs())
this->emit_relocs(&relinfo, i, sh_type, prelocs, reloc_count,
os, output_offset, view, address, view_size,
(*pviews)[i].view, (*pviews)[i].view_size);
{
Relocatable_relocs* rr = this->relocatable_relocs(i);
target->relocate_relocs(&relinfo, sh_type, prelocs, reloc_count,
os, output_offset, rr,
view, address, view_size,
(*pviews)[i].view,
(*pviews)[i].view_size);
}
if (parameters->incremental())
this->incremental_relocs_write(&relinfo, sh_type, prelocs,
reloc_count, os, output_offset, of);
@ -1024,84 +1029,15 @@ Sized_relobj_file<size, big_endian>::do_relocate_sections(
else
{
Relocatable_relocs* rr = this->relocatable_relocs(i);
target->relocate_for_relocatable(&relinfo, sh_type, prelocs,
reloc_count, os, output_offset, rr,
view, address, view_size,
(*pviews)[i].view,
(*pviews)[i].view_size);
target->relocate_relocs(&relinfo, sh_type, prelocs, reloc_count,
os, output_offset, rr,
view, address, view_size,
(*pviews)[i].view,
(*pviews)[i].view_size);
}
}
}
// Emit the relocs for --emit-relocs.
template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::emit_relocs(
const Relocate_info<size, big_endian>* relinfo,
unsigned int i,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
typename elfcpp::Elf_types<size>::Elf_Addr offset_in_output_section,
unsigned char* view,
typename elfcpp::Elf_types<size>::Elf_Addr address,
section_size_type view_size,
unsigned char* reloc_view,
section_size_type reloc_view_size)
{
if (sh_type == elfcpp::SHT_REL)
this->emit_relocs_reltype<elfcpp::SHT_REL>(relinfo, i, prelocs,
reloc_count, output_section,
offset_in_output_section,
view, address, view_size,
reloc_view, reloc_view_size);
else
{
gold_assert(sh_type == elfcpp::SHT_RELA);
this->emit_relocs_reltype<elfcpp::SHT_RELA>(relinfo, i, prelocs,
reloc_count, output_section,
offset_in_output_section,
view, address, view_size,
reloc_view, reloc_view_size);
}
}
// Emit the relocs for --emit-relocs, templatized on the type of the
// relocation section.
template<int size, bool big_endian>
template<int sh_type>
void
Sized_relobj_file<size, big_endian>::emit_relocs_reltype(
const Relocate_info<size, big_endian>* relinfo,
unsigned int i,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
typename elfcpp::Elf_types<size>::Elf_Addr offset_in_output_section,
unsigned char* view,
typename elfcpp::Elf_types<size>::Elf_Addr address,
section_size_type view_size,
unsigned char* reloc_view,
section_size_type reloc_view_size)
{
const Relocatable_relocs* rr = this->relocatable_relocs(i);
relocate_for_relocatable<size, big_endian, sh_type>(
relinfo,
prelocs,
reloc_count,
output_section,
offset_in_output_section,
rr,
view,
address,
view_size,
reloc_view,
reloc_view_size);
}
// Write the incremental relocs.
template<int size, bool big_endian>

View file

@ -131,20 +131,21 @@ class Target_sparc : public Sized_target<size, big_endian>
const unsigned char* plocal_symbols,
Relocatable_relocs*);
// Relocate a section during a relocatable link.
// Emit relocations for a section.
void
relocate_for_relocatable(const Relocate_info<size, big_endian>*,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
off_t offset_in_output_section,
const Relocatable_relocs*,
unsigned char* view,
typename elfcpp::Elf_types<size>::Elf_Addr view_address,
section_size_type view_size,
unsigned char* reloc_view,
section_size_type reloc_view_size);
relocate_relocs(const Relocate_info<size, big_endian>*,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
off_t offset_in_output_section,
const Relocatable_relocs*,
unsigned char* view,
typename elfcpp::Elf_types<size>::Elf_Addr view_address,
section_size_type view_size,
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
@ -4197,11 +4198,11 @@ Target_sparc<size, big_endian>::scan_relocatable_relocs(
rr);
}
// Relocate a section during a relocatable link.
// Emit relocations for a section.
template<int size, bool big_endian>
void
Target_sparc<size, big_endian>::relocate_for_relocatable(
Target_sparc<size, big_endian>::relocate_relocs(
const Relocate_info<size, big_endian>* relinfo,
unsigned int sh_type,
const unsigned char* prelocs,
@ -4217,7 +4218,7 @@ Target_sparc<size, big_endian>::relocate_for_relocatable(
{
gold_assert(sh_type == elfcpp::SHT_RELA);
gold::relocate_for_relocatable<size, big_endian, elfcpp::SHT_RELA>(
gold::relocate_relocs<size, big_endian, elfcpp::SHT_RELA>(
relinfo,
prelocs,
reloc_count,

View file

@ -590,12 +590,12 @@ scan_relocatable_relocs(
}
}
// Relocate relocs during a relocatable link. This is a default
// definition which should work for most targets.
// Relocate relocs. Called for a relocatable link, and for --emit-relocs.
// This is a default definition which should work for most targets.
template<int size, bool big_endian, int sh_type>
void
relocate_for_relocatable(
relocate_relocs(
const Relocate_info<size, big_endian>* relinfo,
const unsigned char* prelocs,
size_t reloc_count,

View file

@ -801,23 +801,22 @@ class Sized_target : public Target
const unsigned char* plocal_symbols,
Relocatable_relocs*) = 0;
// Relocate a section during a relocatable link. The parameters are
// like relocate_section, with additional parameters for the view of
// the output reloc section.
// Emit relocations for a section during a relocatable link, and for
// --emit-relocs. The parameters are like relocate_section, with
// additional parameters for the view of the output reloc section.
virtual void
relocate_for_relocatable(const Relocate_info<size, big_endian>*,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
off_t offset_in_output_section,
const Relocatable_relocs*,
unsigned char* view,
typename elfcpp::Elf_types<size>::Elf_Addr
view_address,
section_size_type view_size,
unsigned char* reloc_view,
section_size_type reloc_view_size) = 0;
relocate_relocs(const Relocate_info<size, big_endian>*,
unsigned int sh_type,
const unsigned char* prelocs,
size_t reloc_count,
Output_section* output_section,
off_t offset_in_output_section,
const Relocatable_relocs*,
unsigned char* view,
typename elfcpp::Elf_types<size>::Elf_Addr view_address,
section_size_type view_size,
unsigned char* reloc_view,
section_size_type reloc_view_size) = 0;
// Perform target-specific processing in a relocatable link. This is
// only used if we use the relocation strategy RELOC_SPECIAL.

View file

@ -72,14 +72,14 @@ class Target_test : public Sized_target<size, big_endian>
{ ERROR("call to Target_test::scan_relocatable_relocs"); }
void
relocate_for_relocatable(const Relocate_info<size, big_endian>*,
unsigned int, const unsigned char*, size_t,
Output_section*, off_t, const Relocatable_relocs*,
unsigned char*,
typename elfcpp::Elf_types<size>::Elf_Addr,
section_size_type, unsigned char*,
section_size_type)
{ ERROR("call to Target_test::relocate_for_relocatable"); }
relocate_relocs(const Relocate_info<size, big_endian>*,
unsigned int, const unsigned char*, size_t,
Output_section*, off_t, const Relocatable_relocs*,
unsigned char*,
typename elfcpp::Elf_types<size>::Elf_Addr,
section_size_type, unsigned char*,
section_size_type)
{ ERROR("call to Target_test::relocate_relocs"); }
static const Target::Target_info test_target_info;
};

View file

@ -469,9 +469,9 @@ class Target_x86_64 : public Sized_target<size, false>
const unsigned char* plocal_symbols,
Relocatable_relocs*);
// Relocate a section during a relocatable link.
// Emit relocations for a section.
void
relocate_for_relocatable(
relocate_relocs(
const Relocate_info<size, false>*,
unsigned int sh_type,
const unsigned char* prelocs,
@ -4208,7 +4208,7 @@ Target_x86_64<size>::scan_relocatable_relocs(
template<int size>
void
Target_x86_64<size>::relocate_for_relocatable(
Target_x86_64<size>::relocate_relocs(
const Relocate_info<size, false>* relinfo,
unsigned int sh_type,
const unsigned char* prelocs,
@ -4224,7 +4224,7 @@ Target_x86_64<size>::relocate_for_relocatable(
{
gold_assert(sh_type == elfcpp::SHT_RELA);
gold::relocate_for_relocatable<size, false, elfcpp::SHT_RELA>(
gold::relocate_relocs<size, false, elfcpp::SHT_RELA>(
relinfo,
prelocs,
reloc_count,