+ size_t slide(_not(size_t));
+ const nlist_xx *symbols(NULL);
+ const char *strings(NULL);
+
+ forlc (segment, mach, LC_SEGMENT_XX, segment_command_xx) {
+ if (segment->fileoff == 0)
+ slide = reinterpret_cast<size_t>(mach) - segment->vmaddr;
+ if (stp->symoff >= segment->fileoff && stp->symoff < segment->fileoff + segment->filesize)
+ symbols = reinterpret_cast<const nlist_xx *>(stp->symoff - segment->fileoff + segment->vmaddr + slide);
+ if (stp->stroff >= segment->fileoff && stp->stroff < segment->fileoff + segment->filesize)
+ strings = reinterpret_cast<const char *>(stp->stroff - segment->fileoff + segment->vmaddr + slide);
+ }
+
+ if (slide == _not(size_t) || symbols == NULL || strings == NULL)
+ return NULL;
+
+ for (size_t i(0); i != stp->nsyms; ++i) {
+ const nlist_xx *symbol(&symbols[i]);
+ if (symbol->n_un.n_strx == 0 || (symbol->n_type & N_STAB) != 0)
+ continue;
+
+ const char *nambuf(strings + symbol->n_un.n_strx);
+ if ($strcmp(name, nambuf) != 0)
+ continue;
+
+ uintptr_t value(symbol->n_value);
+ if (value == 0)
+ continue;
+
+#ifdef __arm__
+ if ((symbol->n_desc & N_ARM_THUMB_DEF) != 0)
+ value |= 0x00000001;
+#endif
+
+ value += slide;
+ return reinterpret_cast<void *>(value);
+ }
+
+ return NULL;
+}
+
+template <typename Type_>
+static _finline void cyset(Type_ &function, const char *name, const mach_header_xx *mach) {
+ function = reinterpret_cast<Type_>(Symbol(mach, name));
+}
+
+static _finline const mach_header_xx *Library(Baton *baton, const char *name) {
+ struct dyld_all_image_infos *infos(reinterpret_cast<struct dyld_all_image_infos *>(baton->dyld));
+ return Library(infos, name);
+}
+
+void *Routine(void *arg) {
+ Baton *baton(reinterpret_cast<Baton *>(arg));
+
+ const mach_header_xx *dyld(NULL);
+ if (dyld == NULL)
+ dyld = Library(baton, "/usr/lib/system/libdyld.dylib");
+ if (dyld == NULL)
+ dyld = Library(baton, "/usr/lib/libSystem.B.dylib");
+
+ char *(*$dlerror)();
+ cyset($dlerror, "_dlerror", dyld);
+
+ void *(*$dlopen)(const char *, int);
+ cyset($dlopen, "_dlopen", dyld);
+
+ void *handle($dlopen(baton->library, RTLD_LAZY | RTLD_LOCAL));