1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +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;
};
using RawPointerSectionList = std::vector<SectionExtent>;
void setObjCImageInfoAddr(JITTargetAddress ObjCImageInfoAddr) {
this->ObjCImageInfoAddr = ObjCImageInfoAddr;
}
@ -47,20 +49,31 @@ public:
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:
using RawPointerSectionList = std::vector<SectionExtent>;
JITTargetAddress ObjCImageInfoAddr;
RawPointerSectionList ModInitSections;

View File

@ -555,18 +555,34 @@ public:
<< "\"\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) {
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();
if (auto Err = KV.second.registerObjCClasses()) {
// FIXME: Roll back registrations on error?
return Err;
}
}
for (auto &KV : *InitSeq)
KV.second.runModInits();
} else
return InitSeq.takeError();
KV.second.runModInits();
}
return Error::success();
}

View File

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