comparison dynload/dynload_syms_mach-o.c @ 382:dd5d03483314

- dynload changes to support macos >= 11.0.1 "built-in dynamic linker cache of all system-provided libraries" (those dylibs are no longer present on the fs)" * dynload_plain test code changes to reflect this * note in doc - changed dynload_plain to not do inode-based tests on windows
author Tassilo Philipp
date Wed, 20 Jan 2021 13:49:43 +0100
parents 7ed642a9c3e9
children 2144287113df
comparison
equal deleted inserted replaced
381:fccbb45a2dae 382:dd5d03483314
37 #include "../autovar/autovar_ARCH.h" 37 #include "../autovar/autovar_ARCH.h"
38 #include "../autovar/autovar_OS.h" 38 #include "../autovar/autovar_OS.h"
39 39
40 #include <mach-o/dyld.h> 40 #include <mach-o/dyld.h>
41 #include <mach-o/nlist.h> 41 #include <mach-o/nlist.h>
42 #include <sys/stat.h>
43 #include <dlfcn.h> 42 #include <dlfcn.h>
44 #include <string.h> 43 #include <string.h>
45 44
46 #if defined(ARCH_X64) || defined(ARCH_PPC64) || defined(ARCH_ARM64) /*@@@ use dyncall_macros.h*/ 45 #if defined(ARCH_X64) || defined(ARCH_PPC64) || defined(ARCH_ARM64) /*@@@ use dyncall_macros.h*/
47 #define MACH_HEADER_TYPE mach_header_64 46 #define MACH_HEADER_TYPE mach_header_64
71 DLSyms* dlSymsInit(const char* libPath) 70 DLSyms* dlSymsInit(const char* libPath)
72 { 71 {
73 DLLib* pLib; 72 DLLib* pLib;
74 DLSyms* pSyms = NULL; 73 DLSyms* pSyms = NULL;
75 uint32_t i, n; 74 uint32_t i, n;
76 struct stat st0;
77 const struct MACH_HEADER_TYPE* pHeader = NULL; 75 const struct MACH_HEADER_TYPE* pHeader = NULL;
78 const struct dysymtab_command* dysymtab_cmd = NULL; 76 const struct dysymtab_command* dysymtab_cmd = NULL;
79
80 if(stat(libPath, &st0) == -1)
81 return NULL;
82 77
83 pLib = dlLoadLibrary(libPath); 78 pLib = dlLoadLibrary(libPath);
84 if(!pLib) 79 if(!pLib)
85 return NULL; 80 return NULL;
86 81
87 /* Loop over all dynamically linked images to find ours. */ 82 /* Loop over all dynamically linked images to find ours. */
88 for(i = 0, n = _dyld_image_count(); i < n; ++i) 83 for(i = 0, n = _dyld_image_count(); i < n; ++i)
89 { 84 {
90 struct stat st1;
91 const char* name = _dyld_get_image_name(i); 85 const char* name = _dyld_get_image_name(i);
92 86
93 if(name && (stat(name, &st1) != -1)) 87 if(name)
94 { 88 {
95 /* Don't rely on name comparison alone, as libPath might be relative, symlink, differently */ 89 /* Don't rely on name comparison alone, as libPath might be relative, symlink, differently */
96 /* cased, etc., but compare inode number with the one of the mapped dyld image. */ 90 /* cased, use weird osx path placeholders, etc., but compare inode number with the one of the mapped dyld image. */
97 if(st0.st_ino == st1.st_ino/*!strcmp(name, libPath)*/) 91
98 { 92 /* reload already loaded lib to get handle to compare with, should be lightweight and only increase ref count */
99 pHeader = (const struct MACH_HEADER_TYPE*) _dyld_get_image_header(i); 93 DLLib* pLib_ = dlLoadLibrary(name);
94 if(pLib_)
95 {
96 /* free / refcount-- */
97 dlFreeLibrary(pLib_);
98
99 if(pLib == pLib_)
100 {
101 pHeader = (const struct MACH_HEADER_TYPE*) _dyld_get_image_header(i);
100 //@@@ slide = _dyld_get_image_vmaddr_slide(i); 102 //@@@ slide = _dyld_get_image_vmaddr_slide(i);
101 break; /* found header */ 103 break; /* found header */
104 }
102 } 105 }
103 } 106 }
104 } 107 }
105 108
106 if(pHeader && (pHeader->magic == MACH_HEADER_MAGIC_NR) && (pHeader->filetype == MH_DYLIB)/*@@@ ignore for now, seems to work without it on El Capitan && !(pHeader->flags & MH_SPLIT_SEGS)*/) 109 if(pHeader && (pHeader->magic == MACH_HEADER_MAGIC_NR) && (pHeader->filetype == MH_DYLIB)/*@@@ ignore for now, seems to work without it on El Capitan && !(pHeader->flags & MH_SPLIT_SEGS)*/)