dyld-733.8.tar.gz
[apple/dyld.git] / testing / test-cases / lazy-symbol-missing.dtest / runner.c
1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <dlfcn.h>
5 #include <unistd.h>
6 #include <signal.h>
7 #include <errno.h>
8 #include <mach/mach.h>
9 #include <mach/machine.h>
10 #include <err.h>
11 #include <System/sys/reason.h>
12 #include <System/sys/proc_info.h>
13 #include <System/kern/kern_cdata.h>
14 #include <libproc.h>
15 #include <mach-o/dyld_priv.h>
16
17 #if __arm64e__
18 // arm64e uses chained binds which does not support lazy binding
19 #define SUPPORTS_LAZY_BINDING 0
20 #else
21 #define SUPPORTS_LAZY_BINDING 1
22 #endif
23
24
25 static bool sSignalCaught = false;
26 static bool sChildAbortInDyld = false;
27 static pid_t sChildPid = 0;
28
29
30 static void childDied(int sig)
31 {
32 sSignalCaught = true;
33 //printf("sigchld for pid=%d\n", sChildPid);
34
35 struct proc_exitreasoninfo info;
36 bzero(&info, sizeof(info));
37 uint8_t packReasonData[OS_REASON_BUFFER_MAX_SIZE];
38 bzero(packReasonData, OS_REASON_BUFFER_MAX_SIZE);
39 info.eri_reason_buf_size = OS_REASON_BUFFER_MAX_SIZE;
40 info.eri_kcd_buf = (user_addr_t)packReasonData;
41 //fprintf(stderr, "info=%p\n", &info);
42 int procResult = proc_pidinfo(sChildPid, PROC_PIDEXITREASONINFO, 1, &info, PROC_PIDEXITREASONINFO_SIZE);
43 if ( procResult != sizeof(struct proc_exitreasoninfo) ) {
44 printf("bad return size from proc_pidinfo(), %d expected %lu\n", procResult, PROC_PIDEXITREASONINFO_SIZE);
45 return;
46 }
47 if ( info.eri_namespace != OS_REASON_DYLD ) {
48 printf("eri_namespace (%d) != OS_REASON_DYLD\n", info.eri_namespace);
49 return;
50 }
51
52 sChildAbortInDyld = true;
53 }
54
55
56 bool runTest(const char* prog)
57 {
58 sSignalCaught = false;
59 sChildAbortInDyld = false;
60
61 // fork and exec child
62 sChildPid = fork();
63 if ( sChildPid < 0 )
64 err(EXIT_FAILURE, "fork");
65 if ( sChildPid == 0 ) {
66 // child side
67 char* childArgv[] = { (char*)prog, NULL };
68 int result = execvp(prog, childArgv);
69 err(EXIT_FAILURE, "exec(\"%s\",...)", prog);
70 }
71 for(int i=0; i < 10; ++i) {
72 if ( sSignalCaught )
73 break;
74 sleep(1);
75 }
76
77 return sChildAbortInDyld;
78 }
79
80
81 int main(int argc, const char* argv[])
82 {
83 printf("[BEGIN] lazy-symbol-missing and called\n");
84
85 #if SUPPORTS_LAZY_BINDING
86 // set up signal handler for catching child terminations
87 signal(SIGCHLD, childDied);
88
89 // test launch program with missing library
90 runTest(RUN_DIR "/lazy-symbol-missing-called.exe");
91
92 if ( sSignalCaught && sChildAbortInDyld )
93 printf("[PASS] lazy-symbol-missing and called\n");
94 else
95 printf("[FAIL] lazy-symbol-missing and called\n");
96 #else
97 printf("[PASS] lazy-symbol-missing and called\n");
98 #endif
99 return 0;
100 }
101