summaryrefslogtreecommitdiff
path: root/lld/ELF/LinkerScript.cpp
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2016-08-12 20:38:20 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2016-08-12 20:38:20 +0000
commit8f66df92ba28f7db8c63bee46780b825750ad8d7 (patch)
treec1ab6711f82f74471a595559ce2af0c220073b46 /lld/ELF/LinkerScript.cpp
parentf4fdb5ddf3f18348393516bea845d406805e497b (diff)
[ELF] - Linkerscript: fix VA value assigned to sections when using constraints.
Previously we searched output section by name to assign VA. That did not work in the case when multiple output sections with different constraints were defined in script. Testcase shows the possible issue scenario, patch fixes the issue. Differential revision: https://reviews.llvm.org/D23451 llvm-svn: 278561
Diffstat (limited to 'lld/ELF/LinkerScript.cpp')
-rw-r--r--lld/ELF/LinkerScript.cpp36
1 files changed, 26 insertions, 10 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 95b28e2af5d8..ca5ab377bf88 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -215,14 +215,20 @@ void LinkerScript<ELFT>::discard(OutputSectionCommand &Cmd) {
}
}
+static bool checkConstraint(uint64_t Flags, ConstraintKind Kind) {
+ bool RO = (Kind == ConstraintKind::ReadOnly);
+ bool RW = (Kind == ConstraintKind::ReadWrite);
+ bool Writable = Flags & SHF_WRITE;
+ return !((RO && Writable) || (RW && !Writable));
+}
+
template <class ELFT>
static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections,
ConstraintKind Kind) {
- bool RO = (Kind == ConstraintKind::ReadOnly);
- bool RW = (Kind == ConstraintKind::ReadWrite);
- return !llvm::any_of(Sections, [=](InputSectionBase<ELFT> *Sec) {
- bool Writable = Sec->getSectionHdr()->sh_flags & SHF_WRITE;
- return (RO && Writable) || (RW && !Writable);
+ if (Kind == ConstraintKind::NoConstraint)
+ return true;
+ return llvm::all_of(Sections, [=](InputSectionBase<ELFT> *Sec) {
+ return checkConstraint(Sec->getSectionHdr()->sh_flags, Kind);
});
}
@@ -330,6 +336,19 @@ template <class ELFT> void assignOffsets(OutputSectionBase<ELFT> *Sec) {
}
}
+template <class ELFT>
+static OutputSectionBase<ELFT> *
+findSection(OutputSectionCommand &Cmd,
+ ArrayRef<OutputSectionBase<ELFT> *> Sections) {
+ for (OutputSectionBase<ELFT> *Sec : Sections) {
+ if (Sec->getName() != Cmd.Name)
+ continue;
+ if (checkConstraint(Sec->getFlags(), Cmd.Constraint))
+ return Sec;
+ }
+ return nullptr;
+}
+
template <class ELFT> void LinkerScript<ELFT>::assignAddresses() {
// Orphan sections are sections present in the input files which
// are not explicitly placed into the output file by the linker script.
@@ -363,12 +382,9 @@ template <class ELFT> void LinkerScript<ELFT>::assignAddresses() {
}
auto *Cmd = cast<OutputSectionCommand>(Base.get());
- auto I = llvm::find_if(*OutputSections, [&](OutputSectionBase<ELFT> *S) {
- return S->getName() == Cmd->Name;
- });
- if (I == OutputSections->end())
+ OutputSectionBase<ELFT> *Sec = findSection<ELFT>(*Cmd, *OutputSections);
+ if (!Sec)
continue;
- OutputSectionBase<ELFT> *Sec = *I;
if (Cmd->AddrExpr)
Dot = Cmd->AddrExpr(Dot);