/* A function called through the vtable to initialise this loader. */ static int vl_init (lt_user_data loader_data) { int errors = 0; if (! dyld_cannot_close) { if (!_dyld_present ()) { ++errors; } else { (void) _dyld_func_lookup ("__dyld_NSAddImage", (unsigned long*) <__addimage); (void) _dyld_func_lookup ("__dyld_NSLookupSymbolInImage", (unsigned long*)<__image_symbol); (void) _dyld_func_lookup ("__dyld_NSIsSymbolNameDefinedInImage", (unsigned long*) <__image_symbol_p); (void) _dyld_func_lookup ("__dyld_NSMakePrivateModulePublic", (unsigned long*) <__module_export); dyld_cannot_close = lt_dladderror ("can't close a dylib"); } } return errors; }
static void* ll_load (lua_State *L, const char* path) { NSObjectFileImage img; NSObjectFileImageReturnCode ret; /* this would be a rare case, but prevents crashing if it happens */ if(!_dyld_present()) { lua_pushliteral(L, "dyld not present"); return nullptr; } ret = NSCreateObjectFileImageFromFile(path, &img); if (ret == NSObjectFileImageSuccess) { NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR); NSDestroyObjectFileImage(img); if (mod == nullptr) pusherror(L); return mod; } lua_pushstring(L, errorfromcode(ret)); return nullptr; }
primitiveExecutableModulesAndOffsets(void) { const struct mach_header *h; const struct mach_header_64 *h64; sqInt i; const char *name; char *nameObjData; sqInt nimages; sqInt resultObj; const struct section *s; const struct section_64 *s64; usqIntptr_t size; usqIntptr_t slide; usqIntptr_t start; sqInt valueObj; # if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 /* _dyld_present was deprecated in 10.5 */ if (!(_dyld_present())) { return primitiveFail(); } # endif /* MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 */ nimages = _dyld_image_count(); resultObj = instantiateClassindexableSize(classArray(), nimages * 4); if (resultObj == 0) { return primitiveFail(); } pushRemappableOop(resultObj); for (i = 0; i < nimages; i += 1) { /* impossible start & size */ start = (size = -1); name = _dyld_get_image_name(i); slide = _dyld_get_image_vmaddr_slide(i); # if __x86_64__ h64 = (const struct mach_header_64 *)_dyld_get_image_header(i); if (!(h64 == null)) { s64 = getsectbynamefromheader_64(h64,SEG_TEXT,SECT_TEXT); if (!(s64 == null)) { start = s64->addr; size = s64->size; } } # else /* __x86_64__ */ h = _dyld_get_image_header(i); if (!(h == null)) { s = getsectbynamefromheader(h,SEG_TEXT,SECT_TEXT); if (!(s == null)) { start = s->addr; size = s->size; } } # endif /* __x86_64__ */ valueObj = instantiateClassindexableSize(classString(), strlen(name)); if (failed()) { popRemappableOop(); return primitiveFail(); } storePointerofObjectwithValue(i * 4, topRemappableOop(), valueObj); nameObjData = arrayValueOf(valueObj); memcpy(nameObjData, name, strlen(name)); valueObj = (BytesPerWord == 8 ? signed64BitIntegerFor(slide) : signed32BitIntegerFor(slide)); if (failed()) { popRemappableOop(); return primitiveFail(); } storePointerofObjectwithValue((i * 4) + 1, topRemappableOop(), valueObj); /* begin positiveMachineIntegerFor: */ valueObj = (BytesPerWord == 8 ? positive64BitIntegerFor(start) : positive32BitIntegerFor(start)); if (failed()) { popRemappableOop(); return primitiveFail(); } storePointerofObjectwithValue((i * 4) + 2, topRemappableOop(), valueObj); /* begin positiveMachineIntegerFor: */ valueObj = (BytesPerWord == 8 ? positive64BitIntegerFor(size) : positive32BitIntegerFor(size)); if (failed()) { popRemappableOop(); return primitiveFail(); } storePointerofObjectwithValue((i * 4) + 3, topRemappableOop(), valueObj); } resultObj = popRemappableOop(); return popthenPush(1, resultObj); }
primitiveExecutableModulesAndOffsets(void) { const struct mach_header *h; sqInt i; const char *name; char *nameObjData; sqInt nimages; sqInt present; sqInt resultObj; const struct section *s; unsigned long size; sqInt slide; unsigned long start; sqInt valueObj; present = _dyld_present(); if (!(present)) { return interpreterProxy->primitiveFail(); } nimages = _dyld_image_count(); resultObj = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), nimages * 4); if (resultObj == 0) { return interpreterProxy->primitiveFail(); } interpreterProxy->pushRemappableOop(resultObj); for (i = 0; i <= (nimages - 1); i += 1) { /* impossible start & size */ start = size = -1; name = _dyld_get_image_name(i); slide = _dyld_get_image_vmaddr_slide(i); h = _dyld_get_image_header(i); if (h != null) { s = getsectbynamefromheader(h,SEG_TEXT,SECT_TEXT); if (s != null) { start = s->addr; size = s->size; } } valueObj = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), strlen(name)); if (interpreterProxy->failed()) { interpreterProxy->pop(1); return interpreterProxy->primitiveFail(); } interpreterProxy->storePointerofObjectwithValue(i * 4, interpreterProxy->topRemappableOop(), valueObj); nameObjData = interpreterProxy->arrayValueOf(valueObj); memcpy(nameObjData, name, strlen(name)); valueObj = interpreterProxy->signed32BitIntegerFor(slide); if (interpreterProxy->failed()) { interpreterProxy->pop(1); return interpreterProxy->primitiveFail(); } interpreterProxy->storePointerofObjectwithValue((i * 4) + 1, interpreterProxy->topRemappableOop(), valueObj); valueObj = interpreterProxy->positive32BitIntegerFor(start); if (interpreterProxy->failed()) { interpreterProxy->pop(1); return interpreterProxy->primitiveFail(); } interpreterProxy->storePointerofObjectwithValue((i * 4) + 2, interpreterProxy->topRemappableOop(), valueObj); valueObj = interpreterProxy->positive32BitIntegerFor(size); if (interpreterProxy->failed()) { interpreterProxy->pop(1); return interpreterProxy->primitiveFail(); } interpreterProxy->storePointerofObjectwithValue((i * 4) + 3, interpreterProxy->topRemappableOop(), valueObj); } resultObj = interpreterProxy->popRemappableOop(); return interpreterProxy->popthenPush(1, resultObj); }