summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ExecutionEngine/JITLink
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2019-05-10 22:24:37 +0000
committerLang Hames <lhames@gmail.com>2019-05-10 22:24:37 +0000
commitb0cecfc90701e01e26bea8c21802918ea275a184 (patch)
tree22ffc8147d46462e6d89b416a18edcbc61f6c71b /llvm/lib/ExecutionEngine/JITLink
parentc10f80eb7b4a546899ded220b3cd6cbaef0c7019 (diff)
downloadbcm5719-llvm-b0cecfc90701e01e26bea8c21802918ea275a184.tar.gz
bcm5719-llvm-b0cecfc90701e01e26bea8c21802918ea275a184.zip
[JITLink][MachO] Mark atoms in sections 'no-dead-strip' set live by default.
If a MachO section has the no-dead-strip attribute set then its atoms should be preserved, regardless of whether they're public or referenced elsewhere in the object. llvm-svn: 360477
Diffstat (limited to 'llvm/lib/ExecutionEngine/JITLink')
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/MachOAtomGraphBuilder.cpp68
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/MachOAtomGraphBuilder.h34
2 files changed, 66 insertions, 36 deletions
diff --git a/llvm/lib/ExecutionEngine/JITLink/MachOAtomGraphBuilder.cpp b/llvm/lib/ExecutionEngine/JITLink/MachOAtomGraphBuilder.cpp
index 215742c0e52..0c19f8fee0d 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachOAtomGraphBuilder.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/MachOAtomGraphBuilder.cpp
@@ -100,27 +100,8 @@ Error MachOAtomGraphBuilder::parseSections() {
if (auto EC = SecRef.getName(Name))
return errorCodeToError(EC);
- StringRef Content;
-
- // If this is a virtual section, leave its content empty.
- if (!SecRef.isVirtual()) {
- if (auto EC = SecRef.getContents(Content))
- return errorCodeToError(EC);
- if (Content.size() != SecRef.getSize())
- return make_error<JITLinkError>("Section content size does not match "
- "declared size for " +
- Name);
- }
-
unsigned SectionIndex = SecRef.getIndex() + 1;
- LLVM_DEBUG({
- dbgs() << "Adding section " << Name << ": "
- << format("0x%016" PRIx64, SecRef.getAddress())
- << ", size: " << Content.size()
- << ", align: " << SecRef.getAlignment() << "\n";
- });
-
// FIXME: Get real section permissions
// How, exactly, on MachO?
sys::Memory::ProtectionFlags Prot;
@@ -132,12 +113,41 @@ Error MachOAtomGraphBuilder::parseSections() {
sys::Memory::MF_WRITE);
auto &GenericSection = G->createSection(Name, Prot, SecRef.isBSS());
- if (SecRef.isVirtual())
- Sections[SectionIndex] =
- MachOSection(GenericSection, SecRef.getAddress(),
- SecRef.getAlignment(), SecRef.getSize());
- Sections[SectionIndex] = MachOSection(GenericSection, SecRef.getAddress(),
- SecRef.getAlignment(), Content);
+
+ LLVM_DEBUG({
+ dbgs() << "Adding section " << Name << ": "
+ << format("0x%016" PRIx64, SecRef.getAddress())
+ << ", align: " << SecRef.getAlignment() << "\n";
+ });
+
+ assert(!Sections.count(SectionIndex) && "Section index already in use");
+
+ auto &MachOSec =
+ Sections
+ .try_emplace(SectionIndex, GenericSection, SecRef.getAddress(),
+ SecRef.getAlignment())
+ .first->second;
+
+ if (!SecRef.isVirtual()) {
+ // If this section has content then record it.
+ StringRef Content;
+ if (auto EC = SecRef.getContents(Content))
+ return errorCodeToError(EC);
+ if (Content.size() != SecRef.getSize())
+ return make_error<JITLinkError>("Section content size does not match "
+ "declared size for " +
+ Name);
+ MachOSec.setContent(Content);
+ } else {
+ // If this is a zero-fill section then just record the size.
+ MachOSec.setZeroFill(SecRef.getSize());
+ }
+
+ uint32_t SectionFlags =
+ Obj.is64Bit() ? Obj.getSection64(SecRef.getRawDataRefImpl()).flags
+ : Obj.getSection(SecRef.getRawDataRefImpl()).flags;
+
+ MachOSec.setNoDeadStrip(SectionFlags & MachO::S_ATTR_NO_DEAD_STRIP);
}
return Error::success();
@@ -290,7 +300,7 @@ Error MachOAtomGraphBuilder::addNonCustomAtoms() {
LLVM_DEBUG(dbgs() << "MachOGraphBuilder setting atom content\n");
- // Set atom contents.
+ // Set atom contents and any section-based flags.
for (auto &KV : SecToAtoms) {
auto &S = *KV.first;
auto &SecAtoms = KV.second;
@@ -304,10 +314,16 @@ Error MachOAtomGraphBuilder::addNonCustomAtoms() {
dbgs() << " " << A << " to [ " << S.getAddress() + Offset << " .. "
<< S.getAddress() + LastAtomAddr << " ]\n";
});
+
if (S.isZeroFill())
A.setZeroFill(LastAtomAddr - Offset);
else
A.setContent(S.getContent().substr(Offset, LastAtomAddr - Offset));
+
+ // If the section has no-dead-strip set then mark the atom as live.
+ if (S.isNoDeadStrip())
+ A.setLive(true);
+
LastAtomAddr = Offset;
}
}
diff --git a/llvm/lib/ExecutionEngine/JITLink/MachOAtomGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/MachOAtomGraphBuilder.h
index 540e2c366f0..f5cd0ea1853 100644
--- a/llvm/lib/ExecutionEngine/JITLink/MachOAtomGraphBuilder.h
+++ b/llvm/lib/ExecutionEngine/JITLink/MachOAtomGraphBuilder.h
@@ -34,17 +34,10 @@ protected:
public:
MachOSection() = default;
- /// Create a MachO section with the given content.
+ /// Create a MachO section with the given address and alignment.
MachOSection(Section &GenericSection, JITTargetAddress Address,
- unsigned Alignment, StringRef Content)
+ unsigned Alignment)
: Address(Address), GenericSection(&GenericSection),
- ContentPtr(Content.data()), Size(Content.size()),
- Alignment(Alignment) {}
-
- /// Create a zero-fill MachO section with the given size.
- MachOSection(Section &GenericSection, JITTargetAddress Address,
- unsigned Alignment, size_t ZeroFillSize)
- : Address(Address), GenericSection(&GenericSection), Size(ZeroFillSize),
Alignment(Alignment) {}
/// Create a section without address, content or size (used for common
@@ -61,6 +54,19 @@ protected:
return GenericSection->getName();
}
+ MachOSection &setContent(StringRef Content) {
+ assert(!ContentPtr && !Size && "Content/zeroFill already set");
+ ContentPtr = Content.data();
+ Size = Content.size();
+ return *this;
+ }
+
+ MachOSection &setZeroFill(uint64_t Size) {
+ assert(!ContentPtr && !Size && "Content/zeroFill already set");
+ this->Size = Size;
+ return *this;
+ }
+
bool isZeroFill() const { return !ContentPtr; }
bool empty() const { return getSize() == 0; }
@@ -76,12 +82,20 @@ protected:
unsigned getAlignment() const { return Alignment; }
+ MachOSection &setNoDeadStrip(bool NoDeadStrip) {
+ this->NoDeadStrip = NoDeadStrip;
+ return *this;
+ }
+
+ bool isNoDeadStrip() const { return NoDeadStrip; }
+
private:
JITTargetAddress Address = 0;
Section *GenericSection = nullptr;
const char *ContentPtr = nullptr;
- size_t Size = 0;
+ uint64_t Size = 0;
unsigned Alignment = 0;
+ bool NoDeadStrip = false;
};
using CustomAtomizeFunction = std::function<Error(MachOSection &S)>;
OpenPOWER on IntegriCloud