1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

[ORC] Remove hard dependency on libobjc when using MachOPlatform with LLJIT.

The LLJIT::MachOPlatformSupport class used to unconditionally attempt to
register __objc_selrefs and __objc_classlist sections. If libobjc had not
been loaded this resulted in an assertion, even if no objc sections were
actually present. This patch replaces this unconditional registration with
a check that no objce sections are present if libobjc has not been loaded.
This will allow clients to use MachOPlatform with LLJIT without requiring
libobjc for non-objc code.
This commit is contained in:
Lang Hames 2020-03-04 21:23:51 -08:00
parent d13ab42a5a
commit 87a444bd04
3 changed files with 38 additions and 9 deletions

View File

@ -39,6 +39,8 @@ public:
uint64_t NumPtrs = 0; uint64_t NumPtrs = 0;
}; };
using RawPointerSectionList = std::vector<SectionExtent>;
void setObjCImageInfoAddr(JITTargetAddress ObjCImageInfoAddr) { void setObjCImageInfoAddr(JITTargetAddress ObjCImageInfoAddr) {
this->ObjCImageInfoAddr = ObjCImageInfoAddr; this->ObjCImageInfoAddr = ObjCImageInfoAddr;
} }
@ -47,20 +49,31 @@ public:
ModInitSections.push_back(std::move(ModInit)); ModInitSections.push_back(std::move(ModInit));
} }
const RawPointerSectionList &getModInitsSections() const {
return ModInitSections;
}
void addObjCSelRefsSection(SectionExtent ObjCSelRefs) { void addObjCSelRefsSection(SectionExtent ObjCSelRefs) {
ObjCSelRefsSections.push_back(std::move(ObjCSelRefs)); ObjCSelRefsSections.push_back(std::move(ObjCSelRefs));
} }
const RawPointerSectionList &getObjCSelRefsSections() const {
return ObjCSelRefsSections;
}
void addObjCClassListSection(SectionExtent ObjCClassList) { void addObjCClassListSection(SectionExtent ObjCClassList) {
ObjCClassListSections.push_back(std::move(ObjCClassList)); ObjCClassListSections.push_back(std::move(ObjCClassList));
} }
const RawPointerSectionList &getObjCClassListSections() const {
return ObjCClassListSections;
}
void runModInits() const; void runModInits() const;
void registerObjCSelectors() const; void registerObjCSelectors() const;
Error registerObjCClasses() const; Error registerObjCClasses() const;
private: private:
using RawPointerSectionList = std::vector<SectionExtent>;
JITTargetAddress ObjCImageInfoAddr; JITTargetAddress ObjCImageInfoAddr;
RawPointerSectionList ModInitSections; RawPointerSectionList ModInitSections;

View File

@ -555,18 +555,34 @@ public:
<< "\"\n"; << "\"\n";
}); });
if (auto InitSeq = MP.getInitializerSequence(JD)) { auto InitSeq = MP.getInitializerSequence(JD);
if (!InitSeq)
return InitSeq.takeError();
// If ObjC is not enabled but there are JIT'd ObjC inits then return
// an error.
if (!objCRegistrationEnabled())
for (auto &KV : *InitSeq) { for (auto &KV : *InitSeq) {
if (!KV.second.getObjCSelRefsSections().empty() ||
!KV.second.getObjCClassListSections().empty())
return make_error<StringError>("JITDylib " + KV.first->getName() +
" contains objc metadata but objc"
" is not enabled",
inconvertibleErrorCode());
}
// Run the initializers.
for (auto &KV : *InitSeq) {
if (objCRegistrationEnabled()) {
KV.second.registerObjCSelectors(); KV.second.registerObjCSelectors();
if (auto Err = KV.second.registerObjCClasses()) { if (auto Err = KV.second.registerObjCClasses()) {
// FIXME: Roll back registrations on error? // FIXME: Roll back registrations on error?
return Err; return Err;
} }
} }
for (auto &KV : *InitSeq) KV.second.runModInits();
KV.second.runModInits(); }
} else
return InitSeq.takeError();
return Error::success(); return Error::success();
} }

View File

@ -81,7 +81,7 @@ Error enableObjCRegistration(const char *PathToLibObjC) {
return Error::success(); return Error::success();
} }
bool objcRegistrationEnabled() { bool objCRegistrationEnabled() {
return ObjCRegistrationAPIState == ObjCRegistrationAPI::Initialized; return ObjCRegistrationAPIState == ObjCRegistrationAPI::Initialized;
} }
@ -98,7 +98,7 @@ void MachOJITDylibInitializers::runModInits() const {
} }
void MachOJITDylibInitializers::registerObjCSelectors() const { void MachOJITDylibInitializers::registerObjCSelectors() const {
assert(objcRegistrationEnabled() && "ObjC registration not enabled."); assert(objCRegistrationEnabled() && "ObjC registration not enabled.");
for (const auto &ObjCSelRefs : ObjCSelRefsSections) { for (const auto &ObjCSelRefs : ObjCSelRefsSections) {
for (uint64_t I = 0; I != ObjCSelRefs.NumPtrs; ++I) { for (uint64_t I = 0; I != ObjCSelRefs.NumPtrs; ++I) {
@ -112,7 +112,7 @@ void MachOJITDylibInitializers::registerObjCSelectors() const {
} }
Error MachOJITDylibInitializers::registerObjCClasses() const { Error MachOJITDylibInitializers::registerObjCClasses() const {
assert(objcRegistrationEnabled() && "ObjC registration not enabled."); assert(objCRegistrationEnabled() && "ObjC registration not enabled.");
struct ObjCClassCompiled { struct ObjCClassCompiled {
void *Metaclass; void *Metaclass;