# HG changeset patch # User Tassilo Philipp # Date 1517486340 -3600 # Node ID 1e3617d8a951647299857b5ad4a830519e66c612 # Parent 5c8eb8f34ae635fb8b8f69b5a13b9f42f3350179 - mach-o loader fix (discovered on High Sierra, not sure what other versions were affected) diff -r 5c8eb8f34ae6 -r 1e3617d8a951 dynload/dynload_syms_mach-o.c --- a/dynload/dynload_syms_mach-o.c Sat Dec 30 00:36:00 2017 +0100 +++ b/dynload/dynload_syms_mach-o.c Thu Feb 01 12:59:00 2018 +0100 @@ -7,7 +7,7 @@ License: Copyright (c) 2007-2015 Olivier Chafik , - 2017 refactored completely for stability, API + 2017-2018 refactored completely for stability, API consistency and portability by Tassilo Philipp. Permission to use, copy, modify, and distribute this software for any @@ -114,12 +114,20 @@ if(cmd->cmd == SEGMEND_COMMAND_ID) { const struct SEGMENT_COMMAND* seg = (struct SEGMENT_COMMAND*)cmd; - if((seg->fileoff == 0) && (seg->filesize != 0)) + /*@@@ unsure why I used this instead of checking __TEXT: if((seg->fileoff == 0) && (seg->filesize != 0))*/ + if(strcmp(seg->segname, "__TEXT") == 0) slide = (uintptr_t)pHeader - seg->vmaddr; /* effective offset of segment from header */ + /* If we have __LINKEDIT segment (= raw data for dynamic linkers), use that one to find symbal table address. */ if(strcmp(seg->segname, "__LINKEDIT") == 0) { - /* Adjust pBase depending on where __LINKEDIT segment is */ + /* Recompute pBase relative to where __LINKEDIT segment is in memory. */ pBase = (const char*)(seg->vmaddr - seg->fileoff) + slide; + + /*@@@ we might want to also check maxprot and initprot here: + VM_PROT_READ ((vm_prot_t) 0x01) + VM_PROT_WRITE ((vm_prot_t) 0x02) + VM_PROT_EXECUTE ((vm_prot_t) 0x04)*/ + symOffset = slide; /* this is also offset of symbols */ } } @@ -138,13 +146,15 @@ pSyms->symOffset = symOffset; pSyms->pLib = pLib; } - else if(cmd->cmd == LC_DYSYMTAB) + else if(cmd->cmd == LC_DYSYMTAB && !dysymtab_cmd/* only init once - just safety check */) { - dysymtab_cmd = (const struct dysymtab_command*)cmd; - /*@@@ check if(cmd->cmdsize != sizeof(struct dysymtab_command)) { - dlFreeMem.... + /* @@@ unused, we'll always run over all symbols, and not check locals, globals, etc. + if(cmd->cmdsize != sizeof(struct symtab_command)) { + dlSymsCleanup(pSyms); break; - }*/ + } + + dysymtab_cmd = (const struct dysymtab_command*)cmd;*/ } } }