From 5471766f9d16fbc5a82dd9503729747d901242a1 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Thu, 8 Jul 2021 14:10:15 +1000 Subject: [PATCH] [ORC] Replace MachOJITDylibInitializers::SectionExtent with ExecutorAddressRange MachOJITDylibInitializers::SectionExtent represented the address range of a section as an (address, size) pair. The new ExecutorAddressRange type generalizes this to an address range (for any object, not necessarily a section) represented as a (start-address, end-address) pair. The aim is to express more of ORC (and the ORC runtime) in terms of simple types that can be serialized/deserialized via SPS. This will simplify SPS-based RPC involving arguments/return-values of these types. --- .../llvm/ExecutionEngine/Orc/MachOPlatform.h | 23 +++--- .../Orc/Shared/CommonOrcRuntimeTypes.h | 66 +++++++++++++++++ .../lib/ExecutionEngine/Orc/MachOPlatform.cpp | 71 +++++++++++-------- 3 files changed, 115 insertions(+), 45 deletions(-) create mode 100644 llvm/include/llvm/ExecutionEngine/Orc/Shared/CommonOrcRuntimeTypes.h diff --git a/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h b/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h index f04bef161ea7..f9d0b587a1be 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h @@ -17,6 +17,7 @@ #include "llvm/ExecutionEngine/Orc/Core.h" #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" +#include "llvm/ExecutionEngine/Orc/Shared/CommonOrcRuntimeTypes.h" #include #include @@ -31,21 +32,13 @@ 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; + using RawPointerSectionList = std::vector; void setObjCImageInfoAddr(JITTargetAddress ObjCImageInfoAddr) { this->ObjCImageInfoAddr = ObjCImageInfoAddr; } - void addModInitsSection(SectionExtent ModInit) { + void addModInitsSection(shared::ExecutorAddressRange ModInit) { ModInitSections.push_back(std::move(ModInit)); } @@ -53,7 +46,7 @@ public: return ModInitSections; } - void addObjCSelRefsSection(SectionExtent ObjCSelRefs) { + void addObjCSelRefsSection(shared::ExecutorAddressRange ObjCSelRefs) { ObjCSelRefsSections.push_back(std::move(ObjCSelRefs)); } @@ -61,7 +54,7 @@ public: return ObjCSelRefsSections; } - void addObjCClassListSection(SectionExtent ObjCClassList) { + void addObjCClassListSection(shared::ExecutorAddressRange ObjCClassList) { ObjCClassListSections.push_back(std::move(ObjCClassList)); } @@ -152,9 +145,9 @@ private: }; void registerInitInfo(JITDylib &JD, JITTargetAddress ObjCImageInfoAddr, - MachOJITDylibInitializers::SectionExtent ModInits, - MachOJITDylibInitializers::SectionExtent ObjCSelRefs, - MachOJITDylibInitializers::SectionExtent ObjCClassList); + shared::ExecutorAddressRange ModInits, + shared::ExecutorAddressRange ObjCSelRefs, + shared::ExecutorAddressRange ObjCClassList); ExecutionSession &ES; ObjectLinkingLayer &ObjLinkingLayer; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/CommonOrcRuntimeTypes.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/CommonOrcRuntimeTypes.h new file mode 100644 index 000000000000..8b0e6272a555 --- /dev/null +++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/CommonOrcRuntimeTypes.h @@ -0,0 +1,66 @@ +//===------------------- CommonOrcRuntimeTypes.h ----------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// Generic types usable with SPS and the ORC runtime. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_COMMONORCRUNTIMETYPES_H +#define LLVM_EXECUTIONENGINE_ORC_SHARED_COMMONORCRUNTIMETYPES_H + +#include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h" + +namespace llvm { +namespace orc { +namespace shared { + +/// Represents an address range in the exceutor process. +struct ExecutorAddressRange { + ExecutorAddressRange() = default; + ExecutorAddressRange(JITTargetAddress StartAddress, + JITTargetAddress EndAddress) + : StartAddress(StartAddress), EndAddress(EndAddress) {} + + bool empty() const { return StartAddress == EndAddress; } + size_t size() const { return EndAddress - StartAddress; } + + JITTargetAddress StartAddress = 0; + JITTargetAddress EndAddress = 0; +}; + +using SPSExecutorAddressRange = + SPSTuple; + +/// Serialization traits for address ranges. +template <> +class SPSSerializationTraits { +public: + static size_t size(const ExecutorAddressRange &Value) { + return SPSArgList::size( + Value.StartAddress, Value.EndAddress); + } + + static bool serialize(SPSOutputBuffer &BOB, + const ExecutorAddressRange &Value) { + return SPSArgList::serialize( + BOB, Value.StartAddress, Value.EndAddress); + } + + static bool deserialize(SPSInputBuffer &BIB, ExecutorAddressRange &Value) { + return SPSArgList::deserialize( + BIB, Value.StartAddress, Value.EndAddress); + } +}; + +using SPSExecutorAddressRangeSequence = SPSSequence; + +} // End namespace shared. +} // End namespace orc. +} // End namespace llvm. + +#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_COMMONORCRUNTIMETYPES_H diff --git a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp index 80df097a0741..74c88b0c1c85 100644 --- a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp +++ b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp @@ -88,11 +88,15 @@ bool objCRegistrationEnabled() { void MachOJITDylibInitializers::runModInits() const { for (const auto &ModInit : ModInitSections) { - for (uint64_t I = 0; I != ModInit.NumPtrs; ++I) { - auto *InitializerAddr = jitTargetAddressToPointer( - ModInit.Address + (I * sizeof(uintptr_t))); - auto *Initializer = - jitTargetAddressToFunction(*InitializerAddr); + assert(ModInit.size() % sizeof(uintptr_t) == 0 && + "ModInit section size is not a pointer multiple?"); + for (uintptr_t * + InitPtr = + jitTargetAddressToPointer(ModInit.StartAddress), + *InitEnd = + jitTargetAddressToPointer(ModInit.EndAddress); + InitPtr != InitEnd; ++InitPtr) { + auto *Initializer = reinterpret_cast(*InitPtr); Initializer(); } } @@ -102,8 +106,11 @@ void MachOJITDylibInitializers::registerObjCSelectors() const { assert(objCRegistrationEnabled() && "ObjC registration not enabled."); for (const auto &ObjCSelRefs : ObjCSelRefsSections) { - for (uint64_t I = 0; I != ObjCSelRefs.NumPtrs; ++I) { - auto SelEntryAddr = ObjCSelRefs.Address + (I * sizeof(uintptr_t)); + assert(ObjCSelRefs.size() % sizeof(uintptr_t) == 0 && + "ObjCSelRefs section size is not a pointer multiple?"); + for (JITTargetAddress SelEntryAddr = ObjCSelRefs.StartAddress; + SelEntryAddr != ObjCSelRefs.EndAddress; + SelEntryAddr += sizeof(uintptr_t)) { const auto *SelName = *jitTargetAddressToPointer(SelEntryAddr); auto Sel = sel_registerName(SelName); @@ -128,8 +135,11 @@ Error MachOJITDylibInitializers::registerObjCClasses() const { auto ClassSelector = sel_registerName("class"); for (const auto &ObjCClassList : ObjCClassListSections) { - for (uint64_t I = 0; I != ObjCClassList.NumPtrs; ++I) { - auto ClassPtrAddr = ObjCClassList.Address + (I * sizeof(uintptr_t)); + assert(ObjCClassList.size() % sizeof(uintptr_t) == 0 && + "ObjCClassList section size is not a pointer multiple?"); + for (JITTargetAddress ClassPtrAddr = ObjCClassList.StartAddress; + ClassPtrAddr != ObjCClassList.EndAddress; + ClassPtrAddr += sizeof(uintptr_t)) { auto Cls = *jitTargetAddressToPointer(ClassPtrAddr); auto *ClassCompiled = *jitTargetAddressToPointer(ClassPtrAddr); @@ -264,37 +274,36 @@ MachOPlatform::getDeinitializerSequence(JITDylib &JD) { void MachOPlatform::registerInitInfo( JITDylib &JD, JITTargetAddress ObjCImageInfoAddr, - MachOJITDylibInitializers::SectionExtent ModInits, - MachOJITDylibInitializers::SectionExtent ObjCSelRefs, - MachOJITDylibInitializers::SectionExtent ObjCClassList) { + shared::ExecutorAddressRange ModInits, + shared::ExecutorAddressRange ObjCSelRefs, + shared::ExecutorAddressRange ObjCClassList) { std::lock_guard Lock(InitSeqsMutex); auto &InitSeq = InitSeqs[&JD]; InitSeq.setObjCImageInfoAddr(ObjCImageInfoAddr); - if (ModInits.Address) + if (ModInits.StartAddress) InitSeq.addModInitsSection(std::move(ModInits)); - if (ObjCSelRefs.Address) + if (ObjCSelRefs.StartAddress) InitSeq.addObjCSelRefsSection(std::move(ObjCSelRefs)); - if (ObjCClassList.Address) + if (ObjCClassList.StartAddress) InitSeq.addObjCClassListSection(std::move(ObjCClassList)); } -static Expected +static Expected getSectionExtent(jitlink::LinkGraph &G, StringRef SectionName) { auto *Sec = G.findSectionByName(SectionName); if (!Sec) - return MachOJITDylibInitializers::SectionExtent(); + return shared::ExecutorAddressRange(); jitlink::SectionRange R(*Sec); if (R.getSize() % G.getPointerSize() != 0) return make_error(SectionName + " section size is not a " "multiple of the pointer size", inconvertibleErrorCode()); - return MachOJITDylibInitializers::SectionExtent( - R.getStart(), R.getSize() / G.getPointerSize()); + return shared::ExecutorAddressRange{R.getStart(), R.getEnd()}; } void MachOPlatform::InitScraperPlugin::modifyPassConfig( @@ -326,8 +335,7 @@ void MachOPlatform::InitScraperPlugin::modifyPassConfig( Config.PostFixupPasses.push_back([this, &JD = MR.getTargetJITDylib()]( jitlink::LinkGraph &G) -> Error { - MachOJITDylibInitializers::SectionExtent ModInits, ObjCSelRefs, - ObjCClassList; + shared::ExecutorAddressRange ModInits, ObjCSelRefs, ObjCClassList; JITTargetAddress ObjCImageInfoAddr = 0; if (auto *ObjCImageInfoSec = @@ -359,23 +367,26 @@ void MachOPlatform::InitScraperPlugin::modifyPassConfig( LLVM_DEBUG({ dbgs() << "MachOPlatform: Scraped " << G.getName() << " init sections:\n"; dbgs() << " __objc_selrefs: "; - if (ObjCSelRefs.NumPtrs) - dbgs() << ObjCSelRefs.NumPtrs << " pointer(s) at " - << formatv("{0:x16}", ObjCSelRefs.Address) << "\n"; + auto NumObjCSelRefs = ObjCSelRefs.size() / sizeof(uintptr_t); + if (NumObjCSelRefs) + dbgs() << NumObjCSelRefs << " pointer(s) at " + << formatv("{0:x16}", ObjCSelRefs.StartAddress) << "\n"; else dbgs() << "none\n"; dbgs() << " __objc_classlist: "; - if (ObjCClassList.NumPtrs) - dbgs() << ObjCClassList.NumPtrs << " pointer(s) at " - << formatv("{0:x16}", ObjCClassList.Address) << "\n"; + auto NumObjCClasses = ObjCClassList.size() / sizeof(uintptr_t); + if (NumObjCClasses) + dbgs() << NumObjCClasses << " pointer(s) at " + << formatv("{0:x16}", ObjCClassList.StartAddress) << "\n"; else dbgs() << "none\n"; dbgs() << " __mod_init_func: "; - if (ModInits.NumPtrs) - dbgs() << ModInits.NumPtrs << " pointer(s) at " - << formatv("{0:x16}", ModInits.Address) << "\n"; + auto NumModInits = ModInits.size() / sizeof(uintptr_t); + if (NumModInits) + dbgs() << NumModInits << " pointer(s) at " + << formatv("{0:x16}", ModInits.StartAddress) << "\n"; else dbgs() << "none\n"; });