174 lines
5.7 KiB
C++
174 lines
5.7 KiB
C++
//===-- MachOPlatform.h - Utilities for executing MachO in Orc --*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Utilities for executing JIT'd MachO in Orc.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
|
|
#define LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/ExecutionEngine/Orc/Core.h"
|
|
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
|
|
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
|
|
|
|
#include <future>
|
|
#include <thread>
|
|
#include <vector>
|
|
|
|
namespace llvm {
|
|
namespace orc {
|
|
|
|
/// Enable registration of JIT'd ObjC classes and selectors.
|
|
Error enableObjCRegistration(const char *PathToLibObjC);
|
|
bool objCRegistrationEnabled();
|
|
|
|
class MachOJITDylibInitializers {
|
|
public:
|
|
struct SectionExtent {
|
|
SectionExtent() = default;
|
|
SectionExtent(JITTargetAddress Address, uint64_t NumPtrs)
|
|
: Address(Address), NumPtrs(NumPtrs) {}
|
|
JITTargetAddress Address = 0;
|
|
uint64_t NumPtrs = 0;
|
|
};
|
|
|
|
using RawPointerSectionList = std::vector<SectionExtent>;
|
|
|
|
void setObjCImageInfoAddr(JITTargetAddress ObjCImageInfoAddr) {
|
|
this->ObjCImageInfoAddr = ObjCImageInfoAddr;
|
|
}
|
|
|
|
void addModInitsSection(SectionExtent ModInit) {
|
|
ModInitSections.push_back(std::move(ModInit));
|
|
}
|
|
|
|
const RawPointerSectionList &getModInitsSections() const {
|
|
return ModInitSections;
|
|
}
|
|
|
|
void addObjCSelRefsSection(SectionExtent ObjCSelRefs) {
|
|
ObjCSelRefsSections.push_back(std::move(ObjCSelRefs));
|
|
}
|
|
|
|
const RawPointerSectionList &getObjCSelRefsSections() const {
|
|
return ObjCSelRefsSections;
|
|
}
|
|
|
|
void addObjCClassListSection(SectionExtent ObjCClassList) {
|
|
ObjCClassListSections.push_back(std::move(ObjCClassList));
|
|
}
|
|
|
|
const RawPointerSectionList &getObjCClassListSections() const {
|
|
return ObjCClassListSections;
|
|
}
|
|
|
|
void runModInits() const;
|
|
void registerObjCSelectors() const;
|
|
Error registerObjCClasses() const;
|
|
|
|
private:
|
|
|
|
JITTargetAddress ObjCImageInfoAddr;
|
|
RawPointerSectionList ModInitSections;
|
|
RawPointerSectionList ObjCSelRefsSections;
|
|
RawPointerSectionList ObjCClassListSections;
|
|
};
|
|
|
|
class MachOJITDylibDeinitializers {};
|
|
|
|
/// Mediates between MachO initialization and ExecutionSession state.
|
|
class MachOPlatform : public Platform {
|
|
public:
|
|
using InitializerSequence =
|
|
std::vector<std::pair<JITDylib *, MachOJITDylibInitializers>>;
|
|
|
|
using DeinitializerSequence =
|
|
std::vector<std::pair<JITDylib *, MachOJITDylibDeinitializers>>;
|
|
|
|
MachOPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
|
|
std::unique_ptr<MemoryBuffer> StandardSymbolsObject);
|
|
|
|
ExecutionSession &getExecutionSession() const { return ES; }
|
|
|
|
Error setupJITDylib(JITDylib &JD) override;
|
|
Error notifyAdding(ResourceTracker &RT,
|
|
const MaterializationUnit &MU) override;
|
|
Error notifyRemoving(ResourceTracker &RT) override;
|
|
|
|
Expected<InitializerSequence> getInitializerSequence(JITDylib &JD);
|
|
|
|
Expected<DeinitializerSequence> getDeinitializerSequence(JITDylib &JD);
|
|
|
|
private:
|
|
// This ObjectLinkingLayer plugin scans JITLink graphs for __mod_init_func,
|
|
// __objc_classlist and __sel_ref sections and records their extents so that
|
|
// they can be run in the target process.
|
|
class InitScraperPlugin : public ObjectLinkingLayer::Plugin {
|
|
public:
|
|
InitScraperPlugin(MachOPlatform &MP) : MP(MP) {}
|
|
|
|
void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
|
|
jitlink::PassConfiguration &Config) override;
|
|
|
|
LocalDependenciesMap getSyntheticSymbolLocalDependencies(
|
|
MaterializationResponsibility &MR) override;
|
|
|
|
// FIXME: We should be tentatively tracking scraped sections and discarding
|
|
// if the MR fails.
|
|
Error notifyFailed(MaterializationResponsibility &MR) override {
|
|
return Error::success();
|
|
}
|
|
|
|
Error notifyRemovingResources(ResourceKey K) override {
|
|
return Error::success();
|
|
}
|
|
|
|
void notifyTransferringResources(ResourceKey DstKey,
|
|
ResourceKey SrcKey) override {}
|
|
|
|
private:
|
|
using InitSymbolDepMap =
|
|
DenseMap<MaterializationResponsibility *, JITLinkSymbolVector>;
|
|
|
|
void preserveInitSectionIfPresent(JITLinkSymbolVector &Syms,
|
|
jitlink::LinkGraph &G,
|
|
StringRef SectionName);
|
|
|
|
Error processObjCImageInfo(jitlink::LinkGraph &G,
|
|
MaterializationResponsibility &MR);
|
|
|
|
std::mutex InitScraperMutex;
|
|
MachOPlatform &MP;
|
|
DenseMap<JITDylib *, std::pair<uint32_t, uint32_t>> ObjCImageInfos;
|
|
InitSymbolDepMap InitSymbolDeps;
|
|
};
|
|
|
|
void registerInitInfo(JITDylib &JD, JITTargetAddress ObjCImageInfoAddr,
|
|
MachOJITDylibInitializers::SectionExtent ModInits,
|
|
MachOJITDylibInitializers::SectionExtent ObjCSelRefs,
|
|
MachOJITDylibInitializers::SectionExtent ObjCClassList);
|
|
|
|
ExecutionSession &ES;
|
|
ObjectLinkingLayer &ObjLinkingLayer;
|
|
std::unique_ptr<MemoryBuffer> StandardSymbolsObject;
|
|
|
|
DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
|
|
|
|
// InitSeqs gets its own mutex to avoid locking the whole session when
|
|
// aggregating data from the jitlink.
|
|
std::mutex InitSeqsMutex;
|
|
DenseMap<JITDylib *, MachOJITDylibInitializers> InitSeqs;
|
|
};
|
|
|
|
} // end namespace orc
|
|
} // end namespace llvm
|
|
|
|
#endif // LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
|