[lld] r221571 - [ELF] Support --no-align-segments.
Shankar Easwaran
shankare at codeaurora.org
Fri Nov 7 19:44:50 PST 2014
Author: shankare
Date: Fri Nov 7 21:44:49 2014
New Revision: 221571
URL: http://llvm.org/viewvc/llvm-project?rev=221571&view=rev
Log:
[ELF] Support --no-align-segments.
lld generates an ELF by adhering to the ELF spec by aligning vma/fileoffset to a
page boundary, but this becomes an issue when dealing with large pages. This
adds support so that lld generated executables adheres to the ELF spec with the
rule vma % p_align = offset % p_align.
This is supported by the flag --no-align-segments.
This could be the default in few targets like X86_64 to save space on disk.
Added:
lld/trunk/test/elf/X86_64/noalignsegments.test
Modified:
lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
lld/trunk/lib/Driver/GnuLdDriver.cpp
lld/trunk/lib/Driver/GnuLdOptions.td
lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h
lld/trunk/test/elf/phdr.test
Modified: lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h?rev=221571&r1=221570&r2=221571&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h Fri Nov 7 21:44:49 2014
@@ -278,6 +278,10 @@ public:
bool demangleSymbols() const { return _demangle; }
void setDemangleSymbols(bool d) { _demangle = d; }
+ /// \brief Align segments.
+ bool alignSegments() const { return _alignSegments; }
+ void setAlignSegments(bool align) { _alignSegments = align; }
+
private:
ELFLinkingContext() LLVM_DELETED_FUNCTION;
@@ -303,6 +307,7 @@ protected:
bool _noAllowDynamicLibraries;
bool _mergeRODataToTextSegment;
bool _demangle;
+ bool _alignSegments;
OutputMagic _outputMagic;
StringRefVector _inputSearchPaths;
std::unique_ptr<Writer> _writer;
Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=221571&r1=221570&r2=221571&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp Fri Nov 7 21:44:49 2014
@@ -555,6 +555,10 @@ bool GnuLdDriver::parse(int argc, const
ctx->setCreateSeparateROSegment();
break;
+ case OPT_no_align_segments:
+ ctx->setAlignSegments(false);
+ break;
+
default:
break;
} // end switch on option ID
Modified: lld/trunk/lib/Driver/GnuLdOptions.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdOptions.td?rev=221571&r1=221570&r2=221571&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdOptions.td (original)
+++ lld/trunk/lib/Driver/GnuLdOptions.td Fri Nov 7 21:44:49 2014
@@ -221,6 +221,9 @@ def rosegment: Flag<["--"], "rosegment">
def z : Separate<["-"], "z">,
HelpText<"Linker Option extensions">,
Group<grp_customopts>;
+def no_align_segments: Flag<["--"], "no-align-segments">,
+ HelpText<"Don't align ELF segments(virtualaddress/fileoffset) to page boundaries">,
+ Group<grp_customopts>;
//===----------------------------------------------------------------------===//
/// Symbol options
Modified: lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp?rev=221571&r1=221570&r2=221571&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp Fri Nov 7 21:44:49 2014
@@ -62,7 +62,8 @@ ELFLinkingContext::ELFLinkingContext(
_mergeCommonStrings(false), _runLayoutPass(true),
_useShlibUndefines(true), _dynamicLinkerArg(false),
_noAllowDynamicLibraries(false), _mergeRODataToTextSegment(true),
- _demangle(true), _outputMagic(OutputMagic::DEFAULT), _sysrootPath("") {}
+ _demangle(true), _alignSegments(true), _outputMagic(OutputMagic::DEFAULT),
+ _sysrootPath("") {}
void ELFLinkingContext::addPasses(PassManager &pm) {
if (_runLayoutPass)
Modified: lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h?rev=221571&r1=221570&r2=221571&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h Fri Nov 7 21:44:49 2014
@@ -399,14 +399,12 @@ void Segment<ELFT>::assignFileOffsets(ui
uint64_t fileOffset = startOffset;
uint64_t curSliceFileOffset = fileOffset;
bool isDataPageAlignedForNMagic = false;
+ bool alignSegments = this->_context.alignSegments();
+ uint64_t p_align = this->_context.getPageSize();
this->setFileOffset(startOffset);
for (auto &slice : slices()) {
- // Align to the slice alignment
- fileOffset = llvm::RoundUpToAlignment(fileOffset, slice->align2());
-
bool isFirstSection = true;
-
for (auto section : slice->sections()) {
// If the linker outputmagic is set to OutputMagic::NMAGIC, align the Data
// to a page boundary
@@ -415,16 +413,25 @@ void Segment<ELFT>::assignFileOffsets(ui
_outputMagic != ELFLinkingContext::OutputMagic::OMAGIC) {
// Align to a page only if the output is not
// OutputMagic::NMAGIC/OutputMagic::OMAGIC
- fileOffset =
- llvm::RoundUpToAlignment(fileOffset, this->_context.getPageSize());
- }
- if (!isDataPageAlignedForNMagic && needAlign(section)) {
+ if (alignSegments)
+ fileOffset = llvm::RoundUpToAlignment(fileOffset, p_align);
+ else {
+ // Align according to ELF spec.
+ // in p75, http://www.sco.com/developers/devspecs/gabi41.pdf
+ uint64_t padding = 0;
+ uint64_t virtualAddress = slice->virtualAddr();
+ Section<ELFT> *sect = dyn_cast<Section<ELFT>>(section);
+ if (sect && sect->isLoadableSection() &&
+ ((virtualAddress & (p_align - 1)) !=
+ (fileOffset & (p_align - 1))))
+ fileOffset = llvm::RoundUpToAlignment(fileOffset, p_align);
+ }
+ } else if (!isDataPageAlignedForNMagic && needAlign(section)) {
fileOffset =
llvm::RoundUpToAlignment(fileOffset, this->_context.getPageSize());
isDataPageAlignedForNMagic = true;
- }
- // Align the section address
- fileOffset = llvm::RoundUpToAlignment(fileOffset, section->align2());
+ } else
+ fileOffset = llvm::RoundUpToAlignment(fileOffset, section->align2());
if (isFirstSection) {
slice->setFileOffset(fileOffset);
@@ -460,6 +467,7 @@ template <class ELFT> void Segment<ELFT>
uint64_t startAddr = addr;
SegmentSlice<ELFT> *slice = nullptr;
uint64_t tlsStartAddr = 0;
+ bool alignSegments = this->_context.alignSegments();
for (auto si = _sections.begin(); si != _sections.end(); ++si) {
// If this is first section in the segment, page align the section start
@@ -467,7 +475,8 @@ template <class ELFT> void Segment<ELFT>
// only if NMAGIC is set.
if (isFirstSection) {
isFirstSection = false;
- if (_outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
+ if (alignSegments &&
+ _outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
_outputMagic != ELFLinkingContext::OutputMagic::OMAGIC)
// Align to a page only if the output is not
// OutputMagic::NMAGIC/OutputMagic::OMAGIC
Added: lld/trunk/test/elf/X86_64/noalignsegments.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/noalignsegments.test?rev=221571&view=auto
==============================================================================
--- lld/trunk/test/elf/X86_64/noalignsegments.test (added)
+++ lld/trunk/test/elf/X86_64/noalignsegments.test Fri Nov 7 21:44:49 2014
@@ -0,0 +1,95 @@
+# Checks that segments are aligned as per ELF spec than aligning each
+# segment fileoffset / virtual address to a page.
+
+# Build executable
+# RUN: yaml2obj -format=elf -docnum 1 %s -o %t.o
+# RUN: lld -flavor gnu -target x86_64 %t.o -o %t.exe -static \
+# RUN: --no-align-segments --noinhibit-exec
+# RUN: llvm-readobj -program-headers %t.exe | FileCheck %s
+#
+#CHECK: VirtualAddress: 0x400000
+#CHECK: PhysicalAddress: 0x400000
+#CHECK: VirtualAddress: 0x400178
+#CHECK: PhysicalAddress: 0x400178
+
+# 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: 0x0000000000000010
+ Content: 554889E5B864000000C745FC000000005DC366666666662E0F1F840000000000554889E531C05DC3
+ - 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: '64000000'
+ - Name: .rodata
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: '64000000'
+ - Name: .eh_frame
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ AddressAlign: 0x0000000000000008
+ Content: 1400000000000000037A5200017810011B0C070890010000180000001C000000000000001200000000410E108602430D060000001800000038000000000000000800000000410E108602430D06000000
+ - Name: .rela.eh_frame
+ Type: SHT_RELA
+ Link: .symtab
+ AddressAlign: 0x0000000000000008
+ Info: .eh_frame
+ Relocations:
+ - Offset: 0x0000000000000020
+ Symbol: .text
+ Type: R_X86_64_PC32
+ Addend: 0
+ - Offset: 0x000000000000003C
+ Symbol: .text
+ Type: R_X86_64_PC32
+ Addend: 32
+Symbols:
+ Local:
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ - Name: .eh_frame
+ Type: STT_SECTION
+ Section: .eh_frame
+ Global:
+ - Name: foo
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x0000000000000020
+ Size: 0x0000000000000008
+ - Name: main
+ Type: STT_FUNC
+ Section: .text
+ Size: 0x0000000000000012
+ - Name: myval
+ Type: STT_OBJECT
+ Section: .bss
+ Size: 0x0000000000000004
+ - Name: val
+ Type: STT_OBJECT
+ Section: .rodata
+ Size: 0x0000000000000004
+...
Modified: lld/trunk/test/elf/phdr.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/phdr.test?rev=221571&r1=221570&r2=221571&view=diff
==============================================================================
--- lld/trunk/test/elf/phdr.test (original)
+++ lld/trunk/test/elf/phdr.test Fri Nov 7 21:44:49 2014
@@ -59,7 +59,7 @@ I386-NEXT: Alignment: 4096
I386-NEXT: }
I386-NEXT: ProgramHeader {
I386-NEXT: Type: PT_LOAD (0x1)
-I386-NEXT: Offset: 0x4000
+I386-NEXT: Offset: 0x2000
I386-NEXT: VirtualAddress: 0x4000
I386-NEXT: PhysicalAddress: 0x4000
I386-NEXT: FileSize: 4
More information about the llvm-commits
mailing list