summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-09-21 18:33:44 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-09-21 18:33:44 +0000
commite746e52c7b783757feec0c0c53746475f274c7f0 (patch)
tree9e91cf31f2f2df66f65974b7ba32ac54143f871e
parent0f8b5d65f62732f77f49a57d6c80a9b555023a28 (diff)
downloadbcm5719-llvm-e746e52c7b783757feec0c0c53746475f274c7f0.tar.gz
bcm5719-llvm-e746e52c7b783757feec0c0c53746475f274c7f0.zip
Implement ONLY_IF_RO/ONLY_IF_RW like bfd.
The actual logic is to keep the output section if the output section would have been ro/rw. This is both simpler and more practical, as the intention is linker scripts is to always keep of of a pair of ONLY_IF_RO/ONLY_IF_RW. llvm-svn: 282099
-rw-r--r--lld/ELF/LinkerScript.cpp13
-rw-r--r--lld/test/ELF/linkerscript/sections-constraint5.s32
2 files changed, 36 insertions, 9 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 3917c6ef1f3..a8ed92513fb 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -138,22 +138,17 @@ getComparator(SortSectionPolicy K) {
}
}
-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) {
if (Kind == ConstraintKind::NoConstraint)
return true;
- return llvm::all_of(Sections, [=](InputSectionData *Sec2) {
+ bool IsRW = llvm::any_of(Sections, [=](InputSectionData *Sec2) {
auto *Sec = static_cast<InputSectionBase<ELFT> *>(Sec2);
- return checkConstraint(Sec->getSectionHdr()->sh_flags, Kind);
+ return Sec->getSectionHdr()->sh_flags & SHF_WRITE;
});
+ return (IsRW && Kind == ConstraintKind::ReadWrite) ||
+ (!IsRW && Kind == ConstraintKind::ReadOnly);
}
static void sortSections(InputSectionData **Begin, InputSectionData **End,
diff --git a/lld/test/ELF/linkerscript/sections-constraint5.s b/lld/test/ELF/linkerscript/sections-constraint5.s
new file mode 100644
index 00000000000..ea14aad5247
--- /dev/null
+++ b/lld/test/ELF/linkerscript/sections-constraint5.s
@@ -0,0 +1,32 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "SECTIONS { \
+# RUN: bar : ONLY_IF_RO { sym1 = .; *(foo*) } \
+# RUN: bar : ONLY_IF_RW { sym2 = .; *(foo*) } \
+# RUN: }" > %t.script
+
+# RUN: ld.lld -o %t -T %t.script %t.o
+# RUN: llvm-readobj -s -t %t | FileCheck %s
+
+# CHECK: Sections [
+# CHECK: Name: bar
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: SHF_WRITE
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size: 2
+
+# CHECK: Symbols [
+# CHECK-NOT: sym1
+# CHECK: sym2
+# CHECK-NOT: sym1
+
+.section foo1,"a"
+.byte 0
+
+.section foo2,"aw"
+.byte 0
+
OpenPOWER on IntegriCloud