[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