mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
Re-re-re-apply "[ORC][ORC-RT] Add initial native-TLV support to MachOPlatform."
The ccache builders have recevied a config update that should eliminate the build issues seen previously.
This commit is contained in:
parent
28751b1109
commit
500a10cb5e
@ -29,6 +29,7 @@ namespace orc {
|
|||||||
|
|
||||||
struct MachOPerObjectSectionsToRegister {
|
struct MachOPerObjectSectionsToRegister {
|
||||||
ExecutorAddressRange EHFrameSection;
|
ExecutorAddressRange EHFrameSection;
|
||||||
|
ExecutorAddressRange ThreadDataSection;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MachOJITDylibInitializers {
|
struct MachOJITDylibInitializers {
|
||||||
@ -158,14 +159,16 @@ private:
|
|||||||
void addMachOHeaderSupportPasses(MaterializationResponsibility &MR,
|
void addMachOHeaderSupportPasses(MaterializationResponsibility &MR,
|
||||||
jitlink::PassConfiguration &Config);
|
jitlink::PassConfiguration &Config);
|
||||||
|
|
||||||
void addEHSupportPasses(MaterializationResponsibility &MR,
|
void addEHAndTLVSupportPasses(MaterializationResponsibility &MR,
|
||||||
jitlink::PassConfiguration &Config);
|
jitlink::PassConfiguration &Config);
|
||||||
|
|
||||||
Error preserveInitSections(jitlink::LinkGraph &G,
|
Error preserveInitSections(jitlink::LinkGraph &G,
|
||||||
MaterializationResponsibility &MR);
|
MaterializationResponsibility &MR);
|
||||||
|
|
||||||
Error registerInitSections(jitlink::LinkGraph &G, JITDylib &JD);
|
Error registerInitSections(jitlink::LinkGraph &G, JITDylib &JD);
|
||||||
|
|
||||||
|
Error fixTLVSectionsAndEdges(jitlink::LinkGraph &G, JITDylib &JD);
|
||||||
|
|
||||||
std::mutex PluginMutex;
|
std::mutex PluginMutex;
|
||||||
MachOPlatform ∓
|
MachOPlatform ∓
|
||||||
InitSymbolDepMap InitSymbolDeps;
|
InitSymbolDepMap InitSymbolDeps;
|
||||||
@ -213,6 +216,8 @@ private:
|
|||||||
|
|
||||||
Error registerPerObjectSections(const MachOPerObjectSectionsToRegister &POSR);
|
Error registerPerObjectSections(const MachOPerObjectSectionsToRegister &POSR);
|
||||||
|
|
||||||
|
Expected<uint64_t> createPThreadKey();
|
||||||
|
|
||||||
ExecutionSession &ES;
|
ExecutionSession &ES;
|
||||||
ObjectLinkingLayer &ObjLinkingLayer;
|
ObjectLinkingLayer &ObjLinkingLayer;
|
||||||
ExecutorProcessControl &EPC;
|
ExecutorProcessControl &EPC;
|
||||||
@ -223,6 +228,7 @@ private:
|
|||||||
ExecutorAddress orc_rt_macho_platform_bootstrap;
|
ExecutorAddress orc_rt_macho_platform_bootstrap;
|
||||||
ExecutorAddress orc_rt_macho_platform_shutdown;
|
ExecutorAddress orc_rt_macho_platform_shutdown;
|
||||||
ExecutorAddress orc_rt_macho_register_object_sections;
|
ExecutorAddress orc_rt_macho_register_object_sections;
|
||||||
|
ExecutorAddress orc_rt_macho_create_pthread_key;
|
||||||
|
|
||||||
DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
|
DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
|
||||||
|
|
||||||
@ -233,11 +239,13 @@ private:
|
|||||||
std::vector<MachOPerObjectSectionsToRegister> BootstrapPOSRs;
|
std::vector<MachOPerObjectSectionsToRegister> BootstrapPOSRs;
|
||||||
|
|
||||||
DenseMap<JITTargetAddress, JITDylib *> HeaderAddrToJITDylib;
|
DenseMap<JITTargetAddress, JITDylib *> HeaderAddrToJITDylib;
|
||||||
|
DenseMap<JITDylib *, uint64_t> JITDylibToPThreadKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace shared {
|
namespace shared {
|
||||||
|
|
||||||
using SPSMachOPerObjectSectionsToRegister = SPSTuple<SPSExecutorAddressRange>;
|
using SPSMachOPerObjectSectionsToRegister =
|
||||||
|
SPSTuple<SPSExecutorAddressRange, SPSExecutorAddressRange>;
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class SPSSerializationTraits<SPSMachOPerObjectSectionsToRegister,
|
class SPSSerializationTraits<SPSMachOPerObjectSectionsToRegister,
|
||||||
@ -246,19 +254,19 @@ class SPSSerializationTraits<SPSMachOPerObjectSectionsToRegister,
|
|||||||
public:
|
public:
|
||||||
static size_t size(const MachOPerObjectSectionsToRegister &MOPOSR) {
|
static size_t size(const MachOPerObjectSectionsToRegister &MOPOSR) {
|
||||||
return SPSMachOPerObjectSectionsToRegister::AsArgList::size(
|
return SPSMachOPerObjectSectionsToRegister::AsArgList::size(
|
||||||
MOPOSR.EHFrameSection);
|
MOPOSR.EHFrameSection, MOPOSR.ThreadDataSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool serialize(SPSOutputBuffer &OB,
|
static bool serialize(SPSOutputBuffer &OB,
|
||||||
const MachOPerObjectSectionsToRegister &MOPOSR) {
|
const MachOPerObjectSectionsToRegister &MOPOSR) {
|
||||||
return SPSMachOPerObjectSectionsToRegister::AsArgList::serialize(
|
return SPSMachOPerObjectSectionsToRegister::AsArgList::serialize(
|
||||||
OB, MOPOSR.EHFrameSection);
|
OB, MOPOSR.EHFrameSection, MOPOSR.ThreadDataSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool deserialize(SPSInputBuffer &IB,
|
static bool deserialize(SPSInputBuffer &IB,
|
||||||
MachOPerObjectSectionsToRegister &MOPOSR) {
|
MachOPerObjectSectionsToRegister &MOPOSR) {
|
||||||
return SPSMachOPerObjectSectionsToRegister::AsArgList::deserialize(
|
return SPSMachOPerObjectSectionsToRegister::AsArgList::deserialize(
|
||||||
IB, MOPOSR.EHFrameSection);
|
IB, MOPOSR.EHFrameSection, MOPOSR.ThreadDataSection);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -313,6 +313,14 @@ private:
|
|||||||
Addend = *(const little32_t *)FixupContent - 4;
|
Addend = *(const little32_t *)FixupContent - 4;
|
||||||
Kind = x86_64::RequestGOTAndTransformToDelta32;
|
Kind = x86_64::RequestGOTAndTransformToDelta32;
|
||||||
break;
|
break;
|
||||||
|
case MachOPCRel32TLV:
|
||||||
|
if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))
|
||||||
|
TargetSymbol = TargetSymbolOrErr->GraphSymbol;
|
||||||
|
else
|
||||||
|
return TargetSymbolOrErr.takeError();
|
||||||
|
Addend = *(const little32_t *)FixupContent;
|
||||||
|
Kind = x86_64::RequestTLVPAndTransformToPCRel32TLVPLoadRelaxable;
|
||||||
|
break;
|
||||||
case MachOPointer32:
|
case MachOPointer32:
|
||||||
if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))
|
if (auto TargetSymbolOrErr = findSymbolByIndex(RI.r_symbolnum))
|
||||||
TargetSymbol = TargetSymbolOrErr->GraphSymbol;
|
TargetSymbol = TargetSymbolOrErr->GraphSymbol;
|
||||||
@ -392,9 +400,6 @@ private:
|
|||||||
assert(TargetSymbol && "No target symbol from parsePairRelocation?");
|
assert(TargetSymbol && "No target symbol from parsePairRelocation?");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MachOPCRel32TLV:
|
|
||||||
return make_error<JITLinkError>(
|
|
||||||
"MachO TLV relocations not yet supported");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVM_DEBUG({
|
LLVM_DEBUG({
|
||||||
|
@ -128,6 +128,9 @@ constexpr MachOHeaderMaterializationUnit::HeaderSymbol
|
|||||||
|
|
||||||
StringRef EHFrameSectionName = "__TEXT,__eh_frame";
|
StringRef EHFrameSectionName = "__TEXT,__eh_frame";
|
||||||
StringRef ModInitFuncSectionName = "__DATA,__mod_init_func";
|
StringRef ModInitFuncSectionName = "__DATA,__mod_init_func";
|
||||||
|
StringRef ThreadBSSSectionName = "__DATA,__thread_bss";
|
||||||
|
StringRef ThreadDataSectionName = "__DATA,__thread_data";
|
||||||
|
StringRef ThreadVarsSectionName = "__DATA,__thread_vars";
|
||||||
|
|
||||||
StringRef InitSectionNames[] = {ModInitFuncSectionName};
|
StringRef InitSectionNames[] = {ModInitFuncSectionName};
|
||||||
|
|
||||||
@ -478,7 +481,8 @@ Error MachOPlatform::bootstrapMachORuntime(JITDylib &PlatformJD) {
|
|||||||
{"___orc_rt_macho_platform_bootstrap", &orc_rt_macho_platform_bootstrap},
|
{"___orc_rt_macho_platform_bootstrap", &orc_rt_macho_platform_bootstrap},
|
||||||
{"___orc_rt_macho_platform_shutdown", &orc_rt_macho_platform_shutdown},
|
{"___orc_rt_macho_platform_shutdown", &orc_rt_macho_platform_shutdown},
|
||||||
{"___orc_rt_macho_register_object_sections",
|
{"___orc_rt_macho_register_object_sections",
|
||||||
&orc_rt_macho_register_object_sections}};
|
&orc_rt_macho_register_object_sections},
|
||||||
|
{"___orc_rt_macho_create_pthread_key", &orc_rt_macho_create_pthread_key}};
|
||||||
|
|
||||||
SymbolLookupSet RuntimeSymbols;
|
SymbolLookupSet RuntimeSymbols;
|
||||||
std::vector<std::pair<SymbolStringPtr, ExecutorAddress *>> AddrsToRecord;
|
std::vector<std::pair<SymbolStringPtr, ExecutorAddress *>> AddrsToRecord;
|
||||||
@ -573,6 +577,20 @@ Error MachOPlatform::registerPerObjectSections(
|
|||||||
return ErrResult;
|
return ErrResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Expected<uint64_t> MachOPlatform::createPThreadKey() {
|
||||||
|
if (!orc_rt_macho_create_pthread_key)
|
||||||
|
return make_error<StringError>(
|
||||||
|
"Attempting to create pthread key in target, but runtime support has "
|
||||||
|
"not been loaded yet",
|
||||||
|
inconvertibleErrorCode());
|
||||||
|
|
||||||
|
Expected<uint64_t> Result(0);
|
||||||
|
if (auto Err = EPC.runSPSWrapper<SPSExpected<uint64_t>(void)>(
|
||||||
|
orc_rt_macho_create_pthread_key.getValue(), Result))
|
||||||
|
return std::move(Err);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
void MachOPlatform::MachOPlatformPlugin::modifyPassConfig(
|
void MachOPlatform::MachOPlatformPlugin::modifyPassConfig(
|
||||||
MaterializationResponsibility &MR, jitlink::LinkGraph &LG,
|
MaterializationResponsibility &MR, jitlink::LinkGraph &LG,
|
||||||
jitlink::PassConfiguration &Config) {
|
jitlink::PassConfiguration &Config) {
|
||||||
@ -590,8 +608,8 @@ void MachOPlatform::MachOPlatformPlugin::modifyPassConfig(
|
|||||||
if (MR.getInitializerSymbol())
|
if (MR.getInitializerSymbol())
|
||||||
addInitializerSupportPasses(MR, Config);
|
addInitializerSupportPasses(MR, Config);
|
||||||
|
|
||||||
// Add passes for eh-frame support.
|
// Add passes for eh-frame and TLV support.
|
||||||
addEHSupportPasses(MR, Config);
|
addEHAndTLVSupportPasses(MR, Config);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectLinkingLayer::Plugin::SyntheticSymbolDependenciesMap
|
ObjectLinkingLayer::Plugin::SyntheticSymbolDependenciesMap
|
||||||
@ -645,10 +663,18 @@ void MachOPlatform::MachOPlatformPlugin::addMachOHeaderSupportPasses(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MachOPlatform::MachOPlatformPlugin::addEHSupportPasses(
|
void MachOPlatform::MachOPlatformPlugin::addEHAndTLVSupportPasses(
|
||||||
MaterializationResponsibility &MR, jitlink::PassConfiguration &Config) {
|
MaterializationResponsibility &MR, jitlink::PassConfiguration &Config) {
|
||||||
|
|
||||||
// Add a pass to register the final addresses of the eh-frame sections
|
// Insert TLV lowering at the start of the PostPrunePasses, since we want
|
||||||
|
// it to run before GOT/PLT lowering.
|
||||||
|
Config.PostPrunePasses.insert(
|
||||||
|
Config.PostPrunePasses.begin(),
|
||||||
|
[this, &JD = MR.getTargetJITDylib()](jitlink::LinkGraph &G) {
|
||||||
|
return fixTLVSectionsAndEdges(G, JD);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add a pass to register the final addresses of the eh-frame and TLV sections
|
||||||
// with the runtime.
|
// with the runtime.
|
||||||
Config.PostFixupPasses.push_back([this](jitlink::LinkGraph &G) -> Error {
|
Config.PostFixupPasses.push_back([this](jitlink::LinkGraph &G) -> Error {
|
||||||
MachOPerObjectSectionsToRegister POSR;
|
MachOPerObjectSectionsToRegister POSR;
|
||||||
@ -660,7 +686,33 @@ void MachOPlatform::MachOPlatformPlugin::addEHSupportPasses(
|
|||||||
ExecutorAddress(R.getEnd())};
|
ExecutorAddress(R.getEnd())};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (POSR.EHFrameSection.StartAddress) {
|
// Get a pointer to the thread data section if there is one. It will be used
|
||||||
|
// below.
|
||||||
|
jitlink::Section *ThreadDataSection =
|
||||||
|
G.findSectionByName(ThreadDataSectionName);
|
||||||
|
|
||||||
|
// Handle thread BSS section if there is one.
|
||||||
|
if (auto *ThreadBSSSection = G.findSectionByName(ThreadBSSSectionName)) {
|
||||||
|
// If there's already a thread data section in this graph then merge the
|
||||||
|
// thread BSS section content into it, otherwise just treat the thread
|
||||||
|
// BSS section as the thread data section.
|
||||||
|
if (ThreadDataSection)
|
||||||
|
G.mergeSections(*ThreadDataSection, *ThreadBSSSection);
|
||||||
|
else
|
||||||
|
ThreadDataSection = ThreadBSSSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Having merged thread BSS (if present) and thread data (if present),
|
||||||
|
// record the resulting section range.
|
||||||
|
if (ThreadDataSection) {
|
||||||
|
jitlink::SectionRange R(*ThreadDataSection);
|
||||||
|
if (!R.empty())
|
||||||
|
POSR.ThreadDataSection = {ExecutorAddress(R.getStart()),
|
||||||
|
ExecutorAddress(R.getEnd())};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (POSR.EHFrameSection.StartAddress ||
|
||||||
|
POSR.ThreadDataSection.StartAddress) {
|
||||||
|
|
||||||
// If we're still bootstrapping the runtime then just record this
|
// If we're still bootstrapping the runtime then just record this
|
||||||
// frame for now.
|
// frame for now.
|
||||||
@ -738,5 +790,61 @@ Error MachOPlatform::MachOPlatformPlugin::registerInitSections(
|
|||||||
return MP.registerInitInfo(JD, InitSections);
|
return MP.registerInitInfo(JD, InitSections);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error MachOPlatform::MachOPlatformPlugin::fixTLVSectionsAndEdges(
|
||||||
|
jitlink::LinkGraph &G, JITDylib &JD) {
|
||||||
|
|
||||||
|
// Rename external references to __tlv_bootstrap to ___orc_rt_tlv_get_addr.
|
||||||
|
for (auto *Sym : G.external_symbols())
|
||||||
|
if (Sym->getName() == "__tlv_bootstrap") {
|
||||||
|
Sym->setName("___orc_rt_macho_tlv_get_addr");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store key in __thread_vars struct fields.
|
||||||
|
if (auto *ThreadDataSec = G.findSectionByName(ThreadVarsSectionName)) {
|
||||||
|
Optional<uint64_t> Key;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> Lock(MP.PlatformMutex);
|
||||||
|
auto I = MP.JITDylibToPThreadKey.find(&JD);
|
||||||
|
if (I != MP.JITDylibToPThreadKey.end())
|
||||||
|
Key = I->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Key) {
|
||||||
|
if (auto KeyOrErr = MP.createPThreadKey())
|
||||||
|
Key = *KeyOrErr;
|
||||||
|
else
|
||||||
|
return KeyOrErr.takeError();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t PlatformKeyBits =
|
||||||
|
support::endian::byte_swap(*Key, G.getEndianness());
|
||||||
|
|
||||||
|
for (auto *B : ThreadDataSec->blocks()) {
|
||||||
|
if (B->getSize() != 3 * G.getPointerSize())
|
||||||
|
return make_error<StringError>("__thread_vars block at " +
|
||||||
|
formatv("{0:x}", B->getAddress()) +
|
||||||
|
" has unexpected size",
|
||||||
|
inconvertibleErrorCode());
|
||||||
|
|
||||||
|
auto NewBlockContent = G.allocateBuffer(B->getSize());
|
||||||
|
llvm::copy(B->getContent(), NewBlockContent.data());
|
||||||
|
memcpy(NewBlockContent.data() + G.getPointerSize(), &PlatformKeyBits,
|
||||||
|
G.getPointerSize());
|
||||||
|
B->setContent(NewBlockContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform any TLV edges into GOT edges.
|
||||||
|
for (auto *B : G.blocks())
|
||||||
|
for (auto &E : B->edges())
|
||||||
|
if (E.getKind() ==
|
||||||
|
jitlink::x86_64::RequestTLVPAndTransformToPCRel32TLVPLoadRelaxable)
|
||||||
|
E.setKind(
|
||||||
|
jitlink::x86_64::RequestGOTAndTransformToPCRel32GOTLoadRelaxable);
|
||||||
|
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
|
||||||
} // End namespace orc.
|
} // End namespace orc.
|
||||||
} // End namespace llvm.
|
} // End namespace llvm.
|
||||||
|
Loading…
Reference in New Issue
Block a user