mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[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
This commit is contained in:
parent
ec873a2c12
commit
49dc5222e8
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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)>;
|
||||
|
@ -263,4 +263,13 @@ subtractor_with_alt_entry_subtrahend_quad:
|
||||
subtractor_with_alt_entry_subtrahend_quad_B:
|
||||
.quad 0
|
||||
|
||||
# Check that unreferenced atoms in no-dead-strip sections are not dead stripped.
|
||||
# We need to use a local symbol for this as any named symbol will end up in the
|
||||
# ORC responsibility set, which is automatically marked live and would couse
|
||||
# spurious passes.
|
||||
#
|
||||
# jitlink-check: *{8}section_addr(macho_reloc.o, __nds_test_sect) = 0
|
||||
.section __DATA,__nds_test_sect,regular,no_dead_strip
|
||||
.quad 0
|
||||
|
||||
.subsections_via_symbols
|
||||
|
Loading…
Reference in New Issue
Block a user