aboutsummaryrefslogtreecommitdiff
path: root/gold/output.h
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2010-01-08 19:33:18 +0000
committerIan Lance Taylor <ian@airs.com>2010-01-08 19:33:18 +0000
commite291e7b9c9cd9e432fdcc63922f2529647f5b930 (patch)
treedf4d976076d4d37f7b062a60f9f6bcb47b7f0ddb /gold/output.h
parentdd35de74344bc1dad410ed21fedd14671ab57aff (diff)
downloadgdb-e291e7b9c9cd9e432fdcc63922f2529647f5b930.zip
gdb-e291e7b9c9cd9e432fdcc63922f2529647f5b930.tar.gz
gdb-e291e7b9c9cd9e432fdcc63922f2529647f5b930.tar.bz2
PR 10287
PR 11063 * i386.cc (class Target_i386): Change return type of plt_section to be non-const. (class Output_data_plt_i386): Add tls_desc_rel_ field. (Output_data_plt_i386::Output_data_plt_i386): Initialize tls_desc_rel_ field. (Output_data_plt_i386::rel_tls_desc): New function. (Target_i386::rel_tls_desc_section): New function. (Target_i386::Scan::local): Rewrite R_386_TLS_GOTDESC handling. (Target_i386::Scan::global): For R_386_TLS_GOTDESC put R_386_TLS_DESC reloc in rel_tls_desc_section. * x86_64.cc (class Target_x86_64): Add tlsdesc_reloc_info_ field. Define struct Tlsdesc_info. (Target_x86_64::Target_x86_64): Initialize tlsdesc_reloc_info_. (Target_x86_64::do_reloc_symbol_index): New function. (Target_x86_64::add_tlsdesc_info): New function. (class Output_data_plt_x86_64): Add tlsdesc_rel_ field. (Output_data_plt_x86_64::Output_data_plt_x86_64): Initialize tlsdesc_rel_ field. (Output_data_plt_x86_64::rela_plt): Rename from rel_plt. Change all callers. (Output_data_plt_x86_64::rela_tlsdesc): New function. (Target_x86_64::rela_tlsdesc_section): New function. (Target_x86_64::Scan::local): Rewrite R_X86_64_GOTPC32_TLSDESC handling. (Target_x86_64::Scan::global): For R_X86_64_GOTPC32_TLSDESC put (Target_x86_64::do_reloc_addend): New function. R_X86_64_TLSDESC reloc in rela_tlsdesc_section. * output.h (class Output_reloc) [SHT_REL]: Add new constructor declarations. Define TARGET_CODE. Add arg field to u1_ union. (Output_reloc::type): New function. (Output_reloc::is_local_section_symbol): Check for TARGET_CODE. (Output_reloc::is_target_specific): New function. (Output_reloc::target_arg): New function. (class Output_reloc) [SHT_RELA]: Add four new constructors for absolute relocs and target specific relocs. (class Output_data_reloc) [SHT_REL]: Add add_absolute and add_target_specific. (class Output_data_reloc) [SHT_RELA]: Likewise. * output.cc (Output_reloc::Output_reloc): Add four new versions for absolute relocs and target specific relocs. (Output_reloc::set_needs_dynsym_index): Add TARGET_CODE case. (Output_reloc::get_symbol_index): Likewise. (Output_reloc::local_section_offset): Check that local_sym_index_ is not TARGET_CODE or 0. (Output_reloc::symbol_value): Likewise. (Output_reloc::write) [SHT_RELA]: Call target for target specific reloc. * target.h (class Target): Add reloc_symbol_index and reloc_addend functions. Add do_reloc_symbol_index and do_reloc_addend virtual functions. * layout.cc (add_target_dynamic_tags): Use output section for DT_PLTRELSZ and DT_JMPREL.
Diffstat (limited to 'gold/output.h')
-rw-r--r--gold/output.h143
1 files changed, 135 insertions, 8 deletions
diff --git a/gold/output.h b/gold/output.h
index 796575a..7a35652 100644
--- a/gold/output.h
+++ b/gold/output.h
@@ -1057,7 +1057,30 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
Sized_relobj<size, big_endian>* relobj,
unsigned int shndx, Address address);
- // Return TRUE if this is a RELATIVE relocation.
+ // An absolute relocation with no symbol.
+
+ Output_reloc(unsigned int type, Output_data* od, Address address);
+
+ Output_reloc(unsigned int type, Sized_relobj<size, big_endian>* relobj,
+ unsigned int shndx, Address address);
+
+ // A target specific relocation. The target will be called to get
+ // the symbol index, passing ARG. The type and offset will be set
+ // as for other relocation types.
+
+ Output_reloc(unsigned int type, void* arg, Output_data* od,
+ Address address);
+
+ Output_reloc(unsigned int type, void* arg,
+ Sized_relobj<size, big_endian>* relobj,
+ unsigned int shndx, Address address);
+
+ // Return the reloc type.
+ unsigned int
+ type() const
+ { return this->type_; }
+
+ // Return whether this is a RELATIVE relocation.
bool
is_relative() const
{ return this->is_relative_; }
@@ -1069,9 +1092,24 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
return (this->local_sym_index_ != GSYM_CODE
&& this->local_sym_index_ != SECTION_CODE
&& this->local_sym_index_ != INVALID_CODE
+ && this->local_sym_index_ != TARGET_CODE
&& this->is_section_symbol_);
}
+ // Return whether this is a target specific relocation.
+ bool
+ is_target_specific() const
+ { return this->local_sym_index_ == TARGET_CODE; }
+
+ // Return the argument to pass to the target for a target specific
+ // relocation.
+ void*
+ target_arg() const
+ {
+ gold_assert(this->local_sym_index_ == TARGET_CODE);
+ return this->u1_.arg;
+ }
+
// For a local section symbol, return the offset of the input
// section within the output section. ADDEND is the addend being
// applied to the input section.
@@ -1124,8 +1162,10 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
GSYM_CODE = -1U,
// Output section.
SECTION_CODE = -2U,
+ // Target specific.
+ TARGET_CODE = -3U,
// Invalid uninitialized entry.
- INVALID_CODE = -3U
+ INVALID_CODE = -4U
};
union
@@ -1143,6 +1183,9 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
// For a relocation against an output section
// (this->local_sym_index_ == SECTION_CODE), the output section.
Output_section* os;
+ // For a target specific relocation, an argument to pass to the
+ // target.
+ void* arg;
} u1_;
union
{
@@ -1157,11 +1200,12 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
// The address offset within the input section or the Output_data.
Address address_;
// This is GSYM_CODE for a global symbol, or SECTION_CODE for a
- // relocation against an output section, or INVALID_CODE for an
- // uninitialized value. Otherwise, for a local symbol
- // (this->is_section_symbol_ is false), the local symbol index. For
- // a local section symbol (this->is_section_symbol_ is true), the
- // section index in the input file.
+ // relocation against an output section, or TARGET_CODE for a target
+ // specific relocation, or INVALID_CODE for an uninitialized value.
+ // Otherwise, for a local symbol (this->is_section_symbol_ is
+ // false), the local symbol index. For a local section symbol
+ // (this->is_section_symbol_ is true), the section index in the
+ // input file.
unsigned int local_sym_index_;
// The reloc type--a processor specific code.
unsigned int type_ : 30;
@@ -1237,7 +1281,34 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
: rel_(os, type, relobj, shndx, address), addend_(addend)
{ }
- // Return TRUE if this is a RELATIVE relocation.
+ // An absolute relocation with no symbol.
+
+ Output_reloc(unsigned int type, Output_data* od, Address address,
+ Addend addend)
+ : rel_(type, od, address), addend_(addend)
+ { }
+
+ Output_reloc(unsigned int type, Sized_relobj<size, big_endian>* relobj,
+ unsigned int shndx, Address address, Addend addend)
+ : rel_(type, relobj, shndx, address), addend_(addend)
+ { }
+
+ // A target specific relocation. The target will be called to get
+ // the symbol index and the addend, passing ARG. The type and
+ // offset will be set as for other relocation types.
+
+ Output_reloc(unsigned int type, void* arg, Output_data* od,
+ Address address, Addend addend)
+ : rel_(type, arg, od, address), addend_(addend)
+ { }
+
+ Output_reloc(unsigned int type, void* arg,
+ Sized_relobj<size, big_endian>* relobj,
+ unsigned int shndx, Address address, Addend addend)
+ : rel_(type, arg, relobj, shndx, address), addend_(addend)
+ { }
+
+ // Return whether this is a RELATIVE relocation.
bool
is_relative() const
{ return this->rel_.is_relative(); }
@@ -1519,6 +1590,32 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
Sized_relobj<size, big_endian>* relobj,
unsigned int shndx, Address address)
{ this->add(od, Output_reloc_type(os, type, relobj, shndx, address)); }
+
+ // Add an absolute relocation.
+
+ void
+ add_absolute(unsigned int type, Output_data* od, Address address)
+ { this->add(od, Output_reloc_type(type, od, address)); }
+
+ void
+ add_absolute(unsigned int type, Output_data* od,
+ Sized_relobj<size, big_endian>* relobj,
+ unsigned int shndx, Address address)
+ { this->add(od, Output_reloc_type(type, relobj, shndx, address)); }
+
+ // Add a target specific relocation. A target which calls this must
+ // define the reloc_symbol_index and reloc_addend virtual functions.
+
+ void
+ add_target_specific(unsigned int type, void* arg, Output_data* od,
+ Address address)
+ { this->add(od, Output_reloc_type(type, arg, od, address)); }
+
+ void
+ add_target_specific(unsigned int type, void* arg, Output_data* od,
+ Sized_relobj<size, big_endian>* relobj,
+ unsigned int shndx, Address address)
+ { this->add(od, Output_reloc_type(type, arg, relobj, shndx, address)); }
};
// The SHT_RELA version of Output_data_reloc.
@@ -1651,6 +1748,36 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
unsigned int shndx, Address address, Addend addend)
{ this->add(os, Output_reloc_type(os, type, relobj, shndx, address,
addend)); }
+
+ // Add an absolute relocation.
+
+ void
+ add_absolute(unsigned int type, Output_data* od, Address address,
+ Addend addend)
+ { this->add(od, Output_reloc_type(type, od, address, addend)); }
+
+ void
+ add_absolute(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(type, relobj, shndx, address, addend)); }
+
+ // Add a target specific relocation. A target which calls this must
+ // define the reloc_symbol_index and reloc_addend virtual functions.
+
+ void
+ add_target_specific(unsigned int type, void* arg, Output_data* od,
+ Address address, Addend addend)
+ { this->add(od, Output_reloc_type(type, arg, od, address, addend)); }
+
+ void
+ add_target_specific(unsigned int type, void* arg, Output_data* od,
+ Sized_relobj<size, big_endian>* relobj,
+ unsigned int shndx, Address address, Addend addend)
+ {
+ this->add(od, Output_reloc_type(type, arg, relobj, shndx, address,
+ addend));
+ }
};
// Output_relocatable_relocs represents a relocation section in a