summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/ELF
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib/ReaderWriter/ELF')
-rw-r--r--lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp3
-rw-r--r--lld/lib/ReaderWriter/ELF/SegmentChunks.h33
2 files changed, 23 insertions, 13 deletions
diff --git a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
index 221a78bfd5c..0eccf64e1a5 100644
--- a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
@@ -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)
diff --git a/lld/lib/ReaderWriter/ELF/SegmentChunks.h b/lld/lib/ReaderWriter/ELF/SegmentChunks.h
index 017358df921..9524f1bc319 100644
--- a/lld/lib/ReaderWriter/ELF/SegmentChunks.h
+++ b/lld/lib/ReaderWriter/ELF/SegmentChunks.h
@@ -399,14 +399,12 @@ void Segment<ELFT>::assignFileOffsets(uint64_t startOffset) {
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(uint64_t startOffset) {
_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>::assignVirtualAddress(uint64_t addr) {
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>::assignVirtualAddress(uint64_t addr) {
// 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
OpenPOWER on IntegriCloud