[lld] r239906 - [ELF] Fix wrong TBSS size

Adhemerval Zanella azanella at linux.vnet.ibm.com
Wed Jun 17 06:46:08 PDT 2015


Author: azanella
Date: Wed Jun 17 08:46:07 2015
New Revision: 239906

URL: http://llvm.org/viewvc/llvm-project?rev=239906&view=rev
Log:
[ELF] Fix wrong TBSS size

This patch fixes the wrong .tbss segment size generated for cases where
multiple modules have non initialized threads variables.  For instance:

* t0.c

__thread int x0;
__thread int x1;
__thread int x2;

extern __thread int e0;
extern __thread int e1;
extern __thread int e2;
extern __thread int e3;

int foo0 ()
{
  return x0;
}

int main ()
{
  return x0;
}

* t1.c

__thread int e0;
__thread int e1;
__thread int e2;
__thread int e3;


lld is generating (for aarch64):

  [14] .tbss             NOBITS           0000000000401000  00001000
       0000000000000010  0000000000000000 WAT       0     0     4

Where is just taking in consideration the largest tbss segment, not all
from all objects.  ld generates a correct output:

  [17] .tbss             NOBITS           0000000000410dec  00000dec
       000000000000001c  0000000000000000 WAT       0     0     4

This issue is at 'lib/ReaderWriter/ELF/SegmentChunks.cpp' where
Segment<ELFT>::assignVirtualAddress is setting wrong slice values, not taking care
of although tbss segments file size does noy play role in other segment virtual
address placement, its size should still be considered.


Added:
    lld/trunk/test/elf/Inputs/tls-tbss-size.yaml
    lld/trunk/test/elf/tls-tbss-size.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp

Modified: lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp?rev=239906&r1=239905&r2=239906&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp Wed Jun 17 08:46:07 2015
@@ -188,6 +188,7 @@ template <class ELFT> void Segment<ELFT>
   uint64_t tlsStartAddr = 0;
   bool alignSegments = this->_ctx.alignSegments();
   StringRef prevOutputSectionName = StringRef();
+  uint64_t tbssMemsize = 0;
 
   // If this is first section in the segment, page align the section start
   // address. The linker needs to align the data section to a page boundary
@@ -231,8 +232,12 @@ template <class ELFT> void Segment<ELFT>
     // segment. If we see a tbss section, don't add memory size to addr The
     // fileOffset is automatically taken care of since TBSS section does not
     // end up using file size
-    if ((*si)->order() != TargetLayout<ELFT>::ORDER_TBSS)
+    if ((*si)->order() != TargetLayout<ELFT>::ORDER_TBSS) {
       curSliceSize = (*si)->memSize();
+      tbssMemsize = 0;
+    } else {
+      tbssMemsize = (*si)->memSize();
+    }
     ++currSection;
     ++si;
   }
@@ -292,6 +297,8 @@ template <class ELFT> void Segment<ELFT>
       slice->setVirtualAddr(curSliceAddress);
       // Start new slice
       curSliceAddress = newAddr;
+      if ((*si)->order() == TargetLayout<ELFT>::ORDER_TBSS)
+        curSliceAddress += tbssMemsize;
       (*si)->setVirtualAddr(curSliceAddress);
       startSectionIter = si;
       startSection = currSection;
