* sparc.cc (class Target_sparc): Add has_got_section.
authorIan Lance Taylor <ian@airs.com>
Tue, 17 Mar 2009 07:19:10 +0000 (07:19 +0000)
committerIan Lance Taylor <ian@airs.com>
Tue, 17 Mar 2009 07:19:10 +0000 (07:19 +0000)
(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.

gold/ChangeLog
gold/sparc.cc

index 3267dabdd19a881268685fb953077077e9eb2119..7af69c498558f8d66ec58a036d18cac559f1cba8 100644 (file)
@@ -1,5 +1,15 @@
 2009-03-17  Ian Lance Taylor  <iant@google.com>
 
+       * 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.
+
        * symtab.cc (Symbol_table::define_default_version): New function,
        broken out of add_from_object.
        (Symbol_table::add_from_object): Call define_default_version.
index 794cab924db84735d68108530d4a382f08188d97..41aa7cd9d6c6d21a4987c5b3f987ff3928e96a37 100644 (file)
@@ -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.