Mercurial > pub > dyncall > dyncall
changeset 223:7076f551faf5
- dynload mach-o handling fixes for 64bit platforms
- dynload test code improvements
- dynload(3) clarification
author | Tassilo Philipp |
---|---|
date | Sat, 15 Apr 2017 15:21:37 +0200 |
parents | 700c67984c08 |
children | 61fff73dbff8 |
files | dynload/dynload.3 dynload/dynload_syms_mach-o.c test/dynload_plain/dynload_plain.c |
diffstat | 3 files changed, 35 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/dynload/dynload.3 Fri Apr 14 21:23:22 2017 +0200 +++ b/dynload/dynload.3 Sat Apr 15 15:21:37 2017 +0200 @@ -53,7 +53,7 @@ .Ar pSymbolName in the library with handle .Ar pLib , -or returns a null pointer if the symbol cannot be found. +or returns a null pointer if the symbol cannot be found. The name is specified as it would appear in C source code (mangled if C++, etc.). .Sh SEE ALSO .Xr dyncall 3 , .Xr dyncallback 3
--- a/dynload/dynload_syms_mach-o.c Fri Apr 14 21:23:22 2017 +0200 +++ b/dynload/dynload_syms_mach-o.c Sat Apr 15 15:21:37 2017 +0200 @@ -45,12 +45,16 @@ #if defined(ARCH_X64) || defined(ARCH_PPC64) || defined(ARCH_ARM64) /*@@@ use dyncall_macros.h*/ #define MACH_HEADER_TYPE mach_header_64 +#define MACH_HEADER_MAGIC_NR MH_MAGIC_64 +#define SEGMEND_COMMAND_ID LC_SEGMENT_64 #define SEGMENT_COMMAND segment_command_64 #define NLIST_TYPE nlist_64 #else #define MACH_HEADER_TYPE mach_header +#define MACH_HEADER_MAGIC_NR MH_MAGIC +#define SEGMEND_COMMAND_ID LC_SEGMENT +#define SEGMENT_COMMAND segment_command #define NLIST_TYPE nlist -#define SEGMENT_COMMAND segment_command #endif @@ -66,10 +70,11 @@ DLSyms* dlSymsInit(const char* libPath) { DLLib* pLib; - DLSyms* pSyms; + DLSyms* pSyms = NULL; uint32_t i, n; struct stat st0; const struct MACH_HEADER_TYPE* pHeader = NULL; + const struct dysymtab_command* dysymtab_cmd = NULL; if(stat(libPath, &st0) == -1) return NULL; @@ -96,7 +101,7 @@ } } - if(pHeader && (pHeader->filetype == MH_DYLIB) && !(pHeader->flags & MH_SPLIT_SEGS)) + if(pHeader && (pHeader->magic == MACH_HEADER_MAGIC_NR) && (pHeader->filetype == MH_DYLIB) && !(pHeader->flags & MH_SPLIT_SEGS)) { const char* pBase = (const char*)pHeader; uintptr_t slide = 0; @@ -104,7 +109,7 @@ for(i = 0, n = pHeader->ncmds; i < n; ++i, cmd = (const struct load_command*)((const char*)cmd + cmd->cmdsize)) { - if(cmd->cmd == LC_SEGMENT) + if(cmd->cmd == SEGMEND_COMMAND_ID) { const struct SEGMENT_COMMAND* seg = (struct SEGMENT_COMMAND*)cmd; if((seg->fileoff == 0) && (seg->filesize != 0)) /* Count segment sizes to slide over...@@@? */ @@ -112,7 +117,7 @@ if(strcmp(seg->segname, "__LINKEDIT") == 0) pBase = (const char*)(seg->vmaddr - seg->fileoff + slide); /* Adjust pBase depending on __LINKEDIT segment */ } - else if(cmd->cmd == LC_SYMTAB) + else if(cmd->cmd == LC_SYMTAB && !pSyms/* only init once - just safety check */) { const struct symtab_command* scmd = (const struct symtab_command*)cmd; @@ -125,13 +130,29 @@ pSyms->pStringTable = pBase + scmd->stroff; pSyms->pSymbolTable = (struct NLIST_TYPE*)(pBase + scmd->symoff); pSyms->pLib = pLib; - - return pSyms; + } + else if(cmd->cmd == LC_DYSYMTAB) + { + dysymtab_cmd = (const struct dysymtab_command*)cmd; + /*@@@ check if(cmd->cmdsize != sizeof(struct dysymtab_command)) { + dlFreeMem.... + break; + }*/ } - /*@@@ handle also LC_DYSYMTAB */ } } + /* Got symbol table? */ + if(pSyms) { + /* Alter symtable info if we got symbols organized in local/defined/undefined groups. */ + /* Only use local ones in that case. */ + /*@@@ don't restrict to only local symbols if(dysymtab_cmd) { + pSyms->pSymbolTable += dysymtab_cmd->ilocalsym; + pSyms->symbolCount = dysymtab_cmd->nlocalsym; + }*/ + return pSyms; + } + /* Couldn't init syms, so free lib and return error. */ dlFreeLibrary(pLib); return NULL;
--- a/test/dynload_plain/dynload_plain.c Fri Apr 14 21:23:22 2017 +0200 +++ b/test/dynload_plain/dynload_plain.c Sat Apr 15 15:21:37 2017 +0200 @@ -46,14 +46,17 @@ "/lib32/libc.so", "/lib32/libc.so.6", "/lib32/libc.so.7", + "/usr/lib/system/libsystem_c.dylib", "/usr/lib/libc.dylib", "C:\\Windows\\system32\\msvcrt.dll" }; for(i=0; i<(sizeof(clibs)/sizeof(const char*)); ++i) { - if(access(clibs[i], F_OK) != -1) + if(access(clibs[i], F_OK) != -1) { path = clibs[i]; + break; + } } if(path) { @@ -100,7 +103,7 @@ } printf("printf symbol found by iteration: %d\n", i<n); - name = dlSymsName(pSyms, i); + name = (i<n) ? dlSymsName(pSyms, i) : NULL; r += (name && strcmp(name, "printf") == 0); // check if we can lookup "printf" by index printf("printf symbol name by index: %s\n", name?name:"");