This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gold patch] Fix problem with placement of .tbss with scripts


Ian,

You commited a patch back in March to fix a problem with placement of
orphan TLS sections that caused a test failure in script_test_2 when
using an archive version of libstdc++.a:

    http://sourceware.org/ml/binutils/2010-03/msg00341.html

Unfortunately, that didn't quite fix the whole problem. In the tests
we ran at the time, the .tbss section was getting assigned an address
of, say, 0x10110990, and the following .bss section, with an alignment
of 32, was aligned to an address of 0x101109a0. When padding was
added, the .tbss section sorted before the .bss section and all was
well. If .tbss happened to be assigned an address aligned to a 32-byte
boundary, however, .bss would get the same starting address, and
Sort_output_sections would send the TLS section to the end:

  // Sort TLS sections to the end.

As a result, Script_sections::create_segments() would think it needed
to start a new segment for the .bss section, and we'd end up with a
segment overlap error.

This patch should fix the problem. I've changed the comparator to sort
sections in the order PROGBITS < TLS PROGBITS < TLS NOBITS < NOBITS.
Sorry, the logic might not be completely obvious -- I wasn't sure how
to show the truth table it's derived from in a comment.

-cary


        * script-sections.cc (Sort_output_sections::operator()): Sort TLS
        sections before NOBITS sections.


diff --git a/gold/script-sections.cc b/gold/script-sections.cc
index 7bcf91c..fd1ae72 100644
--- a/gold/script-sections.cc
+++ b/gold/script-sections.cc
@@ -3586,17 +3586,13 @@ Sort_output_sections::operator()(const
Output_section* os1,
   if (os1->address() != os2->address())
     return os1->address() < os2->address();

-  // Sort TLS sections to the end.
+  // Sort PROGBITS < TLS < TLS NOBITS < NOBITS.
+  bool nobits1 = os1->type() == elfcpp::SHT_NOBITS;
+  bool nobits2 = os2->type() == elfcpp::SHT_NOBITS;
   bool tls1 = (os1->flags() & elfcpp::SHF_TLS) != 0;
   bool tls2 = (os2->flags() & elfcpp::SHF_TLS) != 0;
-  if (tls1 != tls2)
-    return tls2;
-
-  // Sort PROGBITS before NOBITS.
-  if (os1->type() == elfcpp::SHT_PROGBITS && os2->type() == elfcpp::SHT_NOBITS)
-    return true;
-  if (os1->type() == elfcpp::SHT_NOBITS && os2->type() == elfcpp::SHT_PROGBITS)
-    return false;
+  if (nobits1 != nobits2 || tls1 != tls2)
+    return (!nobits1 && nobits2) || (!nobits1 && tls2) || (tls1 && nobits2);

   // Sort non-NOLOAD before NOLOAD.
   if (os1->is_noload() && !os2->is_noload())


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]