diff options
author | Ed Maste <emaste@FreeBSD.org> | 2018-01-29 13:55:50 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2018-01-29 13:55:50 +0000 |
commit | 54a6825c80f48ef33fe058ce75c3981d8419b9a9 (patch) | |
tree | b87ad92292766e1959b4c55b34e050fd9ddb797c /contrib/llvm | |
parent | 1da03555210ed6ec24640f491949bec9b114f080 (diff) | |
download | src-54a6825c80f48ef33fe058ce75c3981d8419b9a9.tar.gz src-54a6825c80f48ef33fe058ce75c3981d8419b9a9.zip |
lld: Put the header in the first PT_LOAD even if that PT_LOAD has a LMAExpr
The root problem is that we were creating a PT_LOAD just for the header.
That was technically valid, but inconvenient: we should not be making
the ELF discontinuous.
The solution is to allow a section with LMAExpr to be added to a PT_LOAD
if that PT_LOAD doesn't already have a LMAExpr.
LLVM PR: 36017
Obtained from: LLVM r323625 by Rafael Espindola
Notes
Notes:
svn path=/head/; revision=328548
Diffstat (limited to 'contrib/llvm')
-rw-r--r-- | contrib/llvm/tools/lld/ELF/Writer.cpp | 7 | ||||
-rw-r--r-- | contrib/llvm/tools/lld/ELF/Writer.h | 5 |
2 files changed, 10 insertions, 2 deletions
diff --git a/contrib/llvm/tools/lld/ELF/Writer.cpp b/contrib/llvm/tools/lld/ELF/Writer.cpp index 5715af94268e..1c3b6495a0d1 100644 --- a/contrib/llvm/tools/lld/ELF/Writer.cpp +++ b/contrib/llvm/tools/lld/ELF/Writer.cpp @@ -822,6 +822,8 @@ void PhdrEntry::add(OutputSection *Sec) { p_align = std::max(p_align, Sec->Alignment); if (p_type == PT_LOAD) Sec->PtLoad = this; + if (Sec->LMAExpr) + ASectionHasLMA = true; } // The beginning and the ending of .rel[a].plt section are marked @@ -1626,8 +1628,9 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() { // different flags or is loaded at a discontiguous address using AT linker // script command. uint64_t NewFlags = computeFlags(Sec->getPhdrFlags()); - if (Sec->LMAExpr || Sec->MemRegion != Load->FirstSec->MemRegion || - Flags != NewFlags) { + if ((Sec->LMAExpr && Load->ASectionHasLMA) || + Sec->MemRegion != Load->FirstSec->MemRegion || Flags != NewFlags) { + Load = AddHdr(PT_LOAD, NewFlags); Flags = NewFlags; } diff --git a/contrib/llvm/tools/lld/ELF/Writer.h b/contrib/llvm/tools/lld/ELF/Writer.h index 6875dc514039..9902f0070cb4 100644 --- a/contrib/llvm/tools/lld/ELF/Writer.h +++ b/contrib/llvm/tools/lld/ELF/Writer.h @@ -44,6 +44,11 @@ struct PhdrEntry { OutputSection *FirstSec = nullptr; OutputSection *LastSec = nullptr; bool HasLMA = false; + + // True if any of the sections in this program header as a LMA specified via + // linker script: AT(addr). + bool ASectionHasLMA = false; + uint64_t LMAOffset = 0; }; |