Loading...
#include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #include <unistd.h> #include <signal.h> #include <errno.h> #include <mach/mach.h> #include <mach/machine.h> #include <err.h> #include <System/sys/reason.h> #include <System/sys/proc_info.h> #include <System/kern/kern_cdata.h> #include <libproc.h> #include <mach-o/dyld_priv.h> #if __arm64e__ // arm64e uses chained binds which does not support lazy binding #define SUPPORTS_LAZY_BINDING 0 #else #define SUPPORTS_LAZY_BINDING 1 #endif #include "test_support.h" static const char* getUserDescription(struct proc_exitreasoninfo& info) { kcdata_iter_t iter = kcdata_iter((void*)info.eri_kcd_buf, info.eri_reason_buf_size); if ( !kcdata_iter_valid(iter) ) return NULL; if ( kcdata_iter_type(iter) != KCDATA_BUFFER_BEGIN_OS_REASON ) return NULL; iter = kcdata_iter_find_type(iter, EXIT_REASON_USER_DESC); if ( !kcdata_iter_valid(iter) ) { return NULL; } return kcdata_iter_string(iter, 0); } int main(int argc, const char* argv[], const char* envp[], const char* apple[]) { #if SUPPORTS_LAZY_BINDING _process process; #ifdef WEAK process.set_executable_path(RUN_DIR "/lazy-symbol-missing-called-weak-lib.exe"); #else process.set_executable_path(RUN_DIR "/lazy-symbol-missing-called.exe"); #endif const char* env[] = { "TEST_OUTPUT=None", NULL}; process.set_env(env); process.set_exit_handler(^(pid_t pid) { LOG("Child exited pid=%d", pid); struct proc_exitreasoninfo info; bzero(&info, sizeof(info)); uint8_t packReasonData[OS_REASON_BUFFER_MAX_SIZE]; bzero(packReasonData, OS_REASON_BUFFER_MAX_SIZE); info.eri_reason_buf_size = OS_REASON_BUFFER_MAX_SIZE; info.eri_kcd_buf = (user_addr_t)packReasonData; LOG("info=%p", &info); int procResult = proc_pidinfo(pid, PROC_PIDEXITREASONINFO, 1, &info, PROC_PIDEXITREASONINFO_SIZE); if ( procResult != sizeof(struct proc_exitreasoninfo) ) { FAIL("bad return size from proc_pidinfo(), %d expected %lu", procResult, PROC_PIDEXITREASONINFO_SIZE); } if ( info.eri_namespace != OS_REASON_DYLD ) { FAIL("eri_namespace (%d) != OS_REASON_DYLD", info.eri_namespace); } const char* userDesc = getUserDescription(info); if ( userDesc != NULL ) { LOG("user desc=%s", (const char*)userDesc); } #if 0 // ifdef WEAK // with dyld4, lazy pointer is set to _dyld_missing_symbol() so there is no place to store missing symbol name or dylib // Make sure we print a dylib name, not a dependency library # when referencing a symbol from a missing library if ( userDesc != NULL ) { if ( strstr(userDesc, "libbar-missing.dylib") == NULL ) { FAIL("Expected name of missing dylib"); } } #endif PASS("Success"); }); (void)process.launch(); #endif PASS("Success"); } |