@@ -302,6 +309,8 @@ template <class ELFT> void Segment<ELFT>
     } else {
       if (sliceAlign < (*si)->alignment())
         sliceAlign = (*si)->alignment();
+      if ((*si)->order() == TargetLayout<ELFT>::ORDER_TBSS)
+        newAddr += tbssMemsize;
       (*si)->setVirtualAddr(newAddr);
       // Handle TLS.
       if (auto section = dyn_cast<Section<ELFT>>(*si)) {
@@ -318,10 +327,16 @@ template <class ELFT> void Segment<ELFT>
       // any segment. If we see a tbss section, don't add memory size to addr
       // The fileOffset is automatically taken care of since TBSS section does
       // not end up using file size.
-      if ((*si)->order() != TargetLayout<ELFT>::ORDER_TBSS)
+      if ((*si)->order() != TargetLayout<ELFT>::ORDER_TBSS) {
         curSliceSize = newAddr - curSliceAddress + (*si)->memSize();
-      else
-        curSliceSize = newAddr - curSliceAddress;
+        tbssMemsize = 0;
+      } else {
+        // Although TBSS section does not contribute to memory of any segment,
+        // we still need to keep track its total size to correct write it
+        // down.  Since it is done based on curSliceAddress, we need to add
+        // add it to virtual address.
+        tbssMemsize = (*si)->memSize();
+      }
     }
     prevOutputSectionName = curOutputSectionName;
     ++currSection;

Added: lld/trunk/test/elf/Inputs/tls-tbss-size.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/tls-tbss-size.yaml?rev=239906&view=auto
==============================================================================
--- lld/trunk/test/elf/Inputs/tls-tbss-size.yaml (added)
+++ lld/trunk/test/elf/Inputs/tls-tbss-size.yaml Wed Jun 17 08:46:07 2015
@@ -0,0 +1,60 @@
+---
+FileHeader:      
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_GNU
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:        
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x0000000000000004
+    Content:         ''
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000004
+    Content:         ''
+  - Name:            .bss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000004
+    Content:         ''
+  - Name:            .tbss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
+    AddressAlign:    0x0000000000000004
+    Content:         00636C616E672076657273696F6E2033
+  - Name:            .note.GNU-stack
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+Symbols:         
+  Local:           
+    - Name:            t1.c
+      Type:            STT_FILE
+    - Name:            .tbss
+      Type:            STT_TLS
+      Section:         .tbss
+  Global:          
+    - Name:            t0
+      Type:            STT_TLS
+      Section:         .tbss
+      Size:            0x0000000000000004
+    - Name:            t1
+      Type:            STT_TLS
+      Section:         .tbss
+      Value:           0x0000000000000004
+      Size:            0x0000000000000004
+    - Name:            t2
+      Type:            STT_TLS
+      Section:         .tbss
+      Value:           0x0000000000000008
+      Size:            0x0000000000000004
+    - Name:            t3
+      Type:            STT_TLS
+      Section:         .tbss
+      Value:           0x000000000000000C
+      Size:            0x0000000000000004
+...

Added: lld/trunk/test/elf/tls-tbss-size.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/tls-tbss-size.test?rev=239906&view=auto
==============================================================================
--- lld/trunk/test/elf/tls-tbss-size.test (added)
+++ lld/trunk/test/elf/tls-tbss-size.test Wed Jun 17 08:46:07 2015
@@ -0,0 +1,177 @@
+# This test verify if external TLS non initialized variables (tbss) are
+# accounted in TBSS segment size
+
+# The input file 'test/elf/Inputs/tls-tbss-size.yaml' declares:
+#
+# __thread int t0;       
+# __thread int t1;
+# __thread int t2;
+# __thread int t3;        
+#
+# And the 'test/elf/tls-tbss-size.test' defines: 
+#
+# __thread int t4;                                                                          
+# __thread int t5;
+# __thread int t6;             
+# __thread int t7;
+#
+# __thread int t8 = 3;                 
+# __thread int t9 = 4;    
+# __thread int t10 = 5;
+# __thread int t11 = 6;                    
+
+#RUN: yaml2obj -format=elf -o=%t-t1.o %p/Inputs/tls-tbss-size.yaml
+#RUN: yaml2obj -format=elf -o=%t-t0.o %s
+#RUN: lld -flavor gnu -target x86_64-linux --noinhibit-exec -o %t.exe %t-t0.o %t-t1.o
+#RUN: llvm-readobj --sections %t.exe | FileCheck %s
+                                          
+#CHECK: Sections [
+#CHECK:   Section {
+#CHECK:     Index: 9
+#CHECK:     Name: .tdata (71)
+#CHECK:     Size: 16
+#CHECK:   } 
+#CHECK:   Section {
+#CHECK:     Index: 10
+#CHECK:     Name: .tbss (78)
+#CHECK:     Size: 32
+#CHECK:   }
+
+---
+FileHeader:      
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_GNU
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:        
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x0000000000000010
+    Content:         488B050000000064C70001000000488B050000000064C70002000000488B050000000064C70003000000488B050000000064C7000400000064C70425000000000500000064C70425000000000600000064C70425000000000700000064C70425000000000800000031C0C3
+  - Name:            .rela.text
+    Type:            SHT_RELA
+    Link:            .symtab
+    AddressAlign:    0x0000000000000008
+    Info:            .text
+    Relocations:     
+      - Offset:          0x0000000000000003
+        Symbol:          t0
+        Type:            R_X86_64_GOTTPOFF
+        Addend:          -4
+      - Offset:          0x0000000000000011
+        Symbol:          t1
+        Type:            R_X86_64_GOTTPOFF
+        Addend:          -4
+      - Offset:          0x000000000000001F
+        Symbol:          t2
+        Type:            R_X86_64_GOTTPOFF
+        Addend:          -4
+      - Offset:          0x000000000000002D
+        Symbol:          t3
+        Type:            R_X86_64_GOTTPOFF
+        Addend:          -4
+      - Offset:          0x000000000000003C
+        Symbol:          t4
+        Type:            R_X86_64_TPOFF32
+      - Offset:          0x0000000000000048
+        Symbol:          t5
+        Type:            R_X86_64_TPOFF32
+      - Offset:          0x0000000000000054
+        Symbol:          t6
+        Type:            R_X86_64_TPOFF32
+      - Offset:          0x0000000000000060
+        Symbol:          t7
+        Type:            R_X86_64_TPOFF32
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000004
+    Content:         ''
+  - Name:            .bss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000004
+    Content:         ''
+  - Name:            .tdata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
+    AddressAlign:    0x0000000000000004
+    Content:         '03000000040000000500000006000000'
+  - Name:            .tbss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
+    AddressAlign:    0x0000000000000004
+    Content:         00636C616E672076657273696F6E2033
+  - Name:            .note.GNU-stack
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+  - Name:            .eh_frame
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    AddressAlign:    0x0000000000000008
+    Content:         1400000000000000017A5200017810011B0C070890010000140000001C000000000000006B0000000000000000000000
+Symbols:         
+  Local:           
+    - Name:            .tbss
+      Type:            STT_TLS
+      Section:         .tbss
+    - Name:            .tdata
+      Type:            STT_TLS
+      Section:         .tdata
+    - Type:            STT_SECTION
+      Section:         .text
+  Global:          
+    - Name:            main
+      Type:            STT_FUNC
+      Section:         .text
+      Size:            0x000000000000006B
+    - Name:            t0
+      Type:            STT_TLS
+    - Name:            t1
+      Type:            STT_TLS
+    - Name:            t10
+      Type:            STT_TLS
+      Section:         .tdata
+      Value:           0x0000000000000008
+      Size:            0x0000000000000004
+    - Name:            t11
+      Type:            STT_TLS
+      Section:         .tdata
+      Value:           0x000000000000000C
+      Size:            0x0000000000000004
+    - Name:            t2
+      Type:            STT_TLS
+    - Name:            t3
+      Type:            STT_TLS
+    - Name:            t4
+      Type:            STT_TLS
+      Section:         .tbss
+      Size:            0x0000000000000004
+    - Name:            t5
+      Type:            STT_TLS
+      Section:         .tbss
+      Value:           0x0000000000000004
+      Size:            0x0000000000000004
+    - Name:            t6
+      Type:            STT_TLS
+      Section:         .tbss
+      Value:           0x0000000000000008
+      Size:            0x0000000000000004
+    - Name:            t7
+      Type:            STT_TLS
+      Section:         .tbss
+      Value:           0x000000000000000C
+      Size:            0x0000000000000004
+    - Name:            t8
+      Type:            STT_TLS
+      Section:         .tdata
+      Size:            0x0000000000000004
+    - Name:            t9
+      Type:            STT_TLS
+      Section:         .tdata
+      Value:           0x0000000000000004
+      Size:            0x0000000000000004
+...





More information about the llvm-commits mailing list