[lld] r222312 - [ELF] Fix creation of segments.

Shankar Easwaran shankare at codeaurora.org
Tue Nov 18 19:51:49 PST 2014


Author: shankare
Date: Tue Nov 18 21:51:48 2014
New Revision: 222312

URL: http://llvm.org/viewvc/llvm-project?rev=222312&view=rev
Log:
[ELF] Fix creation of segments.

Linker was creating a separate output segment in some cases if input sections
had huge alignments. This patch fixes the issue.

Added:
    lld/trunk/test/elf/X86_64/outputsegments.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h
    lld/trunk/test/elf/X86_64/alignoffset.test
    lld/trunk/test/elf/phdr.test

Modified: lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h?rev=222312&r1=222311&r2=222312&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h Tue Nov 18 21:51:48 2014
@@ -406,6 +406,8 @@ void Segment<ELFT>::assignFileOffsets(ui
   for (auto &slice : slices()) {
     bool isFirstSection = true;
     for (auto section : slice->sections()) {
+      // Align fileoffset to the alignment of the section.
+      fileOffset = llvm::RoundUpToAlignment(fileOffset, section->align2());
       // If the linker outputmagic is set to OutputMagic::NMAGIC, align the Data
       // to a page boundary
       if (isFirstSection &&
@@ -430,8 +432,7 @@ void Segment<ELFT>::assignFileOffsets(ui
         fileOffset =
             llvm::RoundUpToAlignment(fileOffset, this->_context.getPageSize());
         isDataPageAlignedForNMagic = true;
-      } else
-        fileOffset = llvm::RoundUpToAlignment(fileOffset, section->align2());
+      }
       if (isFirstSection) {
         slice->setFileOffset(fileOffset);
         isFirstSection = false;
@@ -467,6 +468,7 @@ template <class ELFT> void Segment<ELFT>
   SegmentSlice<ELFT> *slice = nullptr;
   uint64_t tlsStartAddr = 0;
   bool alignSegments = this->_context.alignSegments();
+  StringRef prevOutputSectionName;
 
   for (auto si = _sections.begin(); si != _sections.end(); ++si) {
     // If this is first section in the segment, page align the section start
@@ -522,9 +524,18 @@ template <class ELFT> void Segment<ELFT>
         isDataPageAlignedForNMagic = true;
       }
       uint64_t newAddr = llvm::RoundUpToAlignment(curAddr, (*si)->align2());
+      Section<ELFT> *sec = dyn_cast<Section<ELFT>>(*si);
+      StringRef curOutputSectionName =
+          sec ? sec->outputSectionName() : (*si)->name();
+      bool autoCreateSlice = true;
+      if (curOutputSectionName == prevOutputSectionName)
+        autoCreateSlice = false;
       // If the newAddress computed is more than a page away, let's create
       // a separate segment, so that memory is not used up while running.
-      if (((newAddr - curAddr) > this->_context.getPageSize()) &&
+      // Dont create a slice, if the new section falls in the same output
+      // section as the previous section.
+      if (autoCreateSlice &&
+          ((newAddr - curAddr) > this->_context.getPageSize()) &&
           (_outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
            _outputMagic != ELFLinkingContext::OutputMagic::OMAGIC)) {
         auto sliceIter =
@@ -577,6 +588,7 @@ template <class ELFT> void Segment<ELFT>
         else
           curSliceSize = newAddr - curSliceAddress;
       }
+      prevOutputSectionName = curOutputSectionName;
     }
     currSection++;
   }

Modified: lld/trunk/test/elf/X86_64/alignoffset.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/alignoffset.test?rev=222312&r1=222311&r2=222312&view=diff
==============================================================================
--- lld/trunk/test/elf/X86_64/alignoffset.test (original)
+++ lld/trunk/test/elf/X86_64/alignoffset.test Tue Nov 18 21:51:48 2014
@@ -7,7 +7,7 @@
 # RUN: --no-align-segments --rosegment --noinhibit-exec
 # RUN: llvm-readobj -program-headers %t.exe | FileCheck %s
 #
-#CHECK:    Offset: 0x115C
+#CHECK:    Offset: 0x15C
 #CHECK:    VirtualAddress: 0x40015C
 #CHECK:    PhysicalAddress: 0x40015C
 #

Added: lld/trunk/test/elf/X86_64/outputsegments.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/outputsegments.test?rev=222312&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/outputsegments.test (added)
+++ lld/trunk/test/elf/X86_64/outputsegments.test Tue Nov 18 21:51:48 2014
@@ -0,0 +1,189 @@
+# Tests that lld doesnot create separate segment if the input sections are part
+# of the same output section
+
+# Build executable
+# RUN: yaml2obj -format=elf -docnum 1 %s -o %t.o
+# RUN: lld -flavor gnu -target x86_64 %t.o -o %t1.exe -static \
+# RUN: --no-align-segments --noinhibit-exec
+# RUN: lld -flavor gnu -target x86_64 %t.o -o %t2.exe -static \
+# RUN: --noinhibit-exec
+# RUN: llvm-readobj -program-headers %t1.exe | FileCheck %s -check-prefix=SEGMENTS
+# RUN: llvm-readobj -program-headers %t2.exe | FileCheck %s -check-prefix=SEGMENTS
+#
+#SEGMENTS:    VirtualAddress: 0x400000
+#SEGMENTS:    PhysicalAddress: 0x400000
+#SEGMENTS:    FileSize: 288
+#SEGMENTS:    MemSize: 288
+#SEGMENTS:    VirtualAddress: 0x404000
+#SEGMENTS:    PhysicalAddress: 0x404000
+#SEGMENTS:    FileSize: 16608
+#SEGMENTS:    MemSize: 16608
+#SEGMENTS:    Alignment: 16384
+#
+# object
+---
+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:            .text.foo
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x0000000000002000
+    Content:         554889E54883EC1048BF0000000000000000B000E800000000B9000000008945FC89C84883C4105DC3
+  - Name:            .rela.text.foo
+    Type:            SHT_RELA
+    Link:            .symtab
+    AddressAlign:    0x0000000000000008
+    Info:            .text.foo
+    Relocations:
+      - Offset:          0x000000000000000A
+        Symbol:          .rodata.str1.1
+        Type:            R_X86_64_64
+        Addend:          0
+      - Offset:          0x0000000000000015
+        Symbol:          printf
+        Type:            R_X86_64_PC32
+        Addend:          -4
+  - Name:            .text.bar
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x0000000000004000
+    Content:         554889E54883EC1048BF0000000000000000B000E800000000B9000000008945FC89C84883C4105DC3
+  - Name:            .rela.text.bar
+    Type:            SHT_RELA
+    Link:            .symtab
+    AddressAlign:    0x0000000000000008
+    Info:            .text.bar
+    Relocations:
+      - Offset:          0x000000000000000A
+        Symbol:          .rodata.str1.1
+        Type:            R_X86_64_64
+        Addend:          7
+      - Offset:          0x0000000000000015
+        Symbol:          printf
+        Type:            R_X86_64_PC32
+        Addend:          -4
+  - Name:            .text.main
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x0000000000000010
+    Content:         554889E54883EC10C745FC00000000E8000000008945F8E8000000008B4DF801C189C84883C4105DC3
+  - Name:            .rela.text.main
+    Type:            SHT_RELA
+    Link:            .symtab
+    AddressAlign:    0x0000000000000008
+    Info:            .text.main
+    Relocations:
+      - Offset:          0x0000000000000010
+        Symbol:          foo
+        Type:            R_X86_64_PC32
+        Addend:          -4
+      - Offset:          0x0000000000000018
+        Symbol:          bar
+        Type:            R_X86_64_PC32
+        Addend:          -4
+  - Name:            .rodata.str1.1
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_MERGE, SHF_STRINGS ]
+    AddressAlign:    0x0000000000000001
+    Content:         48656C6C6F0A00576F726C640A00
+  - Name:            .comment
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_MERGE, SHF_STRINGS ]
+    AddressAlign:    0x0000000000000001
+    Content:         005562756E747520636C616E672076657273696F6E20332E352E302D73766E3231373330342D317E6578703120286272616E636865732F72656C656173655F33352920286261736564206F6E204C4C564D20332E352E302900
+  - Name:            .note.GNU-stack
+    Type:            SHT_PROGBITS
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+  - Name:            .eh_frame
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    AddressAlign:    0x0000000000000008
+    Content:         1400000000000000037A5200017810011B0C070890010000180000001C000000000000002900000000410E108602430D060000001800000038000000000000002900000000410E108602430D060000001C00000054000000000000002900000000410E108602430D0600000000000000
+  - Name:            .rela.eh_frame
+    Type:            SHT_RELA
+    Link:            .symtab
+    AddressAlign:    0x0000000000000008
+    Info:            .eh_frame
+    Relocations:
+      - Offset:          0x0000000000000020
+        Symbol:          .text.foo
+        Type:            R_X86_64_PC32
+        Addend:          0
+      - Offset:          0x000000000000003C
+        Symbol:          .text.bar
+        Type:            R_X86_64_PC32
+        Addend:          0
+      - Offset:          0x0000000000000058
+        Symbol:          .text.main
+        Type:            R_X86_64_PC32
+        Addend:          0
+Symbols:
+  Local:
+    - Name:            1.c
+      Type:            STT_FILE
+    - Name:            .text
+      Type:            STT_SECTION
+      Section:         .text
+    - Name:            .data
+      Type:            STT_SECTION
+      Section:         .data
+    - Name:            .bss
+      Type:            STT_SECTION
+      Section:         .bss
+    - Name:            .text.foo
+      Type:            STT_SECTION
+      Section:         .text.foo
+    - Name:            .text.bar
+      Type:            STT_SECTION
+      Section:         .text.bar
+    - Name:            .text.main
+      Type:            STT_SECTION
+      Section:         .text.main
+    - Name:            .rodata.str1.1
+      Type:            STT_SECTION
+      Section:         .rodata.str1.1
+    - Name:            .comment
+      Type:            STT_SECTION
+      Section:         .comment
+    - Name:            .note.GNU-stack
+      Type:            STT_SECTION
+      Section:         .note.GNU-stack
+    - Name:            .eh_frame
+      Type:            STT_SECTION
+      Section:         .eh_frame
+  Global:
+    - Name:            bar
+      Type:            STT_FUNC
+      Section:         .text.bar
+      Size:            0x0000000000000029
+    - Name:            foo
+      Type:            STT_FUNC
+      Section:         .text.foo
+      Size:            0x0000000000000029
+    - Name:            main
+      Type:            STT_FUNC
+      Section:         .text.main
+      Size:            0x0000000000000029
+    - Name:            printf
+...

Modified: lld/trunk/test/elf/phdr.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/phdr.test?rev=222312&r1=222311&r2=222312&view=diff
==============================================================================
--- lld/trunk/test/elf/phdr.test (original)
+++ lld/trunk/test/elf/phdr.test Tue Nov 18 21:51:48 2014
@@ -59,7 +59,7 @@ I386-NEXT:     Alignment: 4096
 I386-NEXT:   }
 I386-NEXT:   ProgramHeader {
 I386-NEXT:     Type: PT_LOAD (0x1)
-I386-NEXT:     Offset: 0x2000
+I386-NEXT:     Offset: 0x4000
 I386-NEXT:     VirtualAddress: 0x4000
 I386-NEXT:     PhysicalAddress: 0x4000
 I386-NEXT:     FileSize: 4





More information about the llvm-commits mailing list