1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // +build darwin,go1.12,amd64 darwin,go1.12,386
16 type darwinTest struct {
21 // TODO(khr): decide whether to keep this test enabled permanently or
23 func TestDarwinLoader(t *testing.T) {
24 // Make sure the Darwin dynamic loader can actually resolve
25 // all the system calls into libSystem.dylib. Unfortunately
26 // there is no easy way to test this at compile time. So we
27 // implement a crazy hack here, calling into the syscall
28 // function with all its arguments set to junk, and see what
29 // error we get. We are happy with any error (or none) except
30 // an error from the dynamic loader.
32 // We have to run each test in a separate subprocess for fault isolation.
34 // Hopefully the junk args won't accidentally ask the system to do "rm -fr /".
36 // In an ideal world each syscall would have its own test, so this test
37 // would be unnecessary. Unfortunately, we do not live in that world.
38 for _, test := range darwinTests {
39 // Call the test binary recursively, giving it a magic argument
40 // (see init below) and the name of the test to run.
41 cmd := exec.Command(os.Args[0], "testDarwinLoader", test.name)
43 // Run subprocess, collect results. Note that we expect the subprocess
44 // to fail somehow, so the error is irrelevant.
45 out, _ := cmd.CombinedOutput()
47 if strings.Contains(string(out), "dyld: Symbol not found:") {
48 t.Errorf("can't resolve %s in libSystem.dylib", test.name)
50 if !strings.Contains(string(out), "success") {
51 // Not really an error. Might be a syscall that never returns,
52 // like exit, or one that segfaults, like gettimeofday.
53 t.Logf("test never finished: %s: %s", test.name, string(out))
59 // The test binary execs itself with the "testDarwinLoader" argument.
60 // Run the test specified by os.Args[2], then panic.
61 if len(os.Args) >= 3 && os.Args[1] == "testDarwinLoader" {
62 for _, test := range darwinTests {
63 if test.name == os.Args[2] {
67 // Panic with a "success" label, so the parent process can check it.
72 // All the _trampoline functions in zsyscall_darwin_$ARCH.s
73 var darwinTests = [...]darwinTest{
74 {"getgroups", libc_getgroups_trampoline},
75 {"setgroups", libc_setgroups_trampoline},
76 {"wait4", libc_wait4_trampoline},
77 {"accept", libc_accept_trampoline},
78 {"bind", libc_bind_trampoline},
79 {"connect", libc_connect_trampoline},
80 {"socket", libc_socket_trampoline},
81 {"getsockopt", libc_getsockopt_trampoline},
82 {"setsockopt", libc_setsockopt_trampoline},
83 {"getpeername", libc_getpeername_trampoline},
84 {"getsockname", libc_getsockname_trampoline},
85 {"shutdown", libc_shutdown_trampoline},
86 {"socketpair", libc_socketpair_trampoline},
87 {"recvfrom", libc_recvfrom_trampoline},
88 {"sendto", libc_sendto_trampoline},
89 {"recvmsg", libc_recvmsg_trampoline},
90 {"sendmsg", libc_sendmsg_trampoline},
91 {"kevent", libc_kevent_trampoline},
92 {"sysctl", libc_sysctl_trampoline},
93 {"utimes", libc_utimes_trampoline},
94 {"futimes", libc_futimes_trampoline},
95 {"fcntl", libc_fcntl_trampoline},
96 {"poll", libc_poll_trampoline},
97 {"madvise", libc_madvise_trampoline},
98 {"mlock", libc_mlock_trampoline},
99 {"mlockall", libc_mlockall_trampoline},
100 {"mprotect", libc_mprotect_trampoline},
101 {"msync", libc_msync_trampoline},
102 {"munlock", libc_munlock_trampoline},
103 {"munlockall", libc_munlockall_trampoline},
104 {"ptrace", libc_ptrace_trampoline},
105 {"pipe", libc_pipe_trampoline},
106 {"getxattr", libc_getxattr_trampoline},
107 {"fgetxattr", libc_fgetxattr_trampoline},
108 {"setxattr", libc_setxattr_trampoline},
109 {"fsetxattr", libc_fsetxattr_trampoline},
110 {"removexattr", libc_removexattr_trampoline},
111 {"fremovexattr", libc_fremovexattr_trampoline},
112 {"listxattr", libc_listxattr_trampoline},
113 {"flistxattr", libc_flistxattr_trampoline},
114 {"kill", libc_kill_trampoline},
115 {"ioctl", libc_ioctl_trampoline},
116 {"access", libc_access_trampoline},
117 {"adjtime", libc_adjtime_trampoline},
118 {"chdir", libc_chdir_trampoline},
119 {"chflags", libc_chflags_trampoline},
120 {"chmod", libc_chmod_trampoline},
121 {"chown", libc_chown_trampoline},
122 {"chroot", libc_chroot_trampoline},
123 {"close", libc_close_trampoline},
124 {"dup", libc_dup_trampoline},
125 {"dup2", libc_dup2_trampoline},
126 {"exchangedata", libc_exchangedata_trampoline},
127 {"exit", libc_exit_trampoline},
128 {"faccessat", libc_faccessat_trampoline},
129 {"fchdir", libc_fchdir_trampoline},
130 {"fchflags", libc_fchflags_trampoline},
131 {"fchmod", libc_fchmod_trampoline},
132 {"fchmodat", libc_fchmodat_trampoline},
133 {"fchown", libc_fchown_trampoline},
134 {"fchownat", libc_fchownat_trampoline},
135 {"flock", libc_flock_trampoline},
136 {"fpathconf", libc_fpathconf_trampoline},
137 {"fstat64", libc_fstat64_trampoline},
138 {"fstatat64", libc_fstatat64_trampoline},
139 {"fstatfs64", libc_fstatfs64_trampoline},
140 {"fsync", libc_fsync_trampoline},
141 {"ftruncate", libc_ftruncate_trampoline},
142 {"getdtablesize", libc_getdtablesize_trampoline},
143 {"getegid", libc_getegid_trampoline},
144 {"geteuid", libc_geteuid_trampoline},
145 {"getgid", libc_getgid_trampoline},
146 {"getpgid", libc_getpgid_trampoline},
147 {"getpgrp", libc_getpgrp_trampoline},
148 {"getpid", libc_getpid_trampoline},
149 {"getppid", libc_getppid_trampoline},
150 {"getpriority", libc_getpriority_trampoline},
151 {"getrlimit", libc_getrlimit_trampoline},
152 {"getrusage", libc_getrusage_trampoline},
153 {"getsid", libc_getsid_trampoline},
154 {"getuid", libc_getuid_trampoline},
155 {"issetugid", libc_issetugid_trampoline},
156 {"kqueue", libc_kqueue_trampoline},
157 {"lchown", libc_lchown_trampoline},
158 {"link", libc_link_trampoline},
159 {"linkat", libc_linkat_trampoline},
160 {"listen", libc_listen_trampoline},
161 {"lstat64", libc_lstat64_trampoline},
162 {"mkdir", libc_mkdir_trampoline},
163 {"mkdirat", libc_mkdirat_trampoline},
164 {"mkfifo", libc_mkfifo_trampoline},
165 {"mknod", libc_mknod_trampoline},
166 {"open", libc_open_trampoline},
167 {"openat", libc_openat_trampoline},
168 {"pathconf", libc_pathconf_trampoline},
169 {"pread", libc_pread_trampoline},
170 {"pwrite", libc_pwrite_trampoline},
171 {"read", libc_read_trampoline},
172 {"readlink", libc_readlink_trampoline},
173 {"readlinkat", libc_readlinkat_trampoline},
174 {"rename", libc_rename_trampoline},
175 {"renameat", libc_renameat_trampoline},
176 {"revoke", libc_revoke_trampoline},
177 {"rmdir", libc_rmdir_trampoline},
178 {"lseek", libc_lseek_trampoline},
179 {"select", libc_select_trampoline},
180 {"setegid", libc_setegid_trampoline},
181 {"seteuid", libc_seteuid_trampoline},
182 {"setgid", libc_setgid_trampoline},
183 {"setlogin", libc_setlogin_trampoline},
184 {"setpgid", libc_setpgid_trampoline},
185 {"setpriority", libc_setpriority_trampoline},
186 {"setprivexec", libc_setprivexec_trampoline},
187 {"setregid", libc_setregid_trampoline},
188 {"setreuid", libc_setreuid_trampoline},
189 {"setrlimit", libc_setrlimit_trampoline},
190 {"setsid", libc_setsid_trampoline},
191 {"settimeofday", libc_settimeofday_trampoline},
192 {"setuid", libc_setuid_trampoline},
193 {"stat64", libc_stat64_trampoline},
194 {"statfs64", libc_statfs64_trampoline},
195 {"symlink", libc_symlink_trampoline},
196 {"symlinkat", libc_symlinkat_trampoline},
197 {"sync", libc_sync_trampoline},
198 {"truncate", libc_truncate_trampoline},
199 {"umask", libc_umask_trampoline},
200 {"undelete", libc_undelete_trampoline},
201 {"unlink", libc_unlink_trampoline},
202 {"unlinkat", libc_unlinkat_trampoline},
203 {"unmount", libc_unmount_trampoline},
204 {"write", libc_write_trampoline},
205 {"mmap", libc_mmap_trampoline},
206 {"munmap", libc_munmap_trampoline},
207 {"gettimeofday", libc_gettimeofday_trampoline},
208 {"getfsstat64", libc_getfsstat64_trampoline},