aboutsummaryrefslogtreecommitdiff
path: root/gold/sparc.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2009-03-17 07:19:10 +0000
committerIan Lance Taylor <ian@airs.com>2009-03-17 07:19:10 +0000
commit9efe6174dc55b401321d1b53cdd04888e470b4c2 (patch)
tree08e85c850522144a5948a43eb53ac277e5493e27 /gold/sparc.cc
parent8c50070107224cdda510640738eca333f67409ee (diff)
downloadgdb-9efe6174dc55b401321d1b53cdd04888e470b4c2.zip
gdb-9efe6174dc55b401321d1b53cdd04888e470b4c2.tar.gz
gdb-9efe6174dc55b401321d1b53cdd04888e470b4c2.tar.bz2
* sparc.cc (class Target_sparc): Add has_got_section.
(Target_sparc::Scan::global): If we see _GLOBAL_OFFSET_TABLE_, make sure we have a GOT section. * sparc.cc (optimize_tls_reloc): Recognize R_SPARC_TLS_IE_ADD. (Target_sparc::Scan::local): Likewise. (Target_sparc::Scan::global): Likewise. (Target_sparc::Relocate::relocate): Likewise. (Target_sparc::Relocate::relocate_tls): Likewise.
Diffstat (limited to 'gold/sparc.cc')
-rw-r--r--gold/sparc.cc28
1 files changed, 26 insertions, 2 deletions
diff --git a/gold/sparc.cc b/gold/sparc.cc
index 794cab9..41aa7cd 100644
--- a/gold/sparc.cc
+++ b/gold/sparc.cc
@@ -155,6 +155,11 @@ class Target_sparc : public Sized_target<size, big_endian>
return strcmp(sym->name(), "___tls_get_addr") == 0;
}
+ // Return whether there is a GOT section.
+ bool
+ has_got_section() const
+ { return this->got_ != NULL; }
+
// Return the size of the GOT section.
section_size_type
got_size()
@@ -1455,6 +1460,7 @@ optimize_tls_reloc(bool is_final, int r_type)
case elfcpp::R_SPARC_TLS_IE_LO10:
case elfcpp::R_SPARC_TLS_IE_LD:
case elfcpp::R_SPARC_TLS_IE_LDX:
+ case elfcpp::R_SPARC_TLS_IE_ADD:
// These are Initial-Exec relocs which get the thread offset
// from the GOT. If we know that we are linking against the
// local symbol, we can switch to Local-Exec, which links the
@@ -1744,6 +1750,7 @@ Target_sparc<size, big_endian>::Scan::local(
case elfcpp::R_SPARC_TLS_IE_LO10:
case elfcpp::R_SPARC_TLS_IE_LD:
case elfcpp::R_SPARC_TLS_IE_LDX:
+ case elfcpp::R_SPARC_TLS_IE_ADD:
case elfcpp::R_SPARC_TLS_LE_HIX22: // Local-exec
case elfcpp::R_SPARC_TLS_LE_LOX10:
{
@@ -1810,6 +1817,7 @@ Target_sparc<size, big_endian>::Scan::local(
case elfcpp::R_SPARC_TLS_IE_LO10:
case elfcpp::R_SPARC_TLS_IE_LD:
case elfcpp::R_SPARC_TLS_IE_LDX:
+ case elfcpp::R_SPARC_TLS_IE_ADD:
layout->set_has_static_tls();
if (optimized_type == tls::TLSOPT_NONE)
{
@@ -1907,6 +1915,13 @@ Target_sparc<size, big_endian>::Scan::global(
{
unsigned int orig_r_type = r_type;
+ // A reference to _GLOBAL_OFFSET_TABLE_ implies that we need a got
+ // section. We check here to avoid creating a dynamic reloc against
+ // _GLOBAL_OFFSET_TABLE_.
+ if (!target->has_got_section()
+ && strcmp(gsym->name(), "_GLOBAL_OFFSET_TABLE_") == 0)
+ target->got_section(symtab, layout);
+
r_type &= 0xff;
switch (r_type)
{
@@ -2105,6 +2120,7 @@ Target_sparc<size, big_endian>::Scan::global(
case elfcpp::R_SPARC_TLS_IE_LO10:
case elfcpp::R_SPARC_TLS_IE_LD:
case elfcpp::R_SPARC_TLS_IE_LDX:
+ case elfcpp::R_SPARC_TLS_IE_ADD:
{
const bool is_final = gsym->final_value_is_known();
const tls::Tls_optimization optimized_type
@@ -2187,6 +2203,7 @@ Target_sparc<size, big_endian>::Scan::global(
case elfcpp::R_SPARC_TLS_IE_LO10:
case elfcpp::R_SPARC_TLS_IE_LD:
case elfcpp::R_SPARC_TLS_IE_LDX:
+ case elfcpp::R_SPARC_TLS_IE_ADD:
layout->set_has_static_tls();
if (optimized_type == tls::TLSOPT_NONE)
{
@@ -2460,8 +2477,8 @@ Target_sparc<size, big_endian>::Relocate::relocate(
case elfcpp::R_SPARC_32:
if (!parameters->options().output_is_position_independent())
- Relocate_functions<size, big_endian>::rela32(view, object,
- psymval, addend);
+ Relocate_functions<size, big_endian>::rela32(view, object,
+ psymval, addend);
break;
case elfcpp::R_SPARC_DISP8:
@@ -2670,6 +2687,7 @@ Target_sparc<size, big_endian>::Relocate::relocate(
case elfcpp::R_SPARC_TLS_IE_LO10:
case elfcpp::R_SPARC_TLS_IE_LD:
case elfcpp::R_SPARC_TLS_IE_LDX:
+ case elfcpp::R_SPARC_TLS_IE_ADD:
case elfcpp::R_SPARC_TLS_LE_HIX22:
case elfcpp::R_SPARC_TLS_LE_LOX10:
this->relocate_tls(relinfo, target, relnum, rela,
@@ -3049,6 +3067,12 @@ Target_sparc<size, big_endian>::Relocate::relocate_tls(
r_type);
break;
+ case elfcpp::R_SPARC_TLS_IE_ADD:
+ // This seems to be mainly so that we can find the addition
+ // instruction if there is one. There doesn't seem to be any
+ // actual relocation to apply.
+ break;
+
case elfcpp::R_SPARC_TLS_LE_HIX22:
// If we're creating a shared library, a dynamic relocation will
// have been created for this location, so do not apply it now.