Skip to content

Commit 85c3953

Browse files
committed
[ORC][MachO] Expose SimpleMachOHeaderMU and related utilities.
SimpleMachOHeaderMU can be used as a convenient base for classes that create custom MachO headers. Instances of these custom classes can be used by passing a MachOHeaderMUBuilder using the MachOPlatform extensions added in ef314d3.
1 parent 6e761f3 commit 85c3953

File tree

2 files changed

+141
-107
lines changed

2 files changed

+141
-107
lines changed

llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@ class MachOPlatform : public Platform {
5252
using MachOHeaderMUBuilder =
5353
unique_function<std::unique_ptr<MaterializationUnit>(MachOPlatform &MOP)>;
5454

55-
static std::unique_ptr<MaterializationUnit>
56-
defaultMachOHeaderBuilder(MachOPlatform &MOP);
55+
/// Simple MachO header graph builder.
56+
static inline std::unique_ptr<MaterializationUnit>
57+
buildSimpleMachOHeaderMU(MachOPlatform &MOP);
5758

5859
/// Try to create a MachOPlatform instance, adding the ORC runtime to the
5960
/// given JITDylib.
@@ -96,14 +97,14 @@ class MachOPlatform : public Platform {
9697
static Expected<std::unique_ptr<MachOPlatform>>
9798
Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
9899
JITDylib &PlatformJD, std::unique_ptr<DefinitionGenerator> OrcRuntime,
99-
MachOHeaderMUBuilder BuildMachOHeaderMU = defaultMachOHeaderBuilder,
100+
MachOHeaderMUBuilder BuildMachOHeaderMU = buildSimpleMachOHeaderMU,
100101
std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);
101102

102103
/// Construct using a path to the ORC runtime.
103104
static Expected<std::unique_ptr<MachOPlatform>>
104105
Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
105106
JITDylib &PlatformJD, const char *OrcRuntimePath,
106-
MachOHeaderMUBuilder BuildMachOHeaderMU = defaultMachOHeaderBuilder,
107+
MachOHeaderMUBuilder BuildMachOHeaderMU = buildSimpleMachOHeaderMU,
107108
std::optional<SymbolAliasMap> RuntimeAliases = std::nullopt);
108109

109110
ExecutionSession &getExecutionSession() const { return ES; }
@@ -332,6 +333,49 @@ class MachOPlatform : public Platform {
332333
std::atomic<BootstrapInfo *> Bootstrap;
333334
};
334335

336+
// Generates a MachO header.
337+
class SimpleMachOHeaderMU : public MaterializationUnit {
338+
public:
339+
SimpleMachOHeaderMU(MachOPlatform &MOP, SymbolStringPtr HeaderStartSymbol);
340+
StringRef getName() const override { return "MachOHeaderMU"; }
341+
void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
342+
void discard(const JITDylib &JD, const SymbolStringPtr &Sym) override;
343+
344+
protected:
345+
virtual jitlink::Block &createHeaderBlock(JITDylib &JD, jitlink::LinkGraph &G,
346+
jitlink::Section &HeaderSection);
347+
348+
private:
349+
struct HeaderSymbol {
350+
const char *Name;
351+
uint64_t Offset;
352+
};
353+
354+
static constexpr HeaderSymbol AdditionalHeaderSymbols[] = {
355+
{"___mh_executable_header", 0}};
356+
357+
void addMachOHeader(JITDylib &JD, jitlink::LinkGraph &G,
358+
const SymbolStringPtr &InitializerSymbol);
359+
static MaterializationUnit::Interface
360+
createHeaderInterface(MachOPlatform &MOP,
361+
const SymbolStringPtr &HeaderStartSymbol);
362+
363+
MachOPlatform &MOP;
364+
};
365+
366+
/// Simple MachO header graph builder.
367+
inline std::unique_ptr<MaterializationUnit>
368+
MachOPlatform::buildSimpleMachOHeaderMU(MachOPlatform &MOP) {
369+
return std::make_unique<SimpleMachOHeaderMU>(MOP, MOP.MachOHeaderStartSymbol);
370+
}
371+
372+
struct MachOHeaderInfo {
373+
size_t PageSize = 0;
374+
uint32_t CPUType = 0;
375+
uint32_t CPUSubType = 0;
376+
};
377+
MachOHeaderInfo getMachOHeaderInfoFromTriple(const Triple &TT);
378+
335379
} // end namespace orc
336380
} // end namespace llvm
337381

llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp

Lines changed: 93 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -116,101 +116,6 @@ std::unique_ptr<jitlink::LinkGraph> createPlatformGraph(MachOPlatform &MOP,
116116
jitlink::getGenericEdgeKindName);
117117
}
118118

119-
// Generates a MachO header.
120-
class MachOHeaderMaterializationUnit : public MaterializationUnit {
121-
public:
122-
MachOHeaderMaterializationUnit(MachOPlatform &MOP,
123-
SymbolStringPtr HeaderStartSymbol)
124-
: MaterializationUnit(
125-
createHeaderInterface(MOP, std::move(HeaderStartSymbol))),
126-
MOP(MOP) {}
127-
128-
StringRef getName() const override { return "MachOHeaderMU"; }
129-
130-
void materialize(std::unique_ptr<MaterializationResponsibility> R) override {
131-
auto G = createPlatformGraph(MOP, "<MachOHeaderMU>");
132-
addMachOHeader(*G, MOP, R->getInitializerSymbol());
133-
MOP.getObjectLinkingLayer().emit(std::move(R), std::move(G));
134-
}
135-
136-
void discard(const JITDylib &JD, const SymbolStringPtr &Sym) override {}
137-
138-
static void addMachOHeader(jitlink::LinkGraph &G, MachOPlatform &MOP,
139-
const SymbolStringPtr &InitializerSymbol) {
140-
auto &HeaderSection = G.createSection("__header", MemProt::Read);
141-
auto &HeaderBlock = createHeaderBlock(G, HeaderSection);
142-
143-
// Init symbol is header-start symbol.
144-
G.addDefinedSymbol(HeaderBlock, 0, *InitializerSymbol,
145-
HeaderBlock.getSize(), jitlink::Linkage::Strong,
146-
jitlink::Scope::Default, false, true);
147-
for (auto &HS : AdditionalHeaderSymbols)
148-
G.addDefinedSymbol(HeaderBlock, HS.Offset, HS.Name, HeaderBlock.getSize(),
149-
jitlink::Linkage::Strong, jitlink::Scope::Default,
150-
false, true);
151-
}
152-
153-
private:
154-
struct HeaderSymbol {
155-
const char *Name;
156-
uint64_t Offset;
157-
};
158-
159-
static constexpr HeaderSymbol AdditionalHeaderSymbols[] = {
160-
{"___mh_executable_header", 0}};
161-
162-
static jitlink::Block &createHeaderBlock(jitlink::LinkGraph &G,
163-
jitlink::Section &HeaderSection) {
164-
MachO::mach_header_64 Hdr;
165-
Hdr.magic = MachO::MH_MAGIC_64;
166-
switch (G.getTargetTriple().getArch()) {
167-
case Triple::aarch64:
168-
Hdr.cputype = MachO::CPU_TYPE_ARM64;
169-
Hdr.cpusubtype = MachO::CPU_SUBTYPE_ARM64_ALL;
170-
break;
171-
case Triple::x86_64:
172-
Hdr.cputype = MachO::CPU_TYPE_X86_64;
173-
Hdr.cpusubtype = MachO::CPU_SUBTYPE_X86_64_ALL;
174-
break;
175-
default:
176-
llvm_unreachable("Unrecognized architecture");
177-
}
178-
Hdr.filetype = MachO::MH_DYLIB; // Custom file type?
179-
Hdr.ncmds = 0;
180-
Hdr.sizeofcmds = 0;
181-
Hdr.flags = 0;
182-
Hdr.reserved = 0;
183-
184-
if (G.getEndianness() != llvm::endianness::native)
185-
MachO::swapStruct(Hdr);
186-
187-
auto HeaderContent = G.allocateContent(
188-
ArrayRef<char>(reinterpret_cast<const char *>(&Hdr), sizeof(Hdr)));
189-
190-
return G.createContentBlock(HeaderSection, HeaderContent, ExecutorAddr(), 8,
191-
0);
192-
}
193-
194-
static MaterializationUnit::Interface
195-
createHeaderInterface(MachOPlatform &MOP,
196-
const SymbolStringPtr &HeaderStartSymbol) {
197-
SymbolFlagsMap HeaderSymbolFlags;
198-
199-
HeaderSymbolFlags[HeaderStartSymbol] = JITSymbolFlags::Exported;
200-
for (auto &HS : AdditionalHeaderSymbols)
201-
HeaderSymbolFlags[MOP.getExecutionSession().intern(HS.Name)] =
202-
JITSymbolFlags::Exported;
203-
204-
return MaterializationUnit::Interface(std::move(HeaderSymbolFlags),
205-
HeaderStartSymbol);
206-
}
207-
208-
MachOPlatform &MOP;
209-
};
210-
211-
constexpr MachOHeaderMaterializationUnit::HeaderSymbol
212-
MachOHeaderMaterializationUnit::AdditionalHeaderSymbols[];
213-
214119
// Creates a Bootstrap-Complete LinkGraph to run deferred actions.
215120
class MachOPlatformCompleteBootstrapMaterializationUnit
216121
: public MaterializationUnit {
@@ -350,12 +255,6 @@ struct ObjCImageInfoFlags {
350255
namespace llvm {
351256
namespace orc {
352257

353-
std::unique_ptr<MaterializationUnit>
354-
MachOPlatform::defaultMachOHeaderBuilder(MachOPlatform &MOP) {
355-
return std::make_unique<MachOHeaderMaterializationUnit>(
356-
MOP, SymbolStringPtr(MOP.getMachOHeaderStartSymbol()));
357-
}
358-
359258
Expected<std::unique_ptr<MachOPlatform>>
360259
MachOPlatform::Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
361260
JITDylib &PlatformJD,
@@ -598,8 +497,7 @@ MachOPlatform::MachOPlatform(
598497
// the support methods callable. The bootstrap is now complete.
599498

600499
// Step (1) Add header materialization unit and request.
601-
if ((Err = PlatformJD.define(std::make_unique<MachOHeaderMaterializationUnit>(
602-
*this, MachOHeaderStartSymbol))))
500+
if ((Err = PlatformJD.define(this->BuildMachOHeaderMU(*this))))
603501
return;
604502
if ((Err = ES.lookup(&PlatformJD, MachOHeaderStartSymbol).takeError()))
605503
return;
@@ -1767,5 +1665,97 @@ Error MachOPlatform::MachOPlatformPlugin::addSymbolTableRegistration(
17671665

17681666
return Error::success();
17691667
}
1668+
1669+
template <typename MachOTraits>
1670+
jitlink::Block &createTrivialHeaderBlock(MachOPlatform &MOP,
1671+
jitlink::LinkGraph &G,
1672+
jitlink::Section &HeaderSection) {
1673+
auto HdrInfo =
1674+
getMachOHeaderInfoFromTriple(MOP.getExecutionSession().getTargetTriple());
1675+
MachOBuilder<MachOTraits> B(HdrInfo.PageSize);
1676+
1677+
B.Header.filetype = MachO::MH_DYLIB;
1678+
B.Header.cputype = HdrInfo.CPUType;
1679+
B.Header.cpusubtype = HdrInfo.CPUSubType;
1680+
1681+
auto HeaderContent = G.allocateBuffer(B.layout());
1682+
B.write(HeaderContent);
1683+
1684+
return G.createContentBlock(HeaderSection, HeaderContent, ExecutorAddr(), 8,
1685+
0);
1686+
}
1687+
1688+
SimpleMachOHeaderMU::SimpleMachOHeaderMU(MachOPlatform &MOP,
1689+
SymbolStringPtr HeaderStartSymbol)
1690+
: MaterializationUnit(
1691+
createHeaderInterface(MOP, std::move(HeaderStartSymbol))),
1692+
MOP(MOP) {}
1693+
1694+
void SimpleMachOHeaderMU::materialize(
1695+
std::unique_ptr<MaterializationResponsibility> R) {
1696+
auto G = createPlatformGraph(MOP, "<MachOHeaderMU>");
1697+
addMachOHeader(R->getTargetJITDylib(), *G, R->getInitializerSymbol());
1698+
MOP.getObjectLinkingLayer().emit(std::move(R), std::move(G));
1699+
}
1700+
1701+
void SimpleMachOHeaderMU::discard(const JITDylib &JD,
1702+
const SymbolStringPtr &Sym) {}
1703+
1704+
void SimpleMachOHeaderMU::addMachOHeader(
1705+
JITDylib &JD, jitlink::LinkGraph &G,
1706+
const SymbolStringPtr &InitializerSymbol) {
1707+
auto &HeaderSection = G.createSection("__header", MemProt::Read);
1708+
auto &HeaderBlock = createHeaderBlock(JD, G, HeaderSection);
1709+
1710+
// Init symbol is header-start symbol.
1711+
G.addDefinedSymbol(HeaderBlock, 0, *InitializerSymbol, HeaderBlock.getSize(),
1712+
jitlink::Linkage::Strong, jitlink::Scope::Default, false,
1713+
true);
1714+
for (auto &HS : AdditionalHeaderSymbols)
1715+
G.addDefinedSymbol(HeaderBlock, HS.Offset, HS.Name, HeaderBlock.getSize(),
1716+
jitlink::Linkage::Strong, jitlink::Scope::Default, false,
1717+
true);
1718+
}
1719+
1720+
jitlink::Block &
1721+
SimpleMachOHeaderMU::createHeaderBlock(JITDylib &JD, jitlink::LinkGraph &G,
1722+
jitlink::Section &HeaderSection) {
1723+
switch (MOP.getExecutionSession().getTargetTriple().getArch()) {
1724+
case Triple::aarch64:
1725+
case Triple::x86_64:
1726+
return createTrivialHeaderBlock<MachO64LE>(MOP, G, HeaderSection);
1727+
default:
1728+
llvm_unreachable("Unsupported architecture");
1729+
}
1730+
}
1731+
1732+
MaterializationUnit::Interface SimpleMachOHeaderMU::createHeaderInterface(
1733+
MachOPlatform &MOP, const SymbolStringPtr &HeaderStartSymbol) {
1734+
SymbolFlagsMap HeaderSymbolFlags;
1735+
1736+
HeaderSymbolFlags[HeaderStartSymbol] = JITSymbolFlags::Exported;
1737+
for (auto &HS : AdditionalHeaderSymbols)
1738+
HeaderSymbolFlags[MOP.getExecutionSession().intern(HS.Name)] =
1739+
JITSymbolFlags::Exported;
1740+
1741+
return MaterializationUnit::Interface(std::move(HeaderSymbolFlags),
1742+
HeaderStartSymbol);
1743+
}
1744+
1745+
MachOHeaderInfo getMachOHeaderInfoFromTriple(const Triple &TT) {
1746+
switch (TT.getArch()) {
1747+
case Triple::aarch64:
1748+
return {/* PageSize = */ 16 * 1024,
1749+
/* CPUType = */ MachO::CPU_TYPE_ARM64,
1750+
/* CPUSubType = */ MachO::CPU_SUBTYPE_ARM64_ALL};
1751+
case Triple::x86_64:
1752+
return {/* PageSize = */ 4 * 1024,
1753+
/* CPUType = */ MachO::CPU_TYPE_X86_64,
1754+
/* CPUSubType = */ MachO::CPU_SUBTYPE_X86_64_ALL};
1755+
default:
1756+
llvm_unreachable("Unrecognized architecture");
1757+
}
1758+
}
1759+
17701760
} // End namespace orc.
17711761
} // End namespace llvm.

0 commit comments

Comments
 (0)