+2015-01-28  Cary Coutant  <ccoutant@google.com>
+
+       * x86_64.cc (Target_x86_64::Scan::global): Allow IE-to-LE optimization
+       for undef TLS symbols.
+       (Target_x86_64::Relocate::relocate_tls): Likewise.
+       (Target_x86_64::Relocate::tls_ie_to_le): Likewise.
+
 2015-01-25  Cary Coutant  <ccoutant@google.com>
 
        * output.cc (Output_segment::set_section_addresses): Fix calculation
 
     case elfcpp::R_X86_64_GOTTPOFF:         // Initial-exec
     case elfcpp::R_X86_64_TPOFF32:          // Local-exec
       {
-       const bool is_final = gsym->final_value_is_known();
+       // For the Initial-Exec model, we can treat undef symbols as final
+       // when building an executable.
+       const bool is_final = (gsym->final_value_is_known() ||
+                              (r_type == elfcpp::R_X86_64_GOTTPOFF &&
+                               gsym->is_undefined() &&
+                               parameters->options().output_is_executable()));
        const tls::Tls_optimization optimized_type
            = Target_x86_64<size>::optimize_tls_reloc(is_final, r_type);
        switch (r_type)
       break;
 
     case elfcpp::R_X86_64_GOTTPOFF:         // Initial-exec
-      if (optimized_type == tls::TLSOPT_TO_LE)
+      if (gsym != NULL && gsym->is_undefined())
+       {
+         Target_x86_64<size>::Relocate::tls_ie_to_le(relinfo, relnum,
+                                                     NULL, rela,
+                                                     r_type, value, view,
+                                                     view_size);
+         break;
+       }
+      else if (optimized_type == tls::TLSOPT_TO_LE)
        {
          if (tls_segment == NULL)
            {
       view[-1] = 0x80 | reg | (reg << 3);
     }
 
-  value -= tls_segment->memsz();
+  if (tls_segment != NULL)
+    value -= tls_segment->memsz();
   Relocate_functions<size, false>::rela32(view, value, 0);
 }