From 64237b26dd18cf5e6f7f6bf7af12cd893d64ccab Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Sat, 16 May 2015 21:50:58 -0700 Subject: [PATCH] Greatly simplify dlpath() implementation on OSX --- src/sys.c | 79 +++++++------------------------------------------------ 1 file changed, 10 insertions(+), 69 deletions(-) diff --git a/src/sys.c b/src/sys.c index eaec6e0c75b7c..a32c5925c866c 100644 --- a/src/sys.c +++ b/src/sys.c @@ -561,66 +561,6 @@ DLLEXPORT size_t jl_get_alignment(jl_datatype_t *ty) return ty->alignment; } - -// Dynamic Library interrogation - -#ifdef __APPLE__ -// This code gratefully lifted from: http://stackoverflow.com/questions/20481058 -#ifdef __LP64__ -typedef struct mach_header_64 mach_header_t; -typedef struct segment_command_64 segment_command_t; -typedef struct nlist_64 nlist_t; -#else -typedef struct mach_header mach_header_t; -typedef struct segment_command segment_command_t; -typedef struct nlist nlist_t; -#endif - -static const char *first_external_symbol_for_image(const mach_header_t *header) -{ - Dl_info info; - if (dladdr(header, &info) == 0) - return NULL; - - segment_command_t *seg_linkedit = NULL; - segment_command_t *seg_text = NULL; - struct symtab_command *symtab = NULL; - - struct load_command *cmd = (struct load_command *)((intptr_t)header + sizeof(mach_header_t)); - for (uint32_t i = 0; i < header->ncmds; i++, cmd = (struct load_command *)((intptr_t)cmd + cmd->cmdsize)) { - switch(cmd->cmd) { - case LC_SEGMENT: - case LC_SEGMENT_64: - if (!strcmp(((segment_command_t *)cmd)->segname, SEG_TEXT)) - seg_text = (segment_command_t *)cmd; - else if (!strcmp(((segment_command_t *)cmd)->segname, SEG_LINKEDIT)) - seg_linkedit = (segment_command_t *)cmd; - break; - - case LC_SYMTAB: - symtab = (struct symtab_command *)cmd; - break; - } - } - - if ((seg_text == NULL) || (seg_linkedit == NULL) || (symtab == NULL)) - return NULL; - - intptr_t file_slide = ((intptr_t)seg_linkedit->vmaddr - (intptr_t)seg_text->vmaddr) - seg_linkedit->fileoff; - intptr_t strings = (intptr_t)header + (symtab->stroff + file_slide); - nlist_t *sym = (nlist_t *)((intptr_t)header + (symtab->symoff + file_slide)); - - for (uint32_t i = 0; i < symtab->nsyms; i++, sym++) { - if ((sym->n_type & N_EXT) != N_EXT || !sym->n_value) - continue; - - return (const char*)strings + sym->n_un.n_strx; - } - - return NULL; -} -#endif - // Takes a handle (as returned from dlopen()) and returns the absolute path to the image loaded DLLEXPORT const char *jl_pathname_for_handle(uv_lib_t *uv_lib) { @@ -629,16 +569,17 @@ DLLEXPORT const char *jl_pathname_for_handle(uv_lib_t *uv_lib) void *handle = uv_lib->handle; #ifdef __APPLE__ + // Iterate through all images currently in memory for (int32_t i = _dyld_image_count(); i >= 0 ; i--) { - const char *first_symbol = first_external_symbol_for_image((const mach_header_t *)_dyld_get_image_header(i)); - if (first_symbol && strlen(first_symbol) > 1) { - handle = (void*)((intptr_t)handle | 1); // in order to trigger findExportedSymbol instead of findExportedSymbolInImageOrDependentImages. See `dlsym` implementation at http://opensource.apple.com/source/dyld/dyld-239.3/src/dyldAPIs.cpp - first_symbol++; // in order to remove the leading underscore - void *address = dlsym(handle, first_symbol); - Dl_info info; - if (dladdr(address, &info)) - return info.dli_fname; - } + // dlopen() each image, check handle + const char *image_name = _dyld_get_image_name(i); + uv_lib_t *probe_lib = jl_load_dynamic_library(image_name, JL_RTLD_DEFAULT); + void *probe_handle = probe_lib->handle; + uv_dlclose(probe_lib); + + // If the handle is the same as what was passed in, return this image name + if (handle == probe_handle) + return image_name; } #elif defined(_OS_WINDOWS_)