* [GOLD] Adjusting --emit-relocs output
@ 2012-09-01 4:26 Alan Modra
2012-09-04 19:55 ` Ian Lance Taylor
0 siblings, 1 reply; 3+ messages in thread
From: Alan Modra @ 2012-09-01 4:26 UTC (permalink / raw)
To: binutils
This patch arranges to call the target relocate_for_relocatable (which
I rename to relocate_relocs) for --emit-relocs. The idea being to
adjust relocs for edited code so that -emit-relocs gives you
relocations that make sense. Unless I'm missing something, the current
Sized_relobj_file::emit_relocs does exactly the same thing as
gold::relocate_for_relocatable with only a minor difference in where
Relocatable_relocs info is found, and all target
relocate_for_relocatable functions except powerpc currently just call
gold::relocate_for_relocatable. OK to apply?
gold/
* 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.
gold/testsuite/
* testfile.cc (Target_test::relocate_for_relocatable): Rename
to relocate_relocs. Update error message.
Index: gold/object.h
===================================================================
RCS file: /cvs/src/src/gold/object.h,v
retrieving revision 1.118
diff -u -p -r1.118 object.h
--- gold/object.h 11 Aug 2012 04:41:27 -0000 1.118
+++ gold/object.h 1 Sep 2012 03:19:35 -0000
@@ -2499,27 +2499,6 @@ class Sized_relobj_file : public Sized_r
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&);
Index: gold/reloc.cc
===================================================================
RCS file: /cvs/src/src/gold/reloc.cc,v
retrieving revision 1.68
diff -u -p -r1.68 reloc.cc
--- gold/reloc.cc 25 Jun 2011 00:40:56 -0000 1.68
+++ gold/reloc.cc 1 Sep 2012 03:19:36 -0000
@@ -1014,9 +1014,14 @@ Sized_relobj_file<size, big_endian>::do_
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_
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>
Index: gold/output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.138
diff -u -p -r1.138 output.h
--- gold/output.h 30 Aug 2012 05:54:59 -0000 1.138
+++ gold/output.h 1 Sep 2012 03:19:36 -0000
@@ -2123,7 +2123,7 @@ class Output_data_reloc<elfcpp::SHT_RELA
// 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
Index: gold/output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.170
diff -u -p -r1.170 output.cc
--- gold/output.cc 30 Aug 2012 05:54:59 -0000 1.170
+++ gold/output.cc 1 Sep 2012 03:19:36 -0000
@@ -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_addre
++p)
{
if ((*p)->is_section())
- return ((*p)->has_load_address()
- ? (*p)->load_address()
- : (*p)->address());
+ return static_cast<Output_section*>(*p);
}
}
gold_unreachable();
Index: gold/target-reloc.h
===================================================================
RCS file: /cvs/src/src/gold/target-reloc.h,v
retrieving revision 1.52
diff -u -p -r1.52 target-reloc.h
--- gold/target-reloc.h 15 Dec 2011 23:29:24 -0000 1.52
+++ gold/target-reloc.h 1 Sep 2012 03:19:36 -0000
@@ -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,
Index: gold/target.h
===================================================================
RCS file: /cvs/src/src/gold/target.h,v
retrieving revision 1.67
diff -u -p -r1.67 target.h
--- gold/target.h 14 Aug 2012 03:39:03 -0000 1.67
+++ gold/target.h 1 Sep 2012 03:19:36 -0000
@@ -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.
- 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;
+ // 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_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.
Index: gold/arm.cc
===================================================================
RCS file: /cvs/src/src/gold/arm.cc,v
retrieving revision 1.152
diff -u -p -r1.152 arm.cc
--- gold/arm.cc 11 Jul 2012 14:18:39 -0000 1.152
+++ gold/arm.cc 1 Sep 2012 03:19:35 -0000
@@ -2286,20 +2286,20 @@ class Target_arm : public Sized_target<3
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
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_rel
{
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,
Index: gold/i386.cc
===================================================================
RCS file: /cvs/src/src/gold/i386.cc,v
retrieving revision 1.145
diff -u -p -r1.145 i386.cc
--- gold/i386.cc 2 May 2012 21:37:23 -0000 1.145
+++ gold/i386.cc 1 Sep 2012 03:19:35 -0000
@@ -407,20 +407,20 @@ class Target_i386 : public Sized_target<
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(Sym
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,
Index: gold/powerpc.cc
===================================================================
RCS file: /cvs/src/src/gold/powerpc.cc,v
retrieving revision 1.51
diff -u -p -r1.51 powerpc.cc
--- gold/powerpc.cc 31 Aug 2012 01:09:52 -0000 1.51
+++ gold/powerpc.cc 1 Sep 2012 03:19:36 -0000
@@ -261,20 +261,20 @@ class Target_powerpc : public Sized_targ
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
@@ -2291,6 +2291,7 @@ Target_powerpc<size, big_endian>::Scan::
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:
@@ -2482,6 +2483,12 @@ Target_powerpc<size, big_endian>::Scan::
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();
@@ -2570,6 +2577,7 @@ Target_powerpc<size, big_endian>::Scan::
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:
@@ -2814,6 +2822,12 @@ Target_powerpc<size, big_endian>::Scan::
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();
@@ -3198,7 +3212,7 @@ Target_powerpc<size, big_endian>::Reloca
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
{
@@ -3324,7 +3338,7 @@ Target_powerpc<size, big_endian>::Reloca
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)
@@ -3880,7 +3894,7 @@ Target_powerpc<size, big_endian>::scan_r
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
@@ -3888,7 +3902,7 @@ Target_powerpc<size, big_endian>::scan_r
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,
@@ -3923,7 +3937,7 @@ Target_powerpc<size, big_endian>::reloca
}
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);
@@ -3933,25 +3947,35 @@ Target_powerpc<size, big_endian>::reloca
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;
@@ -3969,7 +3993,7 @@ Target_powerpc<size, big_endian>::reloca
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;
@@ -3979,22 +4003,19 @@ Target_powerpc<size, big_endian>::reloca
}
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 =
@@ -4003,34 +4024,25 @@ Target_powerpc<size, big_endian>::reloca
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)
@@ -4041,8 +4053,136 @@ Target_powerpc<size, big_endian>::reloca
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;
+ 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)
+ {
+ 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;
}
Index: gold/sparc.cc
===================================================================
RCS file: /cvs/src/src/gold/sparc.cc,v
retrieving revision 1.58
diff -u -p -r1.58 sparc.cc
--- gold/sparc.cc 2 May 2012 21:37:23 -0000 1.58
+++ gold/sparc.cc 1 Sep 2012 03:19:36 -0000
@@ -131,20 +131,21 @@ class Target_sparc : public Sized_target
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_rel
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
{
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,
Index: gold/x86_64.cc
===================================================================
RCS file: /cvs/src/src/gold/x86_64.cc,v
retrieving revision 1.154
diff -u -p -r1.154 x86_64.cc
--- gold/x86_64.cc 15 Aug 2012 04:03:54 -0000 1.154
+++ gold/x86_64.cc 1 Sep 2012 03:19:36 -0000
@@ -469,9 +469,9 @@ class Target_x86_64 : public Sized_targe
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_re
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_reloca
{
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,
Index: gold/testsuite/testfile.cc
===================================================================
RCS file: /cvs/src/src/gold/testsuite/testfile.cc,v
retrieving revision 1.22
diff -u -p -r1.22 testfile.cc
--- gold/testsuite/testfile.cc 2 May 2012 21:37:24 -0000 1.22
+++ gold/testsuite/testfile.cc 1 Sep 2012 03:19:36 -0000
@@ -72,14 +72,14 @@ class Target_test : public Sized_target<
{ 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;
};
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [GOLD] Adjusting --emit-relocs output
2012-09-01 4:26 [GOLD] Adjusting --emit-relocs output Alan Modra
@ 2012-09-04 19:55 ` Ian Lance Taylor
2012-09-05 0:36 ` Alan Modra
0 siblings, 1 reply; 3+ messages in thread
From: Ian Lance Taylor @ 2012-09-04 19:55 UTC (permalink / raw)
To: binutils
On Fri, Aug 31, 2012 at 9:25 PM, Alan Modra <amodra@gmail.com> wrote:
>
> gold/
> * 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.
> gold/testsuite/
> * testfile.cc (Target_test::relocate_for_relocatable): Rename
> to relocate_relocs. Update error message.
> @@ -4626,9 +4626,7 @@ Output_segment::first_section_load_addre
> ++p)
> {
> if ((*p)->is_section())
> - return ((*p)->has_load_address()
> - ? (*p)->load_address()
> - : (*p)->address());
> + return static_cast<Output_section*>(*p);
Don't use a static_cast here. Instead, return (*p)->output_section().
That may require you to change the return type to be a const pointer.
And that will give you trouble elsewhere. You may need two versions
of this function: one a const member function and one not.
OK with that change.
Thanks.
Ian
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [GOLD] Adjusting --emit-relocs output
2012-09-04 19:55 ` Ian Lance Taylor
@ 2012-09-05 0:36 ` Alan Modra
0 siblings, 0 replies; 3+ messages in thread
From: Alan Modra @ 2012-09-05 0:36 UTC (permalink / raw)
To: Ian Lance Taylor; +Cc: binutils
On Tue, Sep 04, 2012 at 12:55:22PM -0700, Ian Lance Taylor wrote:
> > @@ -4626,9 +4626,7 @@ Output_segment::first_section_load_addre
> > ++p)
> > {
> > if ((*p)->is_section())
> > - return ((*p)->has_load_address()
> > - ? (*p)->load_address()
> > - : (*p)->address());
> > + return static_cast<Output_section*>(*p);
>
> Don't use a static_cast here. Instead, return (*p)->output_section().
> That may require you to change the return type to be a const pointer.
> And that will give you trouble elsewhere. You may need two versions
> of this function: one a const member function and one not.
>
> OK with that change.
It turned out OK to return a non-const pointer, so I went with that.
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-09-05 0:36 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-01 4:26 [GOLD] Adjusting --emit-relocs output Alan Modra
2012-09-04 19:55 ` Ian Lance Taylor
2012-09-05 0:36 ` Alan Modra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).