This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[GOLD] Another Output_reloc function
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Date: Thu, 30 Aug 2012 11:05:08 +0930
- Subject: [GOLD] Another Output_reloc function
This is to support emitting R_POWERPC_RELATIVE dynamic relocs for
R_PPC64_TOC relocs on function descriptors. R_PPC64_TOC resolves to
an offset in the output .got section, and the reloc normally doesn't
have a symbol. OK?
* output.h (Output_reloc::Output_reloc <output section>): Add
is_relative param. Adjust calls.
(Output_reloc::add_output_section_relative): New functions.
* output.cc (Output_reloc::Output_reloc <output section>): Handle
is_relative.
(Output_reloc::symbol_value): Handle SECTION_CODE.
Index: gold/output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.137
diff -u -p -r1.137 output.h
--- gold/output.h 24 Aug 2012 18:35:34 -0000 1.137
+++ gold/output.h 29 Aug 2012 10:46:42 -0000
@@ -1046,11 +1046,11 @@ class Output_reloc<elfcpp::SHT_REL, dyna
// A reloc against the STT_SECTION symbol of an output section.
Output_reloc(Output_section* os, unsigned int type, Output_data* od,
- Address address);
+ Address address, bool is_relative);
Output_reloc(Output_section* os, unsigned int type,
- Sized_relobj<size, big_endian>* relobj,
- unsigned int shndx, Address address);
+ Sized_relobj<size, big_endian>* relobj, unsigned int shndx,
+ Address address, bool is_relative);
// An absolute relocation with no symbol.
@@ -1296,14 +1296,15 @@ class Output_reloc<elfcpp::SHT_RELA, dyn
// A reloc against the STT_SECTION symbol of an output section.
Output_reloc(Output_section* os, unsigned int type, Output_data* od,
- Address address, Addend addend)
- : rel_(os, type, od, address), addend_(addend)
+ Address address, Addend addend, bool is_relative)
+ : rel_(os, type, od, address, is_relative), addend_(addend)
{ }
Output_reloc(Output_section* os, unsigned int type,
Sized_relobj<size, big_endian>* relobj,
- unsigned int shndx, Address address, Addend addend)
- : rel_(os, type, relobj, shndx, address), addend_(addend)
+ unsigned int shndx, Address address, Addend addend,
+ bool is_relative)
+ : rel_(os, type, relobj, shndx, address, is_relative), addend_(addend)
{ }
// An absolute relocation with no symbol.
@@ -1745,13 +1746,13 @@ class Output_data_reloc<elfcpp::SHT_REL,
void
add_output_section(Output_section* os, unsigned int type,
Output_data* od, Address address)
- { this->add(od, Output_reloc_type(os, type, od, address)); }
+ { this->add(od, Output_reloc_type(os, type, od, address, false)); }
void
add_output_section(Output_section* os, unsigned int type, Output_data* od,
Sized_relobj<size, big_endian>* relobj,
unsigned int shndx, Address address)
- { this->add(od, Output_reloc_type(os, type, relobj, shndx, address)); }
+ { this->add(od, Output_reloc_type(os, type, relobj, shndx, address, false)); }
void
add_output_section_generic(Output_section* os, unsigned int type,
@@ -1760,7 +1761,8 @@ class Output_data_reloc<elfcpp::SHT_REL,
{
gold_assert(addend == 0);
this->add(od, Output_reloc_type(os, type, od,
- convert_types<Address, uint64_t>(address)));
+ convert_types<Address, uint64_t>(address),
+ false));
}
void
@@ -1773,9 +1775,24 @@ class Output_data_reloc<elfcpp::SHT_REL,
Sized_relobj<size, big_endian>* sized_relobj =
static_cast<Sized_relobj<size, big_endian>*>(relobj);
this->add(od, Output_reloc_type(os, type, sized_relobj, shndx,
- convert_types<Address, uint64_t>(address)));
+ convert_types<Address, uint64_t>(address),
+ false));
}
+ // As above, but the reloc TYPE is relative
+
+ void
+ add_output_section_relative(Output_section* os, unsigned int type,
+ Output_data* od, Address address)
+ { this->add(od, Output_reloc_type(os, type, od, address, true)); }
+
+ void
+ add_output_section_relative(Output_section* os, unsigned int type,
+ Output_data* od,
+ Sized_relobj<size, big_endian>* relobj,
+ unsigned int shndx, Address address)
+ { this->add(od, Output_reloc_type(os, type, relobj, shndx, address, true)); }
+
// Add an absolute relocation.
void
@@ -2021,14 +2038,14 @@ class Output_data_reloc<elfcpp::SHT_RELA
void
add_output_section(Output_section* os, unsigned int type, Output_data* od,
Address address, Addend addend)
- { this->add(od, Output_reloc_type(os, type, od, address, addend)); }
+ { this->add(od, Output_reloc_type(os, type, od, address, addend, false)); }
void
add_output_section(Output_section* os, unsigned int type, Output_data* od,
Sized_relobj<size, big_endian>* relobj,
unsigned int shndx, Address address, Addend addend)
{ this->add(od, Output_reloc_type(os, type, relobj, shndx, address,
- addend)); }
+ addend, false)); }
void
add_output_section_generic(Output_section* os, unsigned int type,
@@ -2037,7 +2054,8 @@ class Output_data_reloc<elfcpp::SHT_RELA
{
this->add(od, Output_reloc_type(os, type, od,
convert_types<Address, uint64_t>(address),
- convert_types<Addend, uint64_t>(addend)));
+ convert_types<Addend, uint64_t>(addend),
+ false));
}
void
@@ -2050,7 +2068,26 @@ class Output_data_reloc<elfcpp::SHT_RELA
static_cast<Sized_relobj<size, big_endian>*>(relobj);
this->add(od, Output_reloc_type(os, type, sized_relobj, shndx,
convert_types<Address, uint64_t>(address),
- convert_types<Addend, uint64_t>(addend)));
+ convert_types<Addend, uint64_t>(addend),
+ false));
+ }
+
+ // As above, but the reloc TYPE is relative
+
+ void
+ add_output_section_relative(Output_section* os, unsigned int type,
+ Output_data* od, Address address, Addend addend)
+ { this->add(od, Output_reloc_type(os, type, od, address, addend, true)); }
+
+ void
+ add_output_section_relative(Output_section* os, unsigned int type,
+ Output_data* od,
+ Sized_relobj<size, big_endian>* relobj,
+ unsigned int shndx, Address address,
+ Addend addend)
+ {
+ this->add(od, Output_reloc_type(os, type, relobj, shndx,
+ address, addend, true));
}
// Add an absolute relocation.
Index: gold/output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.169
diff -u -p -r1.169 output.cc
--- gold/output.cc 24 Aug 2012 18:35:34 -0000 1.169
+++ gold/output.cc 29 Aug 2012 10:46:42 -0000
@@ -811,9 +811,10 @@ Output_reloc<elfcpp::SHT_REL, dynamic, s
Output_section* os,
unsigned int type,
Output_data* od,
- Address address)
+ Address address,
+ bool is_relative)
: address_(address), local_sym_index_(SECTION_CODE), type_(type),
- is_relative_(false), is_symbolless_(false),
+ is_relative_(is_relative), is_symbolless_(is_relative),
is_section_symbol_(true), use_plt_offset_(false), shndx_(INVALID_CODE)
{
// this->type_ is a bitfield; make sure TYPE fits.
@@ -832,9 +833,10 @@ Output_reloc<elfcpp::SHT_REL, dynamic, s
unsigned int type,
Sized_relobj<size, big_endian>* relobj,
unsigned int shndx,
- Address address)
+ Address address,
+ bool is_relative)
: address_(address), local_sym_index_(SECTION_CODE), type_(type),
- is_relative_(false), is_symbolless_(false),
+ is_relative_(is_relative), is_symbolless_(is_relative),
is_section_symbol_(true), use_plt_offset_(false), shndx_(shndx)
{
gold_assert(shndx != INVALID_CODE);
@@ -1134,6 +1136,11 @@ Output_reloc<elfcpp::SHT_REL, dynamic, s
else
return sym->value() + addend;
}
+ if (this->local_sym_index_ == SECTION_CODE)
+ {
+ gold_assert(!this->use_plt_offset_);
+ return this->u1_.os->address() + addend;
+ }
gold_assert(this->local_sym_index_ != SECTION_CODE
&& this->local_sym_index_ != TARGET_CODE
&& this->local_sym_index_ != INVALID_CODE
--
Alan Modra
Australia Development Lab, IBM