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