]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc
Merge ^/head r320573 through r320970.
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / sanitizer_common / sanitizer_mac.cc
1 //===-- sanitizer_mac.cc --------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is shared between various sanitizers' runtime libraries and
11 // implements OSX-specific functions.
12 //===----------------------------------------------------------------------===//
13
14 #include "sanitizer_platform.h"
15 #if SANITIZER_MAC
16 #include "sanitizer_mac.h"
17
18 // Use 64-bit inodes in file operations. ASan does not support OS X 10.5, so
19 // the clients will most certainly use 64-bit ones as well.
20 #ifndef _DARWIN_USE_64_BIT_INODE
21 #define _DARWIN_USE_64_BIT_INODE 1
22 #endif
23 #include <stdio.h>
24
25 #include "sanitizer_common.h"
26 #include "sanitizer_flags.h"
27 #include "sanitizer_internal_defs.h"
28 #include "sanitizer_libc.h"
29 #include "sanitizer_placement_new.h"
30 #include "sanitizer_platform_limits_posix.h"
31 #include "sanitizer_procmaps.h"
32
33 #if !SANITIZER_IOS
34 #include <crt_externs.h>  // for _NSGetEnviron
35 #else
36 extern char **environ;
37 #endif
38
39 #if defined(__has_include) && __has_include(<os/trace.h>)
40 #define SANITIZER_OS_TRACE 1
41 #include <os/trace.h>
42 #else
43 #define SANITIZER_OS_TRACE 0
44 #endif
45
46 #if !SANITIZER_IOS
47 #include <crt_externs.h>  // for _NSGetArgv and _NSGetEnviron
48 #else
49 extern "C" {
50   extern char ***_NSGetArgv(void);
51 }
52 #endif
53
54 #include <asl.h>
55 #include <dlfcn.h>  // for dladdr()
56 #include <errno.h>
57 #include <fcntl.h>
58 #include <libkern/OSAtomic.h>
59 #include <mach-o/dyld.h>
60 #include <mach/mach.h>
61 #include <mach/vm_statistics.h>
62 #include <pthread.h>
63 #include <sched.h>
64 #include <signal.h>
65 #include <stdlib.h>
66 #include <sys/mman.h>
67 #include <sys/resource.h>
68 #include <sys/stat.h>
69 #include <sys/sysctl.h>
70 #include <sys/types.h>
71 #include <sys/wait.h>
72 #include <unistd.h>
73 #include <util.h>
74
75 // From <crt_externs.h>, but we don't have that file on iOS.
76 extern "C" {
77   extern char ***_NSGetArgv(void);
78   extern char ***_NSGetEnviron(void);
79 }
80
81 // From <mach/mach_vm.h>, but we don't have that file on iOS.
82 extern "C" {
83   extern kern_return_t mach_vm_region_recurse(
84     vm_map_t target_task,
85     mach_vm_address_t *address,
86     mach_vm_size_t *size,
87     natural_t *nesting_depth,
88     vm_region_recurse_info_t info,
89     mach_msg_type_number_t *infoCnt);
90 }
91
92 namespace __sanitizer {
93
94 #include "sanitizer_syscall_generic.inc"
95
96 // Direct syscalls, don't call libmalloc hooks (but not available on 10.6).
97 extern "C" void *__mmap(void *addr, size_t len, int prot, int flags, int fildes,
98                         off_t off) SANITIZER_WEAK_ATTRIBUTE;
99 extern "C" int __munmap(void *, size_t) SANITIZER_WEAK_ATTRIBUTE;
100
101 // ---------------------- sanitizer_libc.h
102 uptr internal_mmap(void *addr, size_t length, int prot, int flags,
103                    int fd, u64 offset) {
104   if (fd == -1) fd = VM_MAKE_TAG(VM_MEMORY_ANALYSIS_TOOL);
105   if (&__mmap) return (uptr)__mmap(addr, length, prot, flags, fd, offset);
106   return (uptr)mmap(addr, length, prot, flags, fd, offset);
107 }
108
109 uptr internal_munmap(void *addr, uptr length) {
110   if (&__munmap) return __munmap(addr, length);
111   return munmap(addr, length);
112 }
113
114 int internal_mprotect(void *addr, uptr length, int prot) {
115   return mprotect(addr, length, prot);
116 }
117
118 uptr internal_close(fd_t fd) {
119   return close(fd);
120 }
121
122 uptr internal_open(const char *filename, int flags) {
123   return open(filename, flags);
124 }
125
126 uptr internal_open(const char *filename, int flags, u32 mode) {
127   return open(filename, flags, mode);
128 }
129
130 uptr internal_read(fd_t fd, void *buf, uptr count) {
131   return read(fd, buf, count);
132 }
133
134 uptr internal_write(fd_t fd, const void *buf, uptr count) {
135   return write(fd, buf, count);
136 }
137
138 uptr internal_stat(const char *path, void *buf) {
139   return stat(path, (struct stat *)buf);
140 }
141
142 uptr internal_lstat(const char *path, void *buf) {
143   return lstat(path, (struct stat *)buf);
144 }
145
146 uptr internal_fstat(fd_t fd, void *buf) {
147   return fstat(fd, (struct stat *)buf);
148 }
149
150 uptr internal_filesize(fd_t fd) {
151   struct stat st;
152   if (internal_fstat(fd, &st))
153     return -1;
154   return (uptr)st.st_size;
155 }
156
157 uptr internal_dup2(int oldfd, int newfd) {
158   return dup2(oldfd, newfd);
159 }
160
161 uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
162   return readlink(path, buf, bufsize);
163 }
164
165 uptr internal_unlink(const char *path) {
166   return unlink(path);
167 }
168
169 uptr internal_sched_yield() {
170   return sched_yield();
171 }
172
173 void internal__exit(int exitcode) {
174   _exit(exitcode);
175 }
176
177 unsigned int internal_sleep(unsigned int seconds) {
178   return sleep(seconds);
179 }
180
181 uptr internal_getpid() {
182   return getpid();
183 }
184
185 int internal_sigaction(int signum, const void *act, void *oldact) {
186   return sigaction(signum,
187                    (struct sigaction *)act, (struct sigaction *)oldact);
188 }
189
190 void internal_sigfillset(__sanitizer_sigset_t *set) { sigfillset(set); }
191
192 uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
193                           __sanitizer_sigset_t *oldset) {
194   // Don't use sigprocmask here, because it affects all threads.
195   return pthread_sigmask(how, set, oldset);
196 }
197
198 // Doesn't call pthread_atfork() handlers (but not available on 10.6).
199 extern "C" pid_t __fork(void) SANITIZER_WEAK_ATTRIBUTE;
200
201 int internal_fork() {
202   if (&__fork)
203     return __fork();
204   return fork();
205 }
206
207 int internal_forkpty(int *amaster) {
208   int master, slave;
209   if (openpty(&master, &slave, nullptr, nullptr, nullptr) == -1) return -1;
210   int pid = internal_fork();
211   if (pid == -1) {
212     close(master);
213     close(slave);
214     return -1;
215   }
216   if (pid == 0) {
217     close(master);
218     if (login_tty(slave) != 0) {
219       // We already forked, there's not much we can do.  Let's quit.
220       Report("login_tty failed (errno %d)\n", errno);
221       internal__exit(1);
222     }
223   } else {
224     *amaster = master;
225     close(slave);
226   }
227   return pid;
228 }
229
230 uptr internal_rename(const char *oldpath, const char *newpath) {
231   return rename(oldpath, newpath);
232 }
233
234 uptr internal_ftruncate(fd_t fd, uptr size) {
235   return ftruncate(fd, size);
236 }
237
238 uptr internal_execve(const char *filename, char *const argv[],
239                      char *const envp[]) {
240   return execve(filename, argv, envp);
241 }
242
243 uptr internal_waitpid(int pid, int *status, int options) {
244   return waitpid(pid, status, options);
245 }
246
247 // ----------------- sanitizer_common.h
248 bool FileExists(const char *filename) {
249   struct stat st;
250   if (stat(filename, &st))
251     return false;
252   // Sanity check: filename is a regular file.
253   return S_ISREG(st.st_mode);
254 }
255
256 tid_t GetTid() {
257   tid_t tid;
258   pthread_threadid_np(nullptr, &tid);
259   return tid;
260 }
261
262 void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
263                                 uptr *stack_bottom) {
264   CHECK(stack_top);
265   CHECK(stack_bottom);
266   uptr stacksize = pthread_get_stacksize_np(pthread_self());
267   // pthread_get_stacksize_np() returns an incorrect stack size for the main
268   // thread on Mavericks. See
269   // https://github.com/google/sanitizers/issues/261
270   if ((GetMacosVersion() >= MACOS_VERSION_MAVERICKS) && at_initialization &&
271       stacksize == (1 << 19))  {
272     struct rlimit rl;
273     CHECK_EQ(getrlimit(RLIMIT_STACK, &rl), 0);
274     // Most often rl.rlim_cur will be the desired 8M.
275     if (rl.rlim_cur < kMaxThreadStackSize) {
276       stacksize = rl.rlim_cur;
277     } else {
278       stacksize = kMaxThreadStackSize;
279     }
280   }
281   void *stackaddr = pthread_get_stackaddr_np(pthread_self());
282   *stack_top = (uptr)stackaddr;
283   *stack_bottom = *stack_top - stacksize;
284 }
285
286 char **GetEnviron() {
287 #if !SANITIZER_IOS
288   char ***env_ptr = _NSGetEnviron();
289   if (!env_ptr) {
290     Report("_NSGetEnviron() returned NULL. Please make sure __asan_init() is "
291            "called after libSystem_initializer().\n");
292     CHECK(env_ptr);
293   }
294   char **environ = *env_ptr;
295 #endif
296   CHECK(environ);
297   return environ;
298 }
299
300 const char *GetEnv(const char *name) {
301   char **env = GetEnviron();
302   uptr name_len = internal_strlen(name);
303   while (*env != 0) {
304     uptr len = internal_strlen(*env);
305     if (len > name_len) {
306       const char *p = *env;
307       if (!internal_memcmp(p, name, name_len) &&
308           p[name_len] == '=') {  // Match.
309         return *env + name_len + 1;  // String starting after =.
310       }
311     }
312     env++;
313   }
314   return 0;
315 }
316
317 uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
318   CHECK_LE(kMaxPathLength, buf_len);
319
320   // On OS X the executable path is saved to the stack by dyld. Reading it
321   // from there is much faster than calling dladdr, especially for large
322   // binaries with symbols.
323   InternalScopedString exe_path(kMaxPathLength);
324   uint32_t size = exe_path.size();
325   if (_NSGetExecutablePath(exe_path.data(), &size) == 0 &&
326       realpath(exe_path.data(), buf) != 0) {
327     return internal_strlen(buf);
328   }
329   return 0;
330 }
331
332 uptr ReadLongProcessName(/*out*/char *buf, uptr buf_len) {
333   return ReadBinaryName(buf, buf_len);
334 }
335
336 void ReExec() {
337   UNIMPLEMENTED();
338 }
339
340 uptr GetPageSize() {
341   return sysconf(_SC_PAGESIZE);
342 }
343
344 BlockingMutex::BlockingMutex() {
345   internal_memset(this, 0, sizeof(*this));
346 }
347
348 void BlockingMutex::Lock() {
349   CHECK(sizeof(OSSpinLock) <= sizeof(opaque_storage_));
350   CHECK_EQ(OS_SPINLOCK_INIT, 0);
351   CHECK_EQ(owner_, 0);
352   OSSpinLockLock((OSSpinLock*)&opaque_storage_);
353 }
354
355 void BlockingMutex::Unlock() {
356   OSSpinLockUnlock((OSSpinLock*)&opaque_storage_);
357 }
358
359 void BlockingMutex::CheckLocked() {
360   CHECK_NE(*(OSSpinLock*)&opaque_storage_, 0);
361 }
362
363 u64 NanoTime() {
364   return 0;
365 }
366
367 uptr GetTlsSize() {
368   return 0;
369 }
370
371 void InitTlsSize() {
372 }
373
374 uptr TlsBaseAddr() {
375   uptr segbase = 0;
376 #if defined(__x86_64__)
377   asm("movq %%gs:0,%0" : "=r"(segbase));
378 #elif defined(__i386__)
379   asm("movl %%gs:0,%0" : "=r"(segbase));
380 #endif
381   return segbase;
382 }
383
384 // The size of the tls on darwin does not appear to be well documented,
385 // however the vm memory map suggests that it is 1024 uptrs in size,
386 // with a size of 0x2000 bytes on x86_64 and 0x1000 bytes on i386.
387 uptr TlsSize() {
388 #if defined(__x86_64__) || defined(__i386__)
389   return 1024 * sizeof(uptr);
390 #else
391   return 0;
392 #endif
393 }
394
395 void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
396                           uptr *tls_addr, uptr *tls_size) {
397 #if !SANITIZER_GO
398   uptr stack_top, stack_bottom;
399   GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom);
400   *stk_addr = stack_bottom;
401   *stk_size = stack_top - stack_bottom;
402   *tls_addr = TlsBaseAddr();
403   *tls_size = TlsSize();
404 #else
405   *stk_addr = 0;
406   *stk_size = 0;
407   *tls_addr = 0;
408   *tls_size = 0;
409 #endif
410 }
411
412 void ListOfModules::init() {
413   clear();
414   MemoryMappingLayout memory_mapping(false);
415   memory_mapping.DumpListOfModules(&modules_);
416 }
417
418 static HandleSignalMode GetHandleSignalModeImpl(int signum) {
419   switch (signum) {
420     case SIGABRT:
421       return common_flags()->handle_abort;
422     case SIGILL:
423       return common_flags()->handle_sigill;
424     case SIGFPE:
425       return common_flags()->handle_sigfpe;
426     case SIGSEGV:
427       return common_flags()->handle_segv;
428     case SIGBUS:
429       return common_flags()->handle_sigbus;
430   }
431   return kHandleSignalNo;
432 }
433
434 HandleSignalMode GetHandleSignalMode(int signum) {
435   // Handling fatal signals on watchOS and tvOS devices is disallowed.
436   if ((SANITIZER_WATCHOS || SANITIZER_TVOS) && !(SANITIZER_IOSSIM))
437     return kHandleSignalNo;
438   HandleSignalMode result = GetHandleSignalModeImpl(signum);
439   if (result == kHandleSignalYes && !common_flags()->allow_user_segv_handler)
440     return kHandleSignalExclusive;
441   return result;
442 }
443
444 MacosVersion cached_macos_version = MACOS_VERSION_UNINITIALIZED;
445
446 MacosVersion GetMacosVersionInternal() {
447   int mib[2] = { CTL_KERN, KERN_OSRELEASE };
448   char version[100];
449   uptr len = 0, maxlen = sizeof(version) / sizeof(version[0]);
450   for (uptr i = 0; i < maxlen; i++) version[i] = '\0';
451   // Get the version length.
452   CHECK_NE(sysctl(mib, 2, 0, &len, 0, 0), -1);
453   CHECK_LT(len, maxlen);
454   CHECK_NE(sysctl(mib, 2, version, &len, 0, 0), -1);
455   switch (version[0]) {
456     case '9': return MACOS_VERSION_LEOPARD;
457     case '1': {
458       switch (version[1]) {
459         case '0': return MACOS_VERSION_SNOW_LEOPARD;
460         case '1': return MACOS_VERSION_LION;
461         case '2': return MACOS_VERSION_MOUNTAIN_LION;
462         case '3': return MACOS_VERSION_MAVERICKS;
463         case '4': return MACOS_VERSION_YOSEMITE;
464         default:
465           if (IsDigit(version[1]))
466             return MACOS_VERSION_UNKNOWN_NEWER;
467           else
468             return MACOS_VERSION_UNKNOWN;
469       }
470     }
471     default: return MACOS_VERSION_UNKNOWN;
472   }
473 }
474
475 MacosVersion GetMacosVersion() {
476   atomic_uint32_t *cache =
477       reinterpret_cast<atomic_uint32_t*>(&cached_macos_version);
478   MacosVersion result =
479       static_cast<MacosVersion>(atomic_load(cache, memory_order_acquire));
480   if (result == MACOS_VERSION_UNINITIALIZED) {
481     result = GetMacosVersionInternal();
482     atomic_store(cache, result, memory_order_release);
483   }
484   return result;
485 }
486
487 bool PlatformHasDifferentMemcpyAndMemmove() {
488   // On OS X 10.7 memcpy() and memmove() are both resolved
489   // into memmove$VARIANT$sse42.
490   // See also https://github.com/google/sanitizers/issues/34.
491   // TODO(glider): need to check dynamically that memcpy() and memmove() are
492   // actually the same function.
493   return GetMacosVersion() == MACOS_VERSION_SNOW_LEOPARD;
494 }
495
496 uptr GetRSS() {
497   struct task_basic_info info;
498   unsigned count = TASK_BASIC_INFO_COUNT;
499   kern_return_t result =
500       task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &count);
501   if (UNLIKELY(result != KERN_SUCCESS)) {
502     Report("Cannot get task info. Error: %d\n", result);
503     Die();
504   }
505   return info.resident_size;
506 }
507
508 void *internal_start_thread(void(*func)(void *arg), void *arg) {
509   // Start the thread with signals blocked, otherwise it can steal user signals.
510   __sanitizer_sigset_t set, old;
511   internal_sigfillset(&set);
512   internal_sigprocmask(SIG_SETMASK, &set, &old);
513   pthread_t th;
514   pthread_create(&th, 0, (void*(*)(void *arg))func, arg);
515   internal_sigprocmask(SIG_SETMASK, &old, 0);
516   return th;
517 }
518
519 void internal_join_thread(void *th) { pthread_join((pthread_t)th, 0); }
520
521 #if !SANITIZER_GO
522 static BlockingMutex syslog_lock(LINKER_INITIALIZED);
523 #endif
524
525 void WriteOneLineToSyslog(const char *s) {
526 #if !SANITIZER_GO
527   syslog_lock.CheckLocked();
528   asl_log(nullptr, nullptr, ASL_LEVEL_ERR, "%s", s);
529 #endif
530 }
531
532 void LogMessageOnPrintf(const char *str) {
533   // Log all printf output to CrashLog.
534   if (common_flags()->abort_on_error)
535     CRAppendCrashLogMessage(str);
536 }
537
538 void LogFullErrorReport(const char *buffer) {
539 #if !SANITIZER_GO
540   // Log with os_trace. This will make it into the crash log.
541 #if SANITIZER_OS_TRACE
542   if (GetMacosVersion() >= MACOS_VERSION_YOSEMITE) {
543     // os_trace requires the message (format parameter) to be a string literal.
544     if (internal_strncmp(SanitizerToolName, "AddressSanitizer",
545                          sizeof("AddressSanitizer") - 1) == 0)
546       os_trace("Address Sanitizer reported a failure.");
547     else if (internal_strncmp(SanitizerToolName, "UndefinedBehaviorSanitizer",
548                               sizeof("UndefinedBehaviorSanitizer") - 1) == 0)
549       os_trace("Undefined Behavior Sanitizer reported a failure.");
550     else if (internal_strncmp(SanitizerToolName, "ThreadSanitizer",
551                               sizeof("ThreadSanitizer") - 1) == 0)
552       os_trace("Thread Sanitizer reported a failure.");
553     else
554       os_trace("Sanitizer tool reported a failure.");
555
556     if (common_flags()->log_to_syslog)
557       os_trace("Consult syslog for more information.");
558   }
559 #endif
560
561   // Log to syslog.
562   // The logging on OS X may call pthread_create so we need the threading
563   // environment to be fully initialized. Also, this should never be called when
564   // holding the thread registry lock since that may result in a deadlock. If
565   // the reporting thread holds the thread registry mutex, and asl_log waits
566   // for GCD to dispatch a new thread, the process will deadlock, because the
567   // pthread_create wrapper needs to acquire the lock as well.
568   BlockingMutexLock l(&syslog_lock);
569   if (common_flags()->log_to_syslog)
570     WriteToSyslog(buffer);
571
572   // The report is added to CrashLog as part of logging all of Printf output.
573 #endif
574 }
575
576 SignalContext::WriteFlag SignalContext::GetWriteFlag(void *context) {
577 #if defined(__x86_64__) || defined(__i386__)
578   ucontext_t *ucontext = static_cast<ucontext_t*>(context);
579   return ucontext->uc_mcontext->__es.__err & 2 /*T_PF_WRITE*/ ? WRITE : READ;
580 #else
581   return UNKNOWN;
582 #endif
583 }
584
585 void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
586   ucontext_t *ucontext = (ucontext_t*)context;
587 # if defined(__aarch64__)
588   *pc = ucontext->uc_mcontext->__ss.__pc;
589 #   if defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0
590   *bp = ucontext->uc_mcontext->__ss.__fp;
591 #   else
592   *bp = ucontext->uc_mcontext->__ss.__lr;
593 #   endif
594   *sp = ucontext->uc_mcontext->__ss.__sp;
595 # elif defined(__x86_64__)
596   *pc = ucontext->uc_mcontext->__ss.__rip;
597   *bp = ucontext->uc_mcontext->__ss.__rbp;
598   *sp = ucontext->uc_mcontext->__ss.__rsp;
599 # elif defined(__arm__)
600   *pc = ucontext->uc_mcontext->__ss.__pc;
601   *bp = ucontext->uc_mcontext->__ss.__r[7];
602   *sp = ucontext->uc_mcontext->__ss.__sp;
603 # elif defined(__i386__)
604   *pc = ucontext->uc_mcontext->__ss.__eip;
605   *bp = ucontext->uc_mcontext->__ss.__ebp;
606   *sp = ucontext->uc_mcontext->__ss.__esp;
607 # else
608 # error "Unknown architecture"
609 # endif
610 }
611
612 #if !SANITIZER_GO
613 static const char kDyldInsertLibraries[] = "DYLD_INSERT_LIBRARIES";
614 LowLevelAllocator allocator_for_env;
615
616 // Change the value of the env var |name|, leaking the original value.
617 // If |name_value| is NULL, the variable is deleted from the environment,
618 // otherwise the corresponding "NAME=value" string is replaced with
619 // |name_value|.
620 void LeakyResetEnv(const char *name, const char *name_value) {
621   char **env = GetEnviron();
622   uptr name_len = internal_strlen(name);
623   while (*env != 0) {
624     uptr len = internal_strlen(*env);
625     if (len > name_len) {
626       const char *p = *env;
627       if (!internal_memcmp(p, name, name_len) && p[name_len] == '=') {
628         // Match.
629         if (name_value) {
630           // Replace the old value with the new one.
631           *env = const_cast<char*>(name_value);
632         } else {
633           // Shift the subsequent pointers back.
634           char **del = env;
635           do {
636             del[0] = del[1];
637           } while (*del++);
638         }
639       }
640     }
641     env++;
642   }
643 }
644
645 SANITIZER_WEAK_CXX_DEFAULT_IMPL
646 bool ReexecDisabled() {
647   return false;
648 }
649
650 extern "C" SANITIZER_WEAK_ATTRIBUTE double dyldVersionNumber;
651 static const double kMinDyldVersionWithAutoInterposition = 360.0;
652
653 bool DyldNeedsEnvVariable() {
654   // Although sanitizer support was added to LLVM on OS X 10.7+, GCC users
655   // still may want use them on older systems. On older Darwin platforms, dyld
656   // doesn't export dyldVersionNumber symbol and we simply return true.
657   if (!&dyldVersionNumber) return true;
658   // If running on OS X 10.11+ or iOS 9.0+, dyld will interpose even if
659   // DYLD_INSERT_LIBRARIES is not set. However, checking OS version via
660   // GetMacosVersion() doesn't work for the simulator. Let's instead check
661   // `dyldVersionNumber`, which is exported by dyld, against a known version
662   // number from the first OS release where this appeared.
663   return dyldVersionNumber < kMinDyldVersionWithAutoInterposition;
664 }
665
666 void MaybeReexec() {
667   if (ReexecDisabled()) return;
668
669   // Make sure the dynamic runtime library is preloaded so that the
670   // wrappers work. If it is not, set DYLD_INSERT_LIBRARIES and re-exec
671   // ourselves.
672   Dl_info info;
673   RAW_CHECK(dladdr((void*)((uptr)&__sanitizer_report_error_summary), &info));
674   char *dyld_insert_libraries =
675       const_cast<char*>(GetEnv(kDyldInsertLibraries));
676   uptr old_env_len = dyld_insert_libraries ?
677       internal_strlen(dyld_insert_libraries) : 0;
678   uptr fname_len = internal_strlen(info.dli_fname);
679   const char *dylib_name = StripModuleName(info.dli_fname);
680   uptr dylib_name_len = internal_strlen(dylib_name);
681
682   bool lib_is_in_env = dyld_insert_libraries &&
683                        internal_strstr(dyld_insert_libraries, dylib_name);
684   if (DyldNeedsEnvVariable() && !lib_is_in_env) {
685     // DYLD_INSERT_LIBRARIES is not set or does not contain the runtime
686     // library.
687     InternalScopedString program_name(1024);
688     uint32_t buf_size = program_name.size();
689     _NSGetExecutablePath(program_name.data(), &buf_size);
690     char *new_env = const_cast<char*>(info.dli_fname);
691     if (dyld_insert_libraries) {
692       // Append the runtime dylib name to the existing value of
693       // DYLD_INSERT_LIBRARIES.
694       new_env = (char*)allocator_for_env.Allocate(old_env_len + fname_len + 2);
695       internal_strncpy(new_env, dyld_insert_libraries, old_env_len);
696       new_env[old_env_len] = ':';
697       // Copy fname_len and add a trailing zero.
698       internal_strncpy(new_env + old_env_len + 1, info.dli_fname,
699                        fname_len + 1);
700       // Ok to use setenv() since the wrappers don't depend on the value of
701       // asan_inited.
702       setenv(kDyldInsertLibraries, new_env, /*overwrite*/1);
703     } else {
704       // Set DYLD_INSERT_LIBRARIES equal to the runtime dylib name.
705       setenv(kDyldInsertLibraries, info.dli_fname, /*overwrite*/0);
706     }
707     VReport(1, "exec()-ing the program with\n");
708     VReport(1, "%s=%s\n", kDyldInsertLibraries, new_env);
709     VReport(1, "to enable wrappers.\n");
710     execv(program_name.data(), *_NSGetArgv());
711
712     // We get here only if execv() failed.
713     Report("ERROR: The process is launched without DYLD_INSERT_LIBRARIES, "
714            "which is required for the sanitizer to work. We tried to set the "
715            "environment variable and re-execute itself, but execv() failed, "
716            "possibly because of sandbox restrictions. Make sure to launch the "
717            "executable with:\n%s=%s\n", kDyldInsertLibraries, new_env);
718     RAW_CHECK("execv failed" && 0);
719   }
720
721   // Verify that interceptors really work.  We'll use dlsym to locate
722   // "pthread_create", if interceptors are working, it should really point to
723   // "wrap_pthread_create" within our own dylib.
724   Dl_info info_pthread_create;
725   void *dlopen_addr = dlsym(RTLD_DEFAULT, "pthread_create");
726   RAW_CHECK(dladdr(dlopen_addr, &info_pthread_create));
727   if (internal_strcmp(info.dli_fname, info_pthread_create.dli_fname) != 0) {
728     Report(
729         "ERROR: Interceptors are not working. This may be because %s is "
730         "loaded too late (e.g. via dlopen). Please launch the executable "
731         "with:\n%s=%s\n",
732         SanitizerToolName, kDyldInsertLibraries, info.dli_fname);
733     RAW_CHECK("interceptors not installed" && 0);
734   }
735
736   if (!lib_is_in_env)
737     return;
738
739   // DYLD_INSERT_LIBRARIES is set and contains the runtime library. Let's remove
740   // the dylib from the environment variable, because interceptors are installed
741   // and we don't want our children to inherit the variable.
742
743   uptr env_name_len = internal_strlen(kDyldInsertLibraries);
744   // Allocate memory to hold the previous env var name, its value, the '='
745   // sign and the '\0' char.
746   char *new_env = (char*)allocator_for_env.Allocate(
747       old_env_len + 2 + env_name_len);
748   RAW_CHECK(new_env);
749   internal_memset(new_env, '\0', old_env_len + 2 + env_name_len);
750   internal_strncpy(new_env, kDyldInsertLibraries, env_name_len);
751   new_env[env_name_len] = '=';
752   char *new_env_pos = new_env + env_name_len + 1;
753
754   // Iterate over colon-separated pieces of |dyld_insert_libraries|.
755   char *piece_start = dyld_insert_libraries;
756   char *piece_end = NULL;
757   char *old_env_end = dyld_insert_libraries + old_env_len;
758   do {
759     if (piece_start[0] == ':') piece_start++;
760     piece_end = internal_strchr(piece_start, ':');
761     if (!piece_end) piece_end = dyld_insert_libraries + old_env_len;
762     if ((uptr)(piece_start - dyld_insert_libraries) > old_env_len) break;
763     uptr piece_len = piece_end - piece_start;
764
765     char *filename_start =
766         (char *)internal_memrchr(piece_start, '/', piece_len);
767     uptr filename_len = piece_len;
768     if (filename_start) {
769       filename_start += 1;
770       filename_len = piece_len - (filename_start - piece_start);
771     } else {
772       filename_start = piece_start;
773     }
774
775     // If the current piece isn't the runtime library name,
776     // append it to new_env.
777     if ((dylib_name_len != filename_len) ||
778         (internal_memcmp(filename_start, dylib_name, dylib_name_len) != 0)) {
779       if (new_env_pos != new_env + env_name_len + 1) {
780         new_env_pos[0] = ':';
781         new_env_pos++;
782       }
783       internal_strncpy(new_env_pos, piece_start, piece_len);
784       new_env_pos += piece_len;
785     }
786     // Move on to the next piece.
787     piece_start = piece_end;
788   } while (piece_start < old_env_end);
789
790   // Can't use setenv() here, because it requires the allocator to be
791   // initialized.
792   // FIXME: instead of filtering DYLD_INSERT_LIBRARIES here, do it in
793   // a separate function called after InitializeAllocator().
794   if (new_env_pos == new_env + env_name_len + 1) new_env = NULL;
795   LeakyResetEnv(kDyldInsertLibraries, new_env);
796 }
797 #endif  // SANITIZER_GO
798
799 char **GetArgv() {
800   return *_NSGetArgv();
801 }
802
803 #if defined(__aarch64__) && SANITIZER_IOS && !SANITIZER_IOSSIM
804 // The task_vm_info struct is normally provided by the macOS SDK, but we need
805 // fields only available in 10.12+. Declare the struct manually to be able to
806 // build against older SDKs.
807 struct __sanitizer_task_vm_info {
808   uptr _unused[(SANITIZER_WORDSIZE == 32) ? 20 : 19];
809   uptr min_address;
810   uptr max_address;
811 };
812
813 uptr GetTaskInfoMaxAddress() {
814   __sanitizer_task_vm_info vm_info = {{0}, 0, 0};
815   mach_msg_type_number_t count = sizeof(vm_info) / sizeof(int);
816   int err = task_info(mach_task_self(), TASK_VM_INFO, (int *)&vm_info, &count);
817   if (err == 0) {
818     return vm_info.max_address - 1;
819   } else {
820     // xnu cannot provide vm address limit
821     return 0x200000000 - 1;
822   }
823 }
824 #endif
825
826 uptr GetMaxVirtualAddress() {
827 #if SANITIZER_WORDSIZE == 64
828 # if defined(__aarch64__) && SANITIZER_IOS && !SANITIZER_IOSSIM
829   // Get the maximum VM address
830   static uptr max_vm = GetTaskInfoMaxAddress();
831   CHECK(max_vm);
832   return max_vm;
833 # else
834   return (1ULL << 47) - 1;  // 0x00007fffffffffffUL;
835 # endif
836 #else  // SANITIZER_WORDSIZE == 32
837   return (1ULL << 32) - 1;  // 0xffffffff;
838 #endif  // SANITIZER_WORDSIZE
839 }
840
841 uptr FindAvailableMemoryRange(uptr shadow_size,
842                               uptr alignment,
843                               uptr left_padding,
844                               uptr *largest_gap_found) {
845   typedef vm_region_submap_short_info_data_64_t RegionInfo;
846   enum { kRegionInfoSize = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64 };
847   // Start searching for available memory region past PAGEZERO, which is
848   // 4KB on 32-bit and 4GB on 64-bit.
849   mach_vm_address_t start_address =
850     (SANITIZER_WORDSIZE == 32) ? 0x000000001000 : 0x000100000000;
851
852   mach_vm_address_t address = start_address;
853   mach_vm_address_t free_begin = start_address;
854   kern_return_t kr = KERN_SUCCESS;
855   if (largest_gap_found) *largest_gap_found = 0;
856   while (kr == KERN_SUCCESS) {
857     mach_vm_size_t vmsize = 0;
858     natural_t depth = 0;
859     RegionInfo vminfo;
860     mach_msg_type_number_t count = kRegionInfoSize;
861     kr = mach_vm_region_recurse(mach_task_self(), &address, &vmsize, &depth,
862                                 (vm_region_info_t)&vminfo, &count);
863     if (free_begin != address) {
864       // We found a free region [free_begin..address-1].
865       uptr gap_start = RoundUpTo((uptr)free_begin + left_padding, alignment);
866       uptr gap_end = RoundDownTo((uptr)address, alignment);
867       uptr gap_size = gap_end > gap_start ? gap_end - gap_start : 0;
868       if (shadow_size < gap_size) {
869         return gap_start;
870       }
871
872       if (largest_gap_found && *largest_gap_found < gap_size) {
873         *largest_gap_found = gap_size;
874       }
875     }
876     // Move to the next region.
877     address += vmsize;
878     free_begin = address;
879   }
880
881   // We looked at all free regions and could not find one large enough.
882   return 0;
883 }
884
885 // FIXME implement on this platform.
886 void GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size) { }
887
888 void SignalContext::DumpAllRegisters(void *context) {
889   Report("Register values:\n");
890
891   ucontext_t *ucontext = (ucontext_t*)context;
892 # define DUMPREG64(r) \
893     Printf("%s = 0x%016llx  ", #r, ucontext->uc_mcontext->__ss.__ ## r);
894 # define DUMPREG32(r) \
895     Printf("%s = 0x%08x  ", #r, ucontext->uc_mcontext->__ss.__ ## r);
896 # define DUMPREG_(r)   Printf(" "); DUMPREG(r);
897 # define DUMPREG__(r)  Printf("  "); DUMPREG(r);
898 # define DUMPREG___(r) Printf("   "); DUMPREG(r);
899
900 # if defined(__x86_64__)
901 #  define DUMPREG(r) DUMPREG64(r)
902   DUMPREG(rax); DUMPREG(rbx); DUMPREG(rcx); DUMPREG(rdx); Printf("\n");
903   DUMPREG(rdi); DUMPREG(rsi); DUMPREG(rbp); DUMPREG(rsp); Printf("\n");
904   DUMPREG_(r8); DUMPREG_(r9); DUMPREG(r10); DUMPREG(r11); Printf("\n");
905   DUMPREG(r12); DUMPREG(r13); DUMPREG(r14); DUMPREG(r15); Printf("\n");
906 # elif defined(__i386__)
907 #  define DUMPREG(r) DUMPREG32(r)
908   DUMPREG(eax); DUMPREG(ebx); DUMPREG(ecx); DUMPREG(edx); Printf("\n");
909   DUMPREG(edi); DUMPREG(esi); DUMPREG(ebp); DUMPREG(esp); Printf("\n");
910 # elif defined(__aarch64__)
911 #  define DUMPREG(r) DUMPREG64(r)
912   DUMPREG_(x[0]); DUMPREG_(x[1]); DUMPREG_(x[2]); DUMPREG_(x[3]); Printf("\n");
913   DUMPREG_(x[4]); DUMPREG_(x[5]); DUMPREG_(x[6]); DUMPREG_(x[7]); Printf("\n");
914   DUMPREG_(x[8]); DUMPREG_(x[9]); DUMPREG(x[10]); DUMPREG(x[11]); Printf("\n");
915   DUMPREG(x[12]); DUMPREG(x[13]); DUMPREG(x[14]); DUMPREG(x[15]); Printf("\n");
916   DUMPREG(x[16]); DUMPREG(x[17]); DUMPREG(x[18]); DUMPREG(x[19]); Printf("\n");
917   DUMPREG(x[20]); DUMPREG(x[21]); DUMPREG(x[22]); DUMPREG(x[23]); Printf("\n");
918   DUMPREG(x[24]); DUMPREG(x[25]); DUMPREG(x[26]); DUMPREG(x[27]); Printf("\n");
919   DUMPREG(x[28]); DUMPREG___(fp); DUMPREG___(lr); DUMPREG___(sp); Printf("\n");
920 # elif defined(__arm__)
921 #  define DUMPREG(r) DUMPREG32(r)
922   DUMPREG_(r[0]); DUMPREG_(r[1]); DUMPREG_(r[2]); DUMPREG_(r[3]); Printf("\n");
923   DUMPREG_(r[4]); DUMPREG_(r[5]); DUMPREG_(r[6]); DUMPREG_(r[7]); Printf("\n");
924   DUMPREG_(r[8]); DUMPREG_(r[9]); DUMPREG(r[10]); DUMPREG(r[11]); Printf("\n");
925   DUMPREG(r[12]); DUMPREG___(sp); DUMPREG___(lr); DUMPREG___(pc); Printf("\n");
926 # else
927 # error "Unknown architecture"
928 # endif
929
930 # undef DUMPREG64
931 # undef DUMPREG32
932 # undef DUMPREG_
933 # undef DUMPREG__
934 # undef DUMPREG___
935 # undef DUMPREG
936 }
937
938 static inline bool CompareBaseAddress(const LoadedModule &a,
939                                       const LoadedModule &b) {
940   return a.base_address() < b.base_address();
941 }
942
943 void FormatUUID(char *out, uptr size, const u8 *uuid) {
944   internal_snprintf(out, size,
945                     "<%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-"
946                     "%02X%02X%02X%02X%02X%02X>",
947                     uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5],
948                     uuid[6], uuid[7], uuid[8], uuid[9], uuid[10], uuid[11],
949                     uuid[12], uuid[13], uuid[14], uuid[15]);
950 }
951
952 void PrintModuleMap() {
953   Printf("Process module map:\n");
954   MemoryMappingLayout memory_mapping(false);
955   InternalMmapVector<LoadedModule> modules(/*initial_capacity*/ 128);
956   memory_mapping.DumpListOfModules(&modules);
957   InternalSort(&modules, modules.size(), CompareBaseAddress);
958   for (uptr i = 0; i < modules.size(); ++i) {
959     char uuid_str[128];
960     FormatUUID(uuid_str, sizeof(uuid_str), modules[i].uuid());
961     Printf("0x%zx-0x%zx %s (%s) %s\n", modules[i].base_address(),
962            modules[i].max_executable_address(), modules[i].full_name(),
963            ModuleArchToString(modules[i].arch()), uuid_str);
964   }
965   Printf("End of module map.\n");
966 }
967
968 void CheckNoDeepBind(const char *filename, int flag) {
969   // Do nothing.
970 }
971
972 // FIXME: implement on this platform.
973 bool GetRandom(void *buffer, uptr length) {
974   UNIMPLEMENTED();
975 }
976
977 }  // namespace __sanitizer
978
979 #endif  // SANITIZER_MAC