1//===-- sanitizer_linux.cpp -----------------------------------------------===//
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 AddressSanitizer and ThreadSanitizer
10// run-time libraries and implements linux-specific functions from
11// sanitizer_libc.h.
12//===----------------------------------------------------------------------===//
13
14#include "sanitizer_platform.h"
15
16#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
17 SANITIZER_SOLARIS || SANITIZER_HAIKU
18
19# include "sanitizer_common.h"
20# include "sanitizer_flags.h"
21# include "sanitizer_getauxval.h"
22# include "sanitizer_internal_defs.h"
23# include "sanitizer_libc.h"
24# include "sanitizer_linux.h"
25# include "sanitizer_mutex.h"
26# include "sanitizer_placement_new.h"
27# include "sanitizer_procmaps.h"
28
29# if SANITIZER_LINUX && !SANITIZER_GO
30# include <asm/param.h>
31# endif
32
33// For mips64, syscall(__NR_stat) fills the buffer in the 'struct kernel_stat'
34// format. Struct kernel_stat is defined as 'struct stat' in asm/stat.h. To
35// access stat from asm/stat.h, without conflicting with definition in
36// sys/stat.h, we use this trick. sparc64 is similar, using
37// syscall(__NR_stat64) and struct kernel_stat64.
38# if SANITIZER_LINUX && (SANITIZER_MIPS64 || SANITIZER_SPARC64)
39# include <asm/unistd.h>
40# include <sys/types.h>
41# define stat kernel_stat
42# if SANITIZER_SPARC64
43# define stat64 kernel_stat64
44# endif
45# if SANITIZER_GO
46# undef st_atime
47# undef st_mtime
48# undef st_ctime
49# define st_atime st_atim
50# define st_mtime st_mtim
51# define st_ctime st_ctim
52# endif
53# include <asm/stat.h>
54# undef stat
55# undef stat64
56# endif
57
58# include <dlfcn.h>
59# include <errno.h>
60# include <fcntl.h>
61# include <link.h>
62# include <pthread.h>
63# include <sched.h>
64# include <signal.h>
65# include <sys/mman.h>
66# if !SANITIZER_SOLARIS && !SANITIZER_HAIKU
67# include <sys/ptrace.h>
68# endif
69# include <sys/resource.h>
70# include <sys/stat.h>
71# if !SANITIZER_HAIKU
72# include <sys/syscall.h>
73# include <ucontext.h>
74# endif
75# include <sys/time.h>
76# include <sys/types.h>
77# include <unistd.h>
78
79# if SANITIZER_LINUX
80# include <sys/utsname.h>
81# endif
82
83# if SANITIZER_LINUX && !SANITIZER_ANDROID
84# include <sys/personality.h>
85# endif
86
87# if SANITIZER_ANDROID && __ANDROID_API__ < 35
88// The weak `strerrorname_np` (introduced in API level 35) definition,
89// allows for checking the API level at runtime.
90extern "C" SANITIZER_WEAK_ATTRIBUTE const char *strerrorname_np(int);
91# endif
92
93# if SANITIZER_LINUX && \
94 (defined(__loongarch__) || defined(__hexagon__) || defined(__alpha__))
95# include <sys/sysmacros.h>
96# endif
97
98// Hexagon uses statx() instead of stat64(). glibc provides struct statx
99// through <sys/stat.h>, but musl does not — pull it from <linux/stat.h>.
100// On this musl/hexagon combination the two headers coexist without conflict.
101# if SANITIZER_LINUX && defined(__hexagon__)
102# include <linux/stat.h>
103# endif
104
105# if SANITIZER_LINUX && defined(__powerpc64__)
106# include <asm/ptrace.h>
107# endif
108
109# if SANITIZER_FREEBSD
110# include <machine/atomic.h>
111# include <sys/exec.h>
112# include <sys/procctl.h>
113# include <sys/sysctl.h>
114extern "C" {
115// <sys/umtx.h> must be included after <errno.h> and <sys/types.h> on
116// FreeBSD 9.2 and 10.0.
117# include <sys/umtx.h>
118}
119# include <sys/thr.h>
120# endif // SANITIZER_FREEBSD
121
122# if SANITIZER_NETBSD
123# include <limits.h> // For NAME_MAX
124# include <sys/exec.h>
125# include <sys/sysctl.h>
126extern struct ps_strings *__ps_strings;
127# endif // SANITIZER_NETBSD
128
129# if SANITIZER_SOLARIS
130# include <stddef.h>
131# include <stdlib.h>
132# include <sys/frame.h>
133# include <thread.h>
134# define environ _environ
135# endif
136
137# if SANITIZER_HAIKU
138# include <OS.h>
139# include <elf.h>
140# include <image.h>
141extern "C" char **__libc_argv;
142# endif
143
144extern char **environ;
145
146# if SANITIZER_LINUX
147// <linux/time.h>
148struct kernel_timeval {
149 long tv_sec;
150 long tv_usec;
151};
152
153// <linux/futex.h> is broken on some linux distributions.
154const int FUTEX_WAIT = 0;
155const int FUTEX_WAKE = 1;
156const int FUTEX_PRIVATE_FLAG = 128;
157const int FUTEX_WAIT_PRIVATE = FUTEX_WAIT | FUTEX_PRIVATE_FLAG;
158const int FUTEX_WAKE_PRIVATE = FUTEX_WAKE | FUTEX_PRIVATE_FLAG;
159# endif // SANITIZER_LINUX
160
161// Are we using 32-bit or 64-bit Linux syscalls?
162// x32 (which defines __x86_64__) has SANITIZER_WORDSIZE == 32
163// but it still needs to use 64-bit syscalls.
164# if SANITIZER_LINUX && \
165 (defined(__x86_64__) || defined(__powerpc64__) || \
166 SANITIZER_WORDSIZE == 64 || \
167 (defined(__mips__) && defined(_ABIN32) && _MIPS_SIM == _ABIN32))
168# define SANITIZER_LINUX_USES_64BIT_SYSCALLS 1
169# else
170# define SANITIZER_LINUX_USES_64BIT_SYSCALLS 0
171# endif
172
173// Note : FreeBSD implemented both Linux and OpenBSD apis.
174# if SANITIZER_LINUX && defined(__NR_getrandom)
175# if !defined(GRND_NONBLOCK)
176# define GRND_NONBLOCK 1
177# endif
178# define SANITIZER_USE_GETRANDOM 1
179# else
180# define SANITIZER_USE_GETRANDOM 0
181# endif // SANITIZER_LINUX && defined(__NR_getrandom)
182
183# if SANITIZER_FREEBSD
184# define SANITIZER_USE_GETENTROPY 1
185extern "C" void *__sys_mmap(void *addr, size_t len, int prot, int flags, int fd,
186 off_t offset);
187# endif
188
189namespace __sanitizer {
190
191void SetSigProcMask(__sanitizer_sigset_t *set, __sanitizer_sigset_t *oldset) {
192 CHECK_EQ(0, internal_sigprocmask(SIG_SETMASK, set, oldset));
193}
194
195# if SANITIZER_LINUX
196// Deletes the specified signal from newset, if it is not present in oldset
197// Equivalently: newset[signum] = newset[signum] & oldset[signum]
198static void KeepUnblocked(__sanitizer_sigset_t &newset,
199 __sanitizer_sigset_t &oldset, int signum) {
200 // FIXME: https://github.com/google/sanitizers/issues/1816
201 if (SANITIZER_ANDROID || !internal_sigismember(set: &oldset, signum))
202 internal_sigdelset(set: &newset, signum);
203}
204# endif
205
206// Block asynchronous signals
207void BlockSignals(__sanitizer_sigset_t *oldset) {
208 __sanitizer_sigset_t newset;
209 internal_sigfillset(set: &newset);
210
211# if SANITIZER_LINUX
212 __sanitizer_sigset_t currentset;
213
214# if !SANITIZER_ANDROID
215 // FIXME: https://github.com/google/sanitizers/issues/1816
216 SetSigProcMask(NULL, oldset: &currentset);
217
218 // Glibc uses SIGSETXID signal during setuid call. If this signal is blocked
219 // on any thread, setuid call hangs.
220 // See test/sanitizer_common/TestCases/Linux/setuid.c.
221 KeepUnblocked(newset, oldset&: currentset, signum: 33);
222# endif // !SANITIZER_ANDROID
223
224 // Seccomp-BPF-sandboxed processes rely on SIGSYS to handle trapped syscalls.
225 // If this signal is blocked, such calls cannot be handled and the process may
226 // hang.
227 KeepUnblocked(newset, oldset&: currentset, signum: 31);
228
229# if !SANITIZER_ANDROID
230 // Don't block synchronous signals
231 // but also don't unblock signals that the user had deliberately blocked.
232 // FIXME: https://github.com/google/sanitizers/issues/1816
233 KeepUnblocked(newset, oldset&: currentset, SIGSEGV);
234 KeepUnblocked(newset, oldset&: currentset, SIGBUS);
235 KeepUnblocked(newset, oldset&: currentset, SIGILL);
236 KeepUnblocked(newset, oldset&: currentset, SIGTRAP);
237 KeepUnblocked(newset, oldset&: currentset, SIGABRT);
238 KeepUnblocked(newset, oldset&: currentset, SIGFPE);
239 KeepUnblocked(newset, oldset&: currentset, SIGPIPE);
240# endif //! SANITIZER_ANDROID
241
242# endif // SANITIZER_LINUX
243
244 SetSigProcMask(set: &newset, oldset);
245}
246
247ScopedBlockSignals::ScopedBlockSignals(__sanitizer_sigset_t *copy) {
248 BlockSignals(oldset: &saved_);
249 if (copy)
250 internal_memcpy(dest: copy, src: &saved_, n: sizeof(saved_));
251}
252
253ScopedBlockSignals::~ScopedBlockSignals() { SetSigProcMask(set: &saved_, oldset: nullptr); }
254
255# if SANITIZER_LINUX && defined(__x86_64__)
256# include "sanitizer_syscall_linux_x86_64.inc"
257# elif SANITIZER_LINUX && SANITIZER_RISCV64
258# include "sanitizer_syscall_linux_riscv64.inc"
259# elif SANITIZER_LINUX && defined(__aarch64__)
260# include "sanitizer_syscall_linux_aarch64.inc"
261# elif SANITIZER_LINUX && defined(__arm__)
262# include "sanitizer_syscall_linux_arm.inc"
263# elif SANITIZER_LINUX && defined(__hexagon__)
264# include "sanitizer_syscall_linux_hexagon.inc"
265# elif SANITIZER_LINUX && SANITIZER_LOONGARCH64
266# include "sanitizer_syscall_linux_loongarch64.inc"
267# elif SANITIZER_LINUX && SANITIZER_ALPHA
268# include "sanitizer_syscall_linux_alpha.inc"
269# else
270# include "sanitizer_syscall_generic.inc"
271# endif
272
273// --------------- sanitizer_libc.h
274# if !SANITIZER_SOLARIS && !SANITIZER_NETBSD && !SANITIZER_HAIKU
275# if !SANITIZER_S390
276uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
277 u64 offset) {
278# if SANITIZER_FREEBSD
279 return (uptr)__sys_mmap(addr, length, prot, flags, fd, offset);
280# elif SANITIZER_LINUX_USES_64BIT_SYSCALLS
281 return internal_syscall(SYSCALL(mmap), arg1: (uptr)addr, arg2: length, arg3: prot, arg4: flags, arg5: fd,
282 arg6: offset);
283# else
284 // mmap2 specifies file offset in 4096-byte units.
285 CHECK(IsAligned(offset, 4096));
286 return internal_syscall(SYSCALL(mmap2), addr, length, prot, flags, fd,
287 (OFF_T)(offset / 4096));
288# endif
289}
290# endif // !SANITIZER_S390
291
292uptr internal_munmap(void *addr, uptr length) {
293 return internal_syscall(SYSCALL(munmap), arg1: (uptr)addr, arg2: length);
294}
295
296# if SANITIZER_LINUX
297uptr internal_mremap(void *old_address, uptr old_size, uptr new_size, int flags,
298 void *new_address) {
299 return internal_syscall(SYSCALL(mremap), arg1: (uptr)old_address, arg2: old_size,
300 arg3: new_size, arg4: flags, arg5: (uptr)new_address);
301}
302# endif
303
304int internal_mprotect(void *addr, uptr length, int prot) {
305 return internal_syscall(SYSCALL(mprotect), arg1: (uptr)addr, arg2: length, arg3: prot);
306}
307
308int internal_madvise(uptr addr, uptr length, int advice) {
309 return internal_syscall(SYSCALL(madvise), arg1: addr, arg2: length, arg3: advice);
310}
311
312uptr internal_close_range(fd_t lowfd, fd_t highfd, int flags) {
313# if SANITIZER_FREEBSD || (SANITIZER_LINUX && defined(__NR_close_range))
314 return internal_syscall(SYSCALL(close_range), arg1: lowfd, arg2: highfd, arg3: flags);
315# endif
316 return -1; // Not supported.
317}
318
319uptr internal_close(fd_t fd) { return internal_syscall(SYSCALL(close), arg1: fd); }
320
321uptr internal_open(const char *filename, int flags) {
322# if SANITIZER_LINUX
323 return internal_syscall(SYSCALL(openat), AT_FDCWD, arg2: (uptr)filename, arg3: flags);
324# else
325 return internal_syscall(SYSCALL(open), (uptr)filename, flags);
326# endif
327}
328
329uptr internal_open(const char *filename, int flags, u32 mode) {
330# if SANITIZER_LINUX
331 return internal_syscall(SYSCALL(openat), AT_FDCWD, arg2: (uptr)filename, arg3: flags,
332 arg4: mode);
333# else
334 return internal_syscall(SYSCALL(open), (uptr)filename, flags, mode);
335# endif
336}
337
338uptr internal_read(fd_t fd, void *buf, uptr count) {
339 sptr res;
340 HANDLE_EINTR(res,
341 (sptr)internal_syscall(SYSCALL(read), fd, (uptr)buf, count));
342 return res;
343}
344
345uptr internal_write(fd_t fd, const void *buf, uptr count) {
346 sptr res;
347 HANDLE_EINTR(res,
348 (sptr)internal_syscall(SYSCALL(write), fd, (uptr)buf, count));
349 return res;
350}
351
352uptr internal_ftruncate(fd_t fd, uptr size) {
353 sptr res;
354 HANDLE_EINTR(res,
355 (sptr)internal_syscall(SYSCALL(ftruncate), fd, (OFF_T)size));
356 return res;
357}
358
359# if !SANITIZER_LINUX_USES_64BIT_SYSCALLS && SANITIZER_LINUX && \
360 !defined(__hexagon__)
361static void stat64_to_stat(struct stat64 *in, struct stat *out) {
362 internal_memset(out, 0, sizeof(*out));
363 out->st_dev = in->st_dev;
364 out->st_ino = in->st_ino;
365 out->st_mode = in->st_mode;
366 out->st_nlink = in->st_nlink;
367 out->st_uid = in->st_uid;
368 out->st_gid = in->st_gid;
369 out->st_rdev = in->st_rdev;
370 out->st_size = in->st_size;
371 out->st_blksize = in->st_blksize;
372 out->st_blocks = in->st_blocks;
373 out->st_atime = in->st_atime;
374 out->st_mtime = in->st_mtime;
375 out->st_ctime = in->st_ctime;
376}
377# endif
378
379# if SANITIZER_LINUX && \
380 (defined(__loongarch__) || defined(__hexagon__) || defined(__alpha__))
381static void statx_to_stat(struct statx *in, struct stat *out) {
382 internal_memset(out, 0, sizeof(*out));
383 out->st_dev = makedev(in->stx_dev_major, in->stx_dev_minor);
384 out->st_ino = in->stx_ino;
385 out->st_mode = in->stx_mode;
386 out->st_nlink = in->stx_nlink;
387 out->st_uid = in->stx_uid;
388 out->st_gid = in->stx_gid;
389 out->st_rdev = makedev(in->stx_rdev_major, in->stx_rdev_minor);
390 out->st_size = in->stx_size;
391 out->st_blksize = in->stx_blksize;
392 out->st_blocks = in->stx_blocks;
393 out->st_atime = in->stx_atime.tv_sec;
394 out->st_atim.tv_nsec = in->stx_atime.tv_nsec;
395 out->st_mtime = in->stx_mtime.tv_sec;
396 out->st_mtim.tv_nsec = in->stx_mtime.tv_nsec;
397 out->st_ctime = in->stx_ctime.tv_sec;
398 out->st_ctim.tv_nsec = in->stx_ctime.tv_nsec;
399}
400# endif
401
402# if SANITIZER_MIPS64 || SANITIZER_SPARC64
403# if SANITIZER_MIPS64
404typedef struct kernel_stat kstat_t;
405# else
406typedef struct kernel_stat64 kstat_t;
407# endif
408// Undefine compatibility macros from <sys/stat.h>
409// so that they would not clash with the kernel_stat
410// st_[a|m|c]time fields
411# if !SANITIZER_GO
412# undef st_atime
413# undef st_mtime
414# undef st_ctime
415# endif
416# if defined(SANITIZER_ANDROID)
417// Bionic sys/stat.h defines additional macros
418// for compatibility with the old NDKs and
419// they clash with the kernel_stat structure
420// st_[a|m|c]time_nsec fields.
421# undef st_atime_nsec
422# undef st_mtime_nsec
423# undef st_ctime_nsec
424# endif
425static void kernel_stat_to_stat(kstat_t *in, struct stat *out) {
426 internal_memset(out, 0, sizeof(*out));
427 out->st_dev = in->st_dev;
428 out->st_ino = in->st_ino;
429 out->st_mode = in->st_mode;
430 out->st_nlink = in->st_nlink;
431 out->st_uid = in->st_uid;
432 out->st_gid = in->st_gid;
433 out->st_rdev = in->st_rdev;
434 out->st_size = in->st_size;
435 out->st_blksize = in->st_blksize;
436 out->st_blocks = in->st_blocks;
437# if defined(__USE_MISC) || defined(__USE_XOPEN2K8) || \
438 defined(SANITIZER_ANDROID)
439 out->st_atim.tv_sec = in->st_atime;
440 out->st_atim.tv_nsec = in->st_atime_nsec;
441 out->st_mtim.tv_sec = in->st_mtime;
442 out->st_mtim.tv_nsec = in->st_mtime_nsec;
443 out->st_ctim.tv_sec = in->st_ctime;
444 out->st_ctim.tv_nsec = in->st_ctime_nsec;
445# else
446 out->st_atime = in->st_atime;
447 out->st_atimensec = in->st_atime_nsec;
448 out->st_mtime = in->st_mtime;
449 out->st_mtimensec = in->st_mtime_nsec;
450 out->st_ctime = in->st_ctime;
451 out->st_atimensec = in->st_ctime_nsec;
452# endif
453}
454# endif
455
456uptr internal_stat(const char *path, void *buf) {
457# if SANITIZER_FREEBSD
458 return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf, 0);
459# elif SANITIZER_LINUX
460# if defined(__loongarch__) || defined(__hexagon__) || defined(__alpha__)
461 struct statx bufx;
462 int res = internal_syscall(SYSCALL(statx), AT_FDCWD, (uptr)path,
463 AT_NO_AUTOMOUNT, STATX_BASIC_STATS, (uptr)&bufx);
464 statx_to_stat(&bufx, (struct stat *)buf);
465 return res;
466# elif ( \
467 SANITIZER_WORDSIZE == 64 || SANITIZER_X32 || \
468 (defined(__mips__) && defined(_ABIN32) && _MIPS_SIM == _ABIN32)) && \
469 !SANITIZER_SPARC
470 return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, arg2: (uptr)path, arg3: (uptr)buf,
471 arg4: 0);
472# elif SANITIZER_SPARC64
473 kstat_t buf64;
474 int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path,
475 (uptr)&buf64, 0);
476 kernel_stat_to_stat(&buf64, (struct stat *)buf);
477 return res;
478# else
479 struct stat64 buf64;
480 int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path,
481 (uptr)&buf64, 0);
482 stat64_to_stat(&buf64, (struct stat *)buf);
483 return res;
484# endif
485# else
486 struct stat64 buf64;
487 int res = internal_syscall(SYSCALL(stat64), path, &buf64);
488 stat64_to_stat(&buf64, (struct stat *)buf);
489 return res;
490# endif
491}
492
493uptr internal_lstat(const char *path, void *buf) {
494# if SANITIZER_FREEBSD
495 return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf,
496 AT_SYMLINK_NOFOLLOW);
497# elif SANITIZER_LINUX
498# if defined(__loongarch__) || defined(__hexagon__) || defined(__alpha__)
499 struct statx bufx;
500 int res = internal_syscall(SYSCALL(statx), AT_FDCWD, (uptr)path,
501 AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT,
502 STATX_BASIC_STATS, (uptr)&bufx);
503 statx_to_stat(&bufx, (struct stat *)buf);
504 return res;
505# elif ( \
506 defined(_LP64) || SANITIZER_X32 || \
507 (defined(__mips__) && defined(_ABIN32) && _MIPS_SIM == _ABIN32)) && \
508 !SANITIZER_SPARC
509 return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, arg2: (uptr)path, arg3: (uptr)buf,
510 AT_SYMLINK_NOFOLLOW);
511# elif SANITIZER_SPARC64
512 kstat_t buf64;
513 int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path,
514 (uptr)&buf64, AT_SYMLINK_NOFOLLOW);
515 kernel_stat_to_stat(&buf64, (struct stat *)buf);
516 return res;
517# else
518 struct stat64 buf64;
519 int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path,
520 (uptr)&buf64, AT_SYMLINK_NOFOLLOW);
521 stat64_to_stat(&buf64, (struct stat *)buf);
522 return res;
523# endif
524# else
525 struct stat64 buf64;
526 int res = internal_syscall(SYSCALL(lstat64), path, &buf64);
527 stat64_to_stat(&buf64, (struct stat *)buf);
528 return res;
529# endif
530}
531
532uptr internal_fstat(fd_t fd, void *buf) {
533# if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS
534# if SANITIZER_MIPS64
535 // For mips64, fstat syscall fills buffer in the format of kernel_stat
536 kstat_t kbuf;
537 int res = internal_syscall(SYSCALL(fstat), fd, &kbuf);
538 kernel_stat_to_stat(&kbuf, (struct stat *)buf);
539 return res;
540# elif SANITIZER_LINUX && SANITIZER_SPARC64
541 // For sparc64, fstat64 syscall fills buffer in the format of kernel_stat64
542 kstat_t kbuf;
543 int res = internal_syscall(SYSCALL(fstat64), fd, &kbuf);
544 kernel_stat_to_stat(&kbuf, (struct stat *)buf);
545 return res;
546# elif SANITIZER_LINUX && (defined(__loongarch__) || defined(__alpha__))
547 struct statx bufx;
548 int res = internal_syscall(SYSCALL(statx), fd, "", AT_EMPTY_PATH,
549 STATX_BASIC_STATS, (uptr)&bufx);
550 statx_to_stat(&bufx, (struct stat *)buf);
551 return res;
552# else
553 return internal_syscall(SYSCALL(fstat), arg1: fd, arg2: (uptr)buf);
554# endif
555# elif SANITIZER_LINUX && defined(__hexagon__)
556 // Hexagon musl lacks struct stat64; use statx() instead.
557 struct statx bufx;
558 int res = internal_syscall(SYSCALL(statx), fd, "", AT_EMPTY_PATH,
559 STATX_BASIC_STATS, (uptr)&bufx);
560 statx_to_stat(&bufx, (struct stat*)buf);
561 return res;
562# else
563 struct stat64 buf64;
564 int res = internal_syscall(SYSCALL(fstat64), fd, &buf64);
565 stat64_to_stat(&buf64, (struct stat *)buf);
566 return res;
567# endif
568}
569
570uptr internal_filesize(fd_t fd) {
571 struct stat st;
572 if (internal_fstat(fd, buf: &st))
573 return -1;
574 return (uptr)st.st_size;
575}
576
577uptr internal_dup(int oldfd) { return internal_syscall(SYSCALL(dup), arg1: oldfd); }
578
579uptr internal_dup2(int oldfd, int newfd) {
580# if SANITIZER_LINUX
581 return internal_syscall(SYSCALL(dup3), arg1: oldfd, arg2: newfd, arg3: 0);
582# else
583 return internal_syscall(SYSCALL(dup2), oldfd, newfd);
584# endif
585}
586
587uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
588# if SANITIZER_LINUX
589 return internal_syscall(SYSCALL(readlinkat), AT_FDCWD, arg2: (uptr)path, arg3: (uptr)buf,
590 arg4: bufsize);
591# else
592 return internal_syscall(SYSCALL(readlink), (uptr)path, (uptr)buf, bufsize);
593# endif
594}
595
596uptr internal_unlink(const char *path) {
597# if SANITIZER_LINUX
598 return internal_syscall(SYSCALL(unlinkat), AT_FDCWD, arg2: (uptr)path, arg3: 0);
599# else
600 return internal_syscall(SYSCALL(unlink), (uptr)path);
601# endif
602}
603
604uptr internal_rename(const char *oldpath, const char *newpath) {
605# if (defined(__riscv) || defined(__loongarch__)) && defined(__linux__)
606 return internal_syscall(SYSCALL(renameat2), AT_FDCWD, (uptr)oldpath, AT_FDCWD,
607 (uptr)newpath, 0);
608# elif SANITIZER_LINUX
609 return internal_syscall(SYSCALL(renameat), AT_FDCWD, arg2: (uptr)oldpath, AT_FDCWD,
610 arg4: (uptr)newpath);
611# else
612 return internal_syscall(SYSCALL(rename), (uptr)oldpath, (uptr)newpath);
613# endif
614}
615
616uptr internal_sched_yield() { return internal_syscall(SYSCALL(sched_yield)); }
617
618void internal_usleep(u64 useconds) {
619 struct timespec ts;
620 ts.tv_sec = useconds / 1000000;
621 ts.tv_nsec = (useconds % 1000000) * 1000;
622 internal_syscall(SYSCALL(nanosleep), arg1: &ts, arg2: &ts);
623}
624
625uptr internal_execve(const char *filename, char *const argv[],
626 char *const envp[]) {
627 return internal_syscall(SYSCALL(execve), arg1: (uptr)filename, arg2: (uptr)argv,
628 arg3: (uptr)envp);
629}
630# endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD && !SANITIZER_HAIKU
631
632# if !SANITIZER_NETBSD && !SANITIZER_HAIKU
633void internal__exit(int exitcode) {
634# if SANITIZER_FREEBSD || SANITIZER_SOLARIS
635 internal_syscall(SYSCALL(exit), exitcode);
636# else
637 internal_syscall(SYSCALL(exit_group), arg1: exitcode);
638# endif
639 Die(); // Unreachable.
640}
641# endif // !SANITIZER_NETBSD && !SANITIZER_HAIKU
642
643// ----------------- sanitizer_common.h
644bool FileExists(const char *filename) {
645 if (ShouldMockFailureToOpen(path: filename))
646 return false;
647 struct stat st;
648 if (internal_stat(path: filename, buf: &st))
649 return false;
650 // Sanity check: filename is a regular file.
651 return S_ISREG(st.st_mode);
652}
653
654bool DirExists(const char *path) {
655 struct stat st;
656 if (internal_stat(path, buf: &st))
657 return false;
658 return S_ISDIR(st.st_mode);
659}
660
661# if !SANITIZER_NETBSD
662ThreadID GetTid() {
663# if SANITIZER_FREEBSD
664 long Tid;
665 thr_self(&Tid);
666 return Tid;
667# elif SANITIZER_SOLARIS
668 return thr_self();
669# elif SANITIZER_HAIKU
670 return find_thread(NULL);
671# else
672 return internal_syscall(SYSCALL(gettid));
673# endif
674}
675
676int TgKill(pid_t pid, ThreadID tid, int sig) {
677# if SANITIZER_LINUX
678 return internal_syscall(SYSCALL(tgkill), arg1: pid, arg2: tid, arg3: sig);
679# elif SANITIZER_FREEBSD
680 return internal_syscall(SYSCALL(thr_kill2), pid, tid, sig);
681# elif SANITIZER_SOLARIS
682 (void)pid;
683 errno = thr_kill(tid, sig);
684 // TgKill is expected to return -1 on error, not an errno.
685 return errno != 0 ? -1 : 0;
686# elif SANITIZER_HAIKU
687 return kill_thread(tid);
688# endif
689}
690# endif
691
692# if SANITIZER_GLIBC
693u64 NanoTime() {
694 kernel_timeval tv;
695 internal_memset(s: &tv, c: 0, n: sizeof(tv));
696 internal_syscall(SYSCALL(gettimeofday), arg1: &tv, arg2: 0);
697 return (u64)tv.tv_sec * 1000 * 1000 * 1000 + tv.tv_usec * 1000;
698}
699// Used by real_clock_gettime.
700uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
701 return internal_syscall(SYSCALL(clock_gettime), arg1: clk_id, arg2: tp);
702}
703# elif !SANITIZER_SOLARIS && !SANITIZER_NETBSD
704u64 NanoTime() {
705 struct timespec ts;
706 clock_gettime(CLOCK_REALTIME, &ts);
707 return (u64)ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec;
708}
709# endif
710
711// Like getenv, but reads env directly from /proc (on Linux) or parses the
712// 'environ' array (on some others) and does not use libc. This function
713// should be called first inside __asan_init.
714const char *GetEnv(const char *name) {
715# if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_SOLARIS || \
716 SANITIZER_HAIKU
717 if (::environ != 0) {
718 uptr NameLen = internal_strlen(name);
719 for (char **Env = ::environ; *Env != 0; Env++) {
720 if (internal_strncmp(*Env, name, NameLen) == 0 && (*Env)[NameLen] == '=')
721 return (*Env) + NameLen + 1;
722 }
723 }
724 return 0; // Not found.
725# elif SANITIZER_LINUX
726 static char *environ;
727 static uptr len;
728 static bool inited;
729 if (!inited) {
730 inited = true;
731 uptr environ_size;
732 if (!ReadFileToBuffer(file_name: "/proc/self/environ", buff: &environ, buff_size: &environ_size, read_len: &len))
733 environ = nullptr;
734 }
735 if (!environ || len == 0)
736 return nullptr;
737 uptr namelen = internal_strlen(s: name);
738 const char *p = environ;
739 while (*p != '\0') { // will happen at the \0\0 that terminates the buffer
740 // proc file has the format NAME=value\0NAME=value\0NAME=value\0...
741 const char *endp = (char *)internal_memchr(s: p, c: '\0', n: len - (p - environ));
742 if (!endp) // this entry isn't NUL terminated
743 return nullptr;
744 else if (!internal_memcmp(s1: p, s2: name, n: namelen) && p[namelen] == '=') // Match.
745 return p + namelen + 1; // point after =
746 p = endp + 1;
747 }
748 return nullptr; // Not found.
749# else
750# error "Unsupported platform"
751# endif
752}
753
754# if !SANITIZER_HAIKU && !SANITIZER_FREEBSD && !SANITIZER_NETBSD && \
755 !SANITIZER_GO
756extern "C" {
757SANITIZER_WEAK_ATTRIBUTE extern void *__libc_stack_end;
758}
759# endif
760
761# if !SANITIZER_HAIKU && !SANITIZER_FREEBSD && !SANITIZER_NETBSD
762static void ReadNullSepFileToArray(const char *path, char ***arr,
763 int arr_size) {
764 char *buff;
765 uptr buff_size;
766 uptr buff_len;
767 *arr = (char **)MmapOrDie(size: arr_size * sizeof(char *), mem_type: "NullSepFileArray");
768 if (!ReadFileToBuffer(file_name: path, buff: &buff, buff_size: &buff_size, read_len: &buff_len, max_len: 1024 * 1024)) {
769 (*arr)[0] = nullptr;
770 return;
771 }
772 (*arr)[0] = buff;
773 int count, i;
774 for (count = 1, i = 1;; i++) {
775 if (buff[i] == 0) {
776 if (buff[i + 1] == 0)
777 break;
778 (*arr)[count] = &buff[i + 1];
779 CHECK_LE(count, arr_size - 1); // FIXME: make this more flexible.
780 count++;
781 }
782 }
783 (*arr)[count] = nullptr;
784}
785# endif
786
787static void GetArgsAndEnv(char ***argv, char ***envp) {
788# if SANITIZER_HAIKU
789 *argv = __libc_argv;
790 *envp = environ;
791# elif SANITIZER_FREEBSD
792 // On FreeBSD, retrieving the argument and environment arrays is done via the
793 // kern.ps_strings sysctl, which returns a pointer to a structure containing
794 // this information. See also <sys/exec.h>.
795 ps_strings *pss;
796 uptr sz = sizeof(pss);
797 if (internal_sysctlbyname("kern.ps_strings", &pss, &sz, NULL, 0) == -1) {
798 Printf("sysctl kern.ps_strings failed\n");
799 Die();
800 }
801 *argv = pss->ps_argvstr;
802 *envp = pss->ps_envstr;
803# elif SANITIZER_NETBSD
804 *argv = __ps_strings->ps_argvstr;
805 *envp = __ps_strings->ps_envstr;
806# else // SANITIZER_FREEBSD
807# if !SANITIZER_GO
808 if (&__libc_stack_end) {
809 uptr *stack_end = (uptr *)__libc_stack_end;
810 // Linux/sparc64 needs an adjustment, cf. glibc
811 // sysdeps/sparc/sparc{32,64}/dl-machine.h (DL_STACK_END).
812# if SANITIZER_LINUX && defined(__sparc__)
813 stack_end = &stack_end[16];
814# endif
815 // Normally argc can be obtained from *stack_end, however, on ARM glibc's
816 // _start clobbers it:
817 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/arm/start.S;hb=refs/heads/release/2.31/master#l75
818 // Do not special-case ARM and infer argc from argv everywhere.
819 int argc = 0;
820 while (stack_end[argc + 1]) argc++;
821 *argv = (char **)(stack_end + 1);
822 *envp = (char **)(stack_end + argc + 2);
823 } else {
824# endif // !SANITIZER_GO
825 static const int kMaxArgv = 2000, kMaxEnvp = 2000;
826 ReadNullSepFileToArray(path: "/proc/self/cmdline", arr: argv, arr_size: kMaxArgv);
827 ReadNullSepFileToArray(path: "/proc/self/environ", arr: envp, arr_size: kMaxEnvp);
828# if !SANITIZER_GO
829 }
830# endif // !SANITIZER_GO
831# endif // SANITIZER_HAIKU
832}
833
834char **GetArgv() {
835 char **argv, **envp;
836 GetArgsAndEnv(argv: &argv, envp: &envp);
837 return argv;
838}
839
840char **GetEnviron() {
841 char **argv, **envp;
842 GetArgsAndEnv(argv: &argv, envp: &envp);
843 return envp;
844}
845
846# if !SANITIZER_SOLARIS
847void FutexWait(atomic_uint32_t *p, u32 cmp) {
848# if SANITIZER_FREEBSD
849 _umtx_op(p, UMTX_OP_WAIT_UINT, cmp, 0, 0);
850# elif SANITIZER_NETBSD || SANITIZER_HAIKU
851 sched_yield(); /* No userspace futex-like synchronization */
852# else
853 internal_syscall(SYSCALL(futex), arg1: (uptr)p, arg2: FUTEX_WAIT_PRIVATE, arg3: cmp, arg4: 0, arg5: 0, arg6: 0);
854# endif
855}
856
857void FutexWake(atomic_uint32_t *p, u32 count) {
858# if SANITIZER_FREEBSD
859 _umtx_op(p, UMTX_OP_WAKE, count, 0, 0);
860# elif SANITIZER_NETBSD || SANITIZER_HAIKU
861 /* No userspace futex-like synchronization */
862# else
863 internal_syscall(SYSCALL(futex), arg1: (uptr)p, arg2: FUTEX_WAKE_PRIVATE, arg3: count, arg4: 0, arg5: 0, arg6: 0);
864# endif
865}
866
867# endif // !SANITIZER_SOLARIS
868
869// ----------------- sanitizer_linux.h
870// The actual size of this structure is specified by d_reclen.
871// Note that getdents64 uses a different structure format. We only provide the
872// 32-bit syscall here.
873# if SANITIZER_NETBSD
874// Not used
875# else
876struct linux_dirent {
877# if SANITIZER_X32 || SANITIZER_LINUX
878 u64 d_ino;
879 u64 d_off;
880# else
881 unsigned long d_ino;
882 unsigned long d_off;
883# endif
884 unsigned short d_reclen;
885# if SANITIZER_LINUX
886 unsigned char d_type;
887# endif
888 char d_name[256];
889};
890# endif
891
892# if !SANITIZER_SOLARIS && !SANITIZER_NETBSD && !SANITIZER_HAIKU
893// Syscall wrappers.
894uptr internal_ptrace(int request, int pid, void *addr, void *data) {
895 return internal_syscall(SYSCALL(ptrace), arg1: request, arg2: pid, arg3: (uptr)addr,
896 arg4: (uptr)data);
897}
898
899uptr internal_waitpid(int pid, int *status, int options) {
900 return internal_syscall(SYSCALL(wait4), arg1: pid, arg2: (uptr)status, arg3: options,
901 arg4: 0 /* rusage */);
902}
903
904uptr internal_getpid() { return internal_syscall(SYSCALL(getpid)); }
905
906uptr internal_getppid() { return internal_syscall(SYSCALL(getppid)); }
907
908int internal_dlinfo(void *handle, int request, void *p) {
909# if SANITIZER_FREEBSD
910 return dlinfo(handle, request, p);
911# else
912 UNIMPLEMENTED();
913# endif
914}
915
916uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count) {
917# if SANITIZER_FREEBSD
918 return internal_syscall(SYSCALL(getdirentries), fd, (uptr)dirp, count, NULL);
919# elif SANITIZER_LINUX
920 return internal_syscall(SYSCALL(getdents64), arg1: fd, arg2: (uptr)dirp, arg3: count);
921# else
922 return internal_syscall(SYSCALL(getdents), fd, (uptr)dirp, count);
923# endif
924}
925
926uptr internal_lseek(fd_t fd, OFF_T offset, int whence) {
927 return internal_syscall(SYSCALL(lseek), arg1: fd, arg2: offset, arg3: whence);
928}
929
930# if SANITIZER_LINUX
931uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5) {
932 return internal_syscall(SYSCALL(prctl), arg1: option, arg2, arg3, arg4, arg5);
933}
934# if defined(__x86_64__)
935# include <asm/unistd_64.h>
936// Currently internal_arch_prctl() is only needed on x86_64.
937uptr internal_arch_prctl(int option, uptr arg2) {
938 return internal_syscall(__NR_arch_prctl, arg1: option, arg2);
939}
940# endif
941# endif
942
943uptr internal_sigaltstack(const void *ss, void *oss) {
944 return internal_syscall(SYSCALL(sigaltstack), arg1: (uptr)ss, arg2: (uptr)oss);
945}
946
947extern "C" pid_t __fork(void);
948
949int internal_fork() {
950# if SANITIZER_LINUX
951# if SANITIZER_S390
952 return internal_syscall(SYSCALL(clone), 0, SIGCHLD);
953# elif SANITIZER_SPARC
954 // The clone syscall interface on SPARC differs massively from the rest,
955 // so fall back to __fork.
956 return __fork();
957# else
958 return internal_syscall(SYSCALL(clone), SIGCHLD, arg2: 0);
959# endif
960# else
961 return internal_syscall(SYSCALL(fork));
962# endif
963}
964
965# if SANITIZER_FREEBSD
966int internal_sysctl(const int *name, unsigned int namelen, void *oldp,
967 uptr *oldlenp, const void *newp, uptr newlen) {
968 return internal_syscall(SYSCALL(__sysctl), name, namelen, oldp,
969 (size_t *)oldlenp, newp, (size_t)newlen);
970}
971
972int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp,
973 const void *newp, uptr newlen) {
974 // Note: this function can be called during startup, so we need to avoid
975 // calling any interceptable functions. On FreeBSD >= 1300045 sysctlbyname()
976 // is a real syscall, but for older versions it calls sysctlnametomib()
977 // followed by sysctl(). To avoid calling the intercepted version and
978 // asserting if this happens during startup, call the real sysctlnametomib()
979 // followed by internal_sysctl() if the syscall is not available.
980# ifdef SYS___sysctlbyname
981 return internal_syscall(SYSCALL(__sysctlbyname), sname,
982 internal_strlen(sname), oldp, (size_t *)oldlenp, newp,
983 (size_t)newlen);
984# else
985 static decltype(sysctlnametomib) *real_sysctlnametomib = nullptr;
986 if (!real_sysctlnametomib)
987 real_sysctlnametomib =
988 (decltype(sysctlnametomib) *)dlsym(RTLD_NEXT, "sysctlnametomib");
989 CHECK(real_sysctlnametomib);
990
991 int oid[CTL_MAXNAME];
992 size_t len = CTL_MAXNAME;
993 if (real_sysctlnametomib(sname, oid, &len) == -1)
994 return (-1);
995 return internal_sysctl(oid, len, oldp, oldlenp, newp, newlen);
996# endif
997}
998# endif
999
1000# if SANITIZER_LINUX
1001# define SA_RESTORER 0x04000000
1002// Doesn't set sa_restorer if the caller did not set it, so use with caution
1003//(see below).
1004int internal_sigaction_norestorer(int signum, const void *act, void *oldact) {
1005 __sanitizer_kernel_sigaction_t k_act, k_oldact;
1006 internal_memset(s: &k_act, c: 0, n: sizeof(__sanitizer_kernel_sigaction_t));
1007 internal_memset(s: &k_oldact, c: 0, n: sizeof(__sanitizer_kernel_sigaction_t));
1008 const __sanitizer_sigaction *u_act = (const __sanitizer_sigaction *)act;
1009 __sanitizer_sigaction *u_oldact = (__sanitizer_sigaction *)oldact;
1010 if (u_act) {
1011 k_act.handler = u_act->handler;
1012 k_act.sigaction = u_act->sigaction;
1013 internal_memcpy(dest: &k_act.sa_mask, src: &u_act->sa_mask,
1014 n: sizeof(__sanitizer_kernel_sigset_t));
1015 // Without SA_RESTORER kernel ignores the calls (probably returns EINVAL).
1016 k_act.sa_flags = u_act->sa_flags | SA_RESTORER;
1017 // FIXME: most often sa_restorer is unset, however the kernel requires it
1018 // to point to a valid signal restorer that calls the rt_sigreturn syscall.
1019 // If sa_restorer passed to the kernel is NULL, the program may crash upon
1020 // signal delivery or fail to unwind the stack in the signal handler.
1021 // libc implementation of sigaction() passes its own restorer to
1022 // rt_sigaction, so we need to do the same (we'll need to reimplement the
1023 // restorers; for x86_64 the restorer address can be obtained from
1024 // oldact->sa_restorer upon a call to sigaction(xxx, NULL, oldact).
1025# if (!SANITIZER_ANDROID || !SANITIZER_MIPS32) && !defined(__alpha__)
1026 k_act.sa_restorer = u_act->sa_restorer;
1027# endif
1028 }
1029
1030 uptr result = internal_syscall(SYSCALL(rt_sigaction), arg1: (uptr)signum,
1031 arg2: (uptr)(u_act ? &k_act : nullptr),
1032 arg3: (uptr)(u_oldact ? &k_oldact : nullptr),
1033 arg4: (uptr)sizeof(__sanitizer_kernel_sigset_t));
1034
1035 if ((result == 0) && u_oldact) {
1036 u_oldact->handler = k_oldact.handler;
1037 u_oldact->sigaction = k_oldact.sigaction;
1038 internal_memcpy(dest: &u_oldact->sa_mask, src: &k_oldact.sa_mask,
1039 n: sizeof(__sanitizer_kernel_sigset_t));
1040 u_oldact->sa_flags = k_oldact.sa_flags;
1041# if (!SANITIZER_ANDROID || !SANITIZER_MIPS32) && !defined(__alpha__)
1042 u_oldact->sa_restorer = k_oldact.sa_restorer;
1043# endif
1044 }
1045 return result;
1046}
1047# endif // SANITIZER_LINUX
1048
1049uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
1050 __sanitizer_sigset_t *oldset) {
1051# if SANITIZER_FREEBSD
1052 return internal_syscall(SYSCALL(sigprocmask), how, set, oldset);
1053# else
1054 __sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;
1055 __sanitizer_kernel_sigset_t *k_oldset = (__sanitizer_kernel_sigset_t *)oldset;
1056 return internal_syscall(SYSCALL(rt_sigprocmask), arg1: (uptr)how, arg2: (uptr)k_set,
1057 arg3: (uptr)k_oldset, arg4: sizeof(__sanitizer_kernel_sigset_t));
1058# endif
1059}
1060
1061void internal_sigfillset(__sanitizer_sigset_t *set) {
1062 internal_memset(s: set, c: 0xff, n: sizeof(*set));
1063}
1064
1065void internal_sigemptyset(__sanitizer_sigset_t *set) {
1066 internal_memset(s: set, c: 0, n: sizeof(*set));
1067}
1068
1069# if SANITIZER_LINUX
1070void internal_sigdelset(__sanitizer_sigset_t *set, int signum) {
1071 signum -= 1;
1072 CHECK_GE(signum, 0);
1073 CHECK_LT(signum, sizeof(*set) * 8);
1074 __sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;
1075 const uptr idx = signum / (sizeof(k_set->sig[0]) * 8);
1076 const uptr bit = signum % (sizeof(k_set->sig[0]) * 8);
1077 k_set->sig[idx] &= ~((uptr)1 << bit);
1078}
1079
1080bool internal_sigismember(__sanitizer_sigset_t *set, int signum) {
1081 signum -= 1;
1082 CHECK_GE(signum, 0);
1083 CHECK_LT(signum, sizeof(*set) * 8);
1084 __sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;
1085 const uptr idx = signum / (sizeof(k_set->sig[0]) * 8);
1086 const uptr bit = signum % (sizeof(k_set->sig[0]) * 8);
1087 return k_set->sig[idx] & ((uptr)1 << bit);
1088}
1089# elif SANITIZER_FREEBSD
1090uptr internal_procctl(int type, int id, int cmd, void *data) {
1091 return internal_syscall(SYSCALL(procctl), type, id, cmd, data);
1092}
1093
1094void internal_sigdelset(__sanitizer_sigset_t *set, int signum) {
1095 sigset_t *rset = reinterpret_cast<sigset_t *>(set);
1096 sigdelset(rset, signum);
1097}
1098
1099bool internal_sigismember(__sanitizer_sigset_t *set, int signum) {
1100 sigset_t *rset = reinterpret_cast<sigset_t *>(set);
1101 return sigismember(rset, signum);
1102}
1103# endif
1104# endif // !SANITIZER_SOLARIS
1105
1106# if !SANITIZER_NETBSD && !SANITIZER_HAIKU
1107// ThreadLister implementation.
1108ThreadLister::ThreadLister(pid_t pid) : buffer_(4096) {
1109 task_path_.AppendF(format: "/proc/%d/task", pid);
1110}
1111
1112ThreadLister::Result ThreadLister::ListThreads(
1113 InternalMmapVector<ThreadID> *threads) {
1114 int descriptor = internal_open(filename: task_path_.data(), O_RDONLY | O_DIRECTORY);
1115 if (internal_iserror(retval: descriptor)) {
1116 Report(format: "Can't open %s for reading.\n", task_path_.data());
1117 return Error;
1118 }
1119 auto cleanup = at_scope_exit(fn: [&] { internal_close(fd: descriptor); });
1120 threads->clear();
1121
1122 Result result = Ok;
1123 for (bool first_read = true;; first_read = false) {
1124 CHECK_GE(buffer_.size(), 4096);
1125 uptr read = internal_getdents(
1126 fd: descriptor, dirp: (struct linux_dirent *)buffer_.data(), count: buffer_.size());
1127 if (!read)
1128 return result;
1129 if (internal_iserror(retval: read)) {
1130 Report(format: "Can't read directory entries from %s.\n", task_path_.data());
1131 return Error;
1132 }
1133
1134 for (uptr begin = (uptr)buffer_.data(), end = begin + read; begin < end;) {
1135 struct linux_dirent *entry = (struct linux_dirent *)begin;
1136 begin += entry->d_reclen;
1137 if (entry->d_ino == 1) {
1138 // Inode 1 is for bad blocks and also can be a reason for early return.
1139 // Should be emitted if kernel tried to output terminating thread.
1140 // See proc_task_readdir implementation in Linux.
1141 result = Incomplete;
1142 }
1143 if (entry->d_ino && *entry->d_name >= '0' && *entry->d_name <= '9')
1144 threads->push_back(element: internal_atoll(nptr: entry->d_name));
1145 }
1146
1147 // Now we are going to detect short-read or early EOF. In such cases Linux
1148 // can return inconsistent list with missing alive threads.
1149 // Code will just remember that the list can be incomplete but it will
1150 // continue reads to return as much as possible.
1151 if (!first_read) {
1152 // The first one was a short-read by definition.
1153 result = Incomplete;
1154 } else if (read > buffer_.size() - 1024) {
1155 // Read was close to the buffer size. So double the size and assume the
1156 // worst.
1157 buffer_.resize(new_size: buffer_.size() * 2);
1158 result = Incomplete;
1159 } else if (!threads->empty() && !IsAlive(tid: threads->back())) {
1160 // Maybe Linux early returned from read on terminated thread (!pid_alive)
1161 // and failed to restore read position.
1162 // See next_tid and proc_task_instantiate in Linux.
1163 result = Incomplete;
1164 }
1165 }
1166}
1167
1168const char *ThreadLister::LoadStatus(ThreadID tid) {
1169 status_path_.clear();
1170 status_path_.AppendF(format: "%s/%llu/status", task_path_.data(), tid);
1171 auto cleanup = at_scope_exit(fn: [&] {
1172 // Resize back to capacity if it is downsized by `ReadFileToVector`.
1173 buffer_.resize(new_size: buffer_.capacity());
1174 });
1175 if (!ReadFileToVector(file_name: status_path_.data(), buff: &buffer_) || buffer_.empty())
1176 return nullptr;
1177 buffer_.push_back(element: '\0');
1178 return buffer_.data();
1179}
1180
1181bool ThreadLister::IsAlive(ThreadID tid) {
1182 // /proc/%d/task/%d/status uses same call to detect alive threads as
1183 // proc_task_readdir. See task_state implementation in Linux.
1184 static const char kPrefix[] = "\nPPid:";
1185 const char *status = LoadStatus(tid);
1186 if (!status)
1187 return false;
1188 const char *field = internal_strstr(haystack: status, needle: kPrefix);
1189 if (!field)
1190 return false;
1191 field += internal_strlen(s: kPrefix);
1192 return (int)internal_atoll(nptr: field) != 0;
1193}
1194
1195# endif
1196
1197# if SANITIZER_WORDSIZE == 32
1198// Take care of unusable kernel area in top gigabyte.
1199static uptr GetKernelAreaSize() {
1200# if SANITIZER_LINUX && !SANITIZER_X32
1201 const uptr gbyte = 1UL << 30;
1202
1203 // Firstly check if there are writable segments
1204 // mapped to top gigabyte (e.g. stack).
1205 MemoryMappingLayout proc_maps(/*cache_enabled*/ true);
1206 if (proc_maps.Error())
1207 return 0;
1208 MemoryMappedSegment segment;
1209 while (proc_maps.Next(&segment)) {
1210 if ((segment.end >= 3 * gbyte) && segment.IsWritable())
1211 return 0;
1212 }
1213
1214# if !SANITIZER_ANDROID
1215 // Even if nothing is mapped, top Gb may still be accessible
1216 // if we are running on 64-bit kernel.
1217 // Uname may report misleading results if personality type
1218 // is modified (e.g. under schroot) so check this as well.
1219 struct utsname uname_info;
1220 int pers = personality(0xffffffffUL);
1221 if (!(pers & PER_MASK) && internal_uname(&uname_info) == 0 &&
1222 internal_strstr(uname_info.machine, "64"))
1223 return 0;
1224# endif // SANITIZER_ANDROID
1225
1226 // Top gigabyte is reserved for kernel.
1227 return gbyte;
1228# else
1229 return 0;
1230# endif // SANITIZER_LINUX && !SANITIZER_X32
1231}
1232# endif // SANITIZER_WORDSIZE == 32
1233
1234uptr GetMaxVirtualAddress() {
1235# if SANITIZER_NETBSD && defined(__x86_64__)
1236 return 0x7f7ffffff000ULL; // (0x00007f8000000000 - PAGE_SIZE)
1237# elif SANITIZER_WORDSIZE == 64
1238# if defined(__powerpc64__) || defined(__aarch64__) || \
1239 defined(__loongarch__) || SANITIZER_RISCV64
1240 // On PowerPC64 we have two different address space layouts: 44- and 46-bit.
1241 // We somehow need to figure out which one we are using now and choose
1242 // one of 0x00000fffffffffffUL and 0x00003fffffffffffUL.
1243 // Note that with 'ulimit -s unlimited' the stack is moved away from the top
1244 // of the address space, so simply checking the stack address is not enough.
1245 // This should (does) work for both PowerPC64 Endian modes.
1246 // Similarly, aarch64 has multiple address space layouts: 39, 42 and 47-bit.
1247 // loongarch64 also has multiple address space layouts: default is 47-bit.
1248 // RISC-V 64 also has multiple address space layouts: 39, 48 and 57-bit.
1249 return (1ULL << (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1)) - 1;
1250# elif SANITIZER_ALPHA
1251 // Linux/Alpha uses a 42-bit user VAS (TASK_SIZE = 0x40000000000). With
1252 // fixed shadow offset 0x10000000000 (1 TiB) the layout is:
1253 // LowMem: [0x000000000000, 0x00ffffffffff] (1 TiB)
1254 // LowShadow: [0x010000000000, 0x011fffffffff] (128 GiB)
1255 // ShadowGap: [0x012000000000, 0x012fffffffff]
1256 // HighShadow:[0x013000000000, 0x017fffffffff] (256 GiB)
1257 // HighMem: [0x018000000000, 0x03ffffffffff] (2.5 TiB, stack near top)
1258 // Capping at TASK_SIZE - 1 avoids treating kernel addresses as HighMem.
1259 return (1ULL << 42) - 1; // TASK_SIZE - 1
1260# elif SANITIZER_MIPS64
1261 return (1ULL << 40) - 1; // 0x000000ffffffffffUL;
1262# elif defined(__s390x__)
1263 return (1ULL << 53) - 1; // 0x001fffffffffffffUL;
1264# elif defined(__sparc__)
1265 return ~(uptr)0;
1266# else
1267 return (1ULL << 47) - 1; // 0x00007fffffffffffUL;
1268# endif
1269# else // SANITIZER_WORDSIZE == 32
1270# if defined(__s390__)
1271 return (1ULL << 31) - 1; // 0x7fffffff;
1272# else
1273 return (1ULL << 32) - 1; // 0xffffffff;
1274# endif
1275# endif // SANITIZER_WORDSIZE
1276}
1277
1278uptr GetMaxUserVirtualAddress() {
1279 uptr addr = GetMaxVirtualAddress();
1280# if SANITIZER_WORDSIZE == 32 && !defined(__s390__)
1281 if (!common_flags()->full_address_space)
1282 addr -= GetKernelAreaSize();
1283 CHECK_LT(reinterpret_cast<uptr>(&addr), addr);
1284# endif
1285 return addr;
1286}
1287
1288# if !SANITIZER_ANDROID || defined(__aarch64__)
1289uptr GetPageSize() {
1290# if SANITIZER_LINUX && (defined(__x86_64__) || defined(__i386__)) && \
1291 defined(EXEC_PAGESIZE)
1292 return EXEC_PAGESIZE;
1293# elif SANITIZER_FREEBSD || SANITIZER_NETBSD
1294 // Use sysctl as sysconf can trigger interceptors internally.
1295 int pz = 0;
1296 uptr pzl = sizeof(pz);
1297 int mib[2] = {CTL_HW, HW_PAGESIZE};
1298 int rv = internal_sysctl(mib, 2, &pz, &pzl, nullptr, 0);
1299 CHECK_EQ(rv, 0);
1300 return (uptr)pz;
1301# elif SANITIZER_USE_GETAUXVAL
1302# if SANITIZER_ANDROID && __ANDROID_API__ < 35
1303 // The 16 KB page size was introduced in Android 15 (API level 35), while
1304 // earlier versions of Android always used a 4 KB page size.
1305 // We are checking the weak definition of `strerrorname_np` (introduced in API
1306 // level 35) because some earlier API levels crashed when
1307 // `getauxval(AT_PAGESZ)` was called from the `.preinit_array`.
1308 if (!strerrorname_np)
1309 return 4096;
1310# endif
1311
1312 return getauxval(AT_PAGESZ);
1313# else
1314 return sysconf(_SC_PAGESIZE); // EXEC_PAGESIZE may not be trustworthy.
1315# endif
1316}
1317# endif
1318
1319uptr ReadBinaryName(/*out*/ char *buf, uptr buf_len) {
1320# if SANITIZER_HAIKU
1321 int32 cookie = 0;
1322 image_info info;
1323 const char *argv0 = "<UNKNOWN>";
1324 while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) {
1325 if (info.type != B_APP_IMAGE)
1326 continue;
1327 argv0 = info.name;
1328 break;
1329 }
1330 internal_strncpy(buf, argv0, buf_len);
1331 return internal_strlen(buf);
1332# elif SANITIZER_SOLARIS
1333 const char *default_module_name = getexecname();
1334 CHECK_NE(default_module_name, NULL);
1335 return internal_snprintf(buf, buf_len, "%s", default_module_name);
1336# else
1337# if SANITIZER_FREEBSD || SANITIZER_NETBSD
1338# if SANITIZER_FREEBSD
1339 const int Mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
1340# else
1341 const int Mib[4] = {CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME};
1342# endif
1343 const char *default_module_name = "kern.proc.pathname";
1344 uptr Size = buf_len;
1345 bool IsErr =
1346 (internal_sysctl(Mib, ARRAY_SIZE(Mib), buf, &Size, NULL, 0) != 0);
1347 int readlink_error = IsErr ? errno : 0;
1348 uptr module_name_len = Size;
1349# else
1350 const char *default_module_name = "/proc/self/exe";
1351 uptr module_name_len = internal_readlink(path: default_module_name, buf, bufsize: buf_len);
1352 int readlink_error;
1353 bool IsErr = internal_iserror(retval: module_name_len, rverrno: &readlink_error);
1354# endif
1355 if (IsErr) {
1356 // We can't read binary name for some reason, assume it's unknown.
1357 Report(
1358 format: "WARNING: reading executable name failed with errno %d, "
1359 "some stack frames may not be symbolized\n",
1360 readlink_error);
1361 module_name_len =
1362 internal_snprintf(buffer: buf, length: buf_len, format: "%s", default_module_name);
1363 CHECK_LT(module_name_len, buf_len);
1364 }
1365 return module_name_len;
1366# endif
1367}
1368
1369uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) {
1370# if SANITIZER_LINUX
1371 char *tmpbuf;
1372 uptr tmpsize;
1373 uptr tmplen;
1374 if (ReadFileToBuffer(file_name: "/proc/self/cmdline", buff: &tmpbuf, buff_size: &tmpsize, read_len: &tmplen,
1375 max_len: 1024 * 1024)) {
1376 internal_strncpy(dst: buf, src: tmpbuf, n: buf_len);
1377 UnmapOrDie(addr: tmpbuf, size: tmpsize);
1378 return internal_strlen(s: buf);
1379 }
1380# endif
1381 return ReadBinaryName(buf, buf_len);
1382}
1383
1384// Match full names of the form /path/to/base_name{-,.}*
1385bool LibraryNameIs(const char *full_name, const char *base_name) {
1386 const char *name = full_name;
1387 // Strip path.
1388 while (*name != '\0') name++;
1389 while (name > full_name && *name != '/') name--;
1390 if (*name == '/')
1391 name++;
1392 uptr base_name_length = internal_strlen(s: base_name);
1393 if (internal_strncmp(s1: name, s2: base_name, n: base_name_length))
1394 return false;
1395 return (name[base_name_length] == '-' || name[base_name_length] == '.');
1396}
1397
1398# if !SANITIZER_ANDROID && !SANITIZER_HAIKU
1399// Call cb for each region mapped by map.
1400void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)) {
1401 CHECK_NE(map, nullptr);
1402# if !SANITIZER_FREEBSD && !SANITIZER_HAIKU
1403 typedef ElfW(Phdr) Elf_Phdr;
1404 typedef ElfW(Ehdr) Elf_Ehdr;
1405# endif // !SANITIZER_FREEBSD
1406 char *base = (char *)map->l_addr;
1407 Elf_Ehdr *ehdr = (Elf_Ehdr *)base;
1408 char *phdrs = base + ehdr->e_phoff;
1409 char *phdrs_end = phdrs + ehdr->e_phnum * ehdr->e_phentsize;
1410
1411 // Find the segment with the minimum base so we can "relocate" the p_vaddr
1412 // fields. Typically ET_DYN objects (DSOs) have base of zero and ET_EXEC
1413 // objects have a non-zero base.
1414 uptr preferred_base = (uptr)-1;
1415 for (char *iter = phdrs; iter != phdrs_end; iter += ehdr->e_phentsize) {
1416 Elf_Phdr *phdr = (Elf_Phdr *)iter;
1417 if (phdr->p_type == PT_LOAD && preferred_base > (uptr)phdr->p_vaddr)
1418 preferred_base = (uptr)phdr->p_vaddr;
1419 }
1420
1421 // Compute the delta from the real base to get a relocation delta.
1422 sptr delta = (uptr)base - preferred_base;
1423 // Now we can figure out what the loader really mapped.
1424 for (char *iter = phdrs; iter != phdrs_end; iter += ehdr->e_phentsize) {
1425 Elf_Phdr *phdr = (Elf_Phdr *)iter;
1426 if (phdr->p_type == PT_LOAD) {
1427 uptr seg_start = phdr->p_vaddr + delta;
1428 uptr seg_end = seg_start + phdr->p_memsz;
1429 // None of these values are aligned. We consider the ragged edges of the
1430 // load command as defined, since they are mapped from the file.
1431 seg_start = RoundDownTo(x: seg_start, boundary: GetPageSizeCached());
1432 seg_end = RoundUpTo(size: seg_end, boundary: GetPageSizeCached());
1433 cb((void *)seg_start, seg_end - seg_start);
1434 }
1435 }
1436}
1437# endif
1438
1439# if SANITIZER_LINUX
1440# if defined(__x86_64__)
1441// We cannot use glibc's clone wrapper, because it messes with the child
1442// task's TLS. It writes the PID and TID of the child task to its thread
1443// descriptor, but in our case the child task shares the thread descriptor with
1444// the parent (because we don't know how to allocate a new thread
1445// descriptor to keep glibc happy). So the stock version of clone(), when
1446// used with CLONE_VM, would end up corrupting the parent's thread descriptor.
1447uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
1448 int *parent_tidptr, void *newtls, int *child_tidptr) {
1449 long long res;
1450 if (!fn || !child_stack)
1451 return -EINVAL;
1452 CHECK_EQ(0, (uptr)child_stack % 16);
1453 child_stack = (char *)child_stack - 2 * sizeof(unsigned long long);
1454 ((unsigned long long *)child_stack)[0] = (uptr)fn;
1455 ((unsigned long long *)child_stack)[1] = (uptr)arg;
1456 register void *r8 __asm__("r8") = newtls;
1457 register int *r10 __asm__("r10") = child_tidptr;
1458 __asm__ __volatile__(
1459 /* %rax = syscall(%rax = SYSCALL(clone),
1460 * %rdi = flags,
1461 * %rsi = child_stack,
1462 * %rdx = parent_tidptr,
1463 * %r8 = new_tls,
1464 * %r10 = child_tidptr)
1465 */
1466 "syscall\n"
1467
1468 /* if (%rax != 0)
1469 * return;
1470 */
1471 "testq %%rax,%%rax\n"
1472 "jnz 1f\n"
1473
1474 /* In the child. Terminate unwind chain. */
1475 // XXX: We should also terminate the CFI unwind chain
1476 // here. Unfortunately clang 3.2 doesn't support the
1477 // necessary CFI directives, so we skip that part.
1478 "xorq %%rbp,%%rbp\n"
1479
1480 /* Call "fn(arg)". */
1481 "popq %%rax\n"
1482 "popq %%rdi\n"
1483 "call *%%rax\n"
1484
1485 /* Call _exit(%rax). */
1486 "movq %%rax,%%rdi\n"
1487 "movq %2,%%rax\n"
1488 "syscall\n"
1489
1490 /* Return to parent. */
1491 "1:\n"
1492 : "=a"(res)
1493 : "a"(SYSCALL(clone)), "i"(SYSCALL(exit)), "S"(child_stack), "D"(flags),
1494 "d"(parent_tidptr), "r"(r8), "r"(r10)
1495 : "memory", "r11", "rcx");
1496 return res;
1497}
1498# elif defined(__mips__)
1499uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
1500 int *parent_tidptr, void *newtls, int *child_tidptr) {
1501 long long res;
1502 if (!fn || !child_stack)
1503 return -EINVAL;
1504 CHECK_EQ(0, (uptr)child_stack % 16);
1505 child_stack = (char *)child_stack - 2 * sizeof(unsigned long long);
1506 ((unsigned long long *)child_stack)[0] = (uptr)fn;
1507 ((unsigned long long *)child_stack)[1] = (uptr)arg;
1508 register void *a3 __asm__("$7") = newtls;
1509 register int *a4 __asm__("$8") = child_tidptr;
1510 // We don't have proper CFI directives here because it requires alot of code
1511 // for very marginal benefits.
1512 __asm__ __volatile__(
1513 /* $v0 = syscall($v0 = __NR_clone,
1514 * $a0 = flags,
1515 * $a1 = child_stack,
1516 * $a2 = parent_tidptr,
1517 * $a3 = new_tls,
1518 * $a4 = child_tidptr)
1519 */
1520 ".cprestore 16;\n"
1521 "move $4,%1;\n"
1522 "move $5,%2;\n"
1523 "move $6,%3;\n"
1524 "move $7,%4;\n"
1525 /* Store the fifth argument on stack
1526 * if we are using 32-bit abi.
1527 */
1528# if SANITIZER_WORDSIZE == 32
1529 "lw %5,16($29);\n"
1530# else
1531 "move $8,%5;\n"
1532# endif
1533 "li $2,%6;\n"
1534 "syscall;\n"
1535
1536 /* if ($v0 != 0)
1537 * return;
1538 */
1539 "bnez $2,1f;\n"
1540
1541 /* Call "fn(arg)". */
1542# if SANITIZER_WORDSIZE == 32
1543# ifdef __BIG_ENDIAN__
1544 "lw $25,4($29);\n"
1545 "lw $4,12($29);\n"
1546# else
1547 "lw $25,0($29);\n"
1548 "lw $4,8($29);\n"
1549# endif
1550# else
1551 "ld $25,0($29);\n"
1552 "ld $4,8($29);\n"
1553# endif
1554 "jal $25;\n"
1555
1556 /* Call _exit($v0). */
1557 "move $4,$2;\n"
1558 "li $2,%7;\n"
1559 "syscall;\n"
1560
1561 /* Return to parent. */
1562 "1:\n"
1563 : "=r"(res)
1564 : "r"(flags), "r"(child_stack), "r"(parent_tidptr), "r"(a3), "r"(a4),
1565 "i"(__NR_clone), "i"(__NR_exit)
1566 : "memory", "$29");
1567 return res;
1568}
1569# elif SANITIZER_RISCV64
1570uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
1571 int *parent_tidptr, void *newtls, int *child_tidptr) {
1572 if (!fn || !child_stack)
1573 return -EINVAL;
1574
1575 CHECK_EQ(0, (uptr)child_stack % 16);
1576
1577 register int res __asm__("a0");
1578 register int __flags __asm__("a0") = flags;
1579 register void *__stack __asm__("a1") = child_stack;
1580 register int *__ptid __asm__("a2") = parent_tidptr;
1581 register void *__tls __asm__("a3") = newtls;
1582 register int *__ctid __asm__("a4") = child_tidptr;
1583 register int (*__fn)(void *) __asm__("a5") = fn;
1584 register void *__arg __asm__("a6") = arg;
1585 register int nr_clone __asm__("a7") = __NR_clone;
1586
1587 __asm__ __volatile__(
1588 "ecall\n"
1589
1590 /* if (a0 != 0)
1591 * return a0;
1592 */
1593 "bnez a0, 1f\n"
1594
1595 // In the child, now. Call "fn(arg)".
1596 "mv a0, a6\n"
1597 "jalr a5\n"
1598
1599 // Call _exit(a0).
1600 "addi a7, zero, %9\n"
1601 "ecall\n"
1602 "1:\n"
1603
1604 : "=r"(res)
1605 : "0"(__flags), "r"(__stack), "r"(__ptid), "r"(__tls), "r"(__ctid),
1606 "r"(__fn), "r"(__arg), "r"(nr_clone), "i"(__NR_exit)
1607 : "memory");
1608 return res;
1609}
1610# elif defined(__aarch64__)
1611uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
1612 int *parent_tidptr, void *newtls, int *child_tidptr) {
1613 register long long res __asm__("x0");
1614 if (!fn || !child_stack)
1615 return -EINVAL;
1616 CHECK_EQ(0, (uptr)child_stack % 16);
1617 child_stack = (char *)child_stack - 2 * sizeof(unsigned long long);
1618 ((unsigned long long *)child_stack)[0] = (uptr)fn;
1619 ((unsigned long long *)child_stack)[1] = (uptr)arg;
1620
1621 register int (*__fn)(void *) __asm__("x0") = fn;
1622 register void *__stack __asm__("x1") = child_stack;
1623 register int __flags __asm__("x2") = flags;
1624 register void *__arg __asm__("x3") = arg;
1625 register int *__ptid __asm__("x4") = parent_tidptr;
1626 register void *__tls __asm__("x5") = newtls;
1627 register int *__ctid __asm__("x6") = child_tidptr;
1628
1629 __asm__ __volatile__(
1630 "mov x0,x2\n" /* flags */
1631 "mov x2,x4\n" /* ptid */
1632 "mov x3,x5\n" /* tls */
1633 "mov x4,x6\n" /* ctid */
1634 "mov x8,%9\n" /* clone */
1635
1636 "svc 0x0\n"
1637
1638 /* if (%r0 != 0)
1639 * return %r0;
1640 */
1641 "cmp x0, #0\n"
1642 "bne 1f\n"
1643
1644 /* In the child, now. Call "fn(arg)". */
1645 "ldp x1, x0, [sp], #16\n"
1646 "blr x1\n"
1647
1648 /* Call _exit(%r0). */
1649 "mov x8, %10\n"
1650 "svc 0x0\n"
1651 "1:\n"
1652
1653 : "=r"(res)
1654 : "i"(-EINVAL), "r"(__fn), "r"(__stack), "r"(__flags), "r"(__arg),
1655 "r"(__ptid), "r"(__tls), "r"(__ctid), "i"(__NR_clone), "i"(__NR_exit)
1656 : "x30", "memory");
1657 return res;
1658}
1659# elif SANITIZER_LOONGARCH64
1660uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
1661 int *parent_tidptr, void *newtls, int *child_tidptr) {
1662 if (!fn || !child_stack)
1663 return -EINVAL;
1664
1665 CHECK_EQ(0, (uptr)child_stack % 16);
1666
1667 register int res __asm__("$a0");
1668 register int __flags __asm__("$a0") = flags;
1669 register void *__stack __asm__("$a1") = child_stack;
1670 register int *__ptid __asm__("$a2") = parent_tidptr;
1671 register int *__ctid __asm__("$a3") = child_tidptr;
1672 register void *__tls __asm__("$a4") = newtls;
1673 register int (*__fn)(void *) __asm__("$a5") = fn;
1674 register void *__arg __asm__("$a6") = arg;
1675 register int nr_clone __asm__("$a7") = __NR_clone;
1676
1677 __asm__ __volatile__(
1678 "syscall 0\n"
1679
1680 // if ($a0 != 0)
1681 // return $a0;
1682 "bnez $a0, 1f\n"
1683
1684 // In the child, now. Call "fn(arg)".
1685 "move $a0, $a6\n"
1686 "jirl $ra, $a5, 0\n"
1687
1688 // Call _exit($a0).
1689 "addi.d $a7, $zero, %9\n"
1690 "syscall 0\n"
1691
1692 "1:\n"
1693
1694 : "=r"(res)
1695 : "0"(__flags), "r"(__stack), "r"(__ptid), "r"(__ctid), "r"(__tls),
1696 "r"(__fn), "r"(__arg), "r"(nr_clone), "i"(__NR_exit)
1697 : "memory", "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7",
1698 "$t8");
1699 return res;
1700}
1701# elif defined(__powerpc64__)
1702uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
1703 int *parent_tidptr, void *newtls, int *child_tidptr) {
1704 long long res;
1705// Stack frame structure.
1706# if SANITIZER_PPC64V1
1707 // Back chain == 0 (SP + 112)
1708 // Frame (112 bytes):
1709 // Parameter save area (SP + 48), 8 doublewords
1710 // TOC save area (SP + 40)
1711 // Link editor doubleword (SP + 32)
1712 // Compiler doubleword (SP + 24)
1713 // LR save area (SP + 16)
1714 // CR save area (SP + 8)
1715 // Back chain (SP + 0)
1716# define FRAME_SIZE 112
1717# define FRAME_TOC_SAVE_OFFSET 40
1718# elif SANITIZER_PPC64V2
1719 // Back chain == 0 (SP + 32)
1720 // Frame (32 bytes):
1721 // TOC save area (SP + 24)
1722 // LR save area (SP + 16)
1723 // CR save area (SP + 8)
1724 // Back chain (SP + 0)
1725# define FRAME_SIZE 32
1726# define FRAME_TOC_SAVE_OFFSET 24
1727# else
1728# error "Unsupported PPC64 ABI"
1729# endif
1730 if (!fn || !child_stack)
1731 return -EINVAL;
1732 CHECK_EQ(0, (uptr)child_stack % 16);
1733
1734 register int (*__fn)(void *) __asm__("r3") = fn;
1735 register void *__cstack __asm__("r4") = child_stack;
1736 register int __flags __asm__("r5") = flags;
1737 register void *__arg __asm__("r6") = arg;
1738 register int *__ptidptr __asm__("r7") = parent_tidptr;
1739 register void *__newtls __asm__("r8") = newtls;
1740 register int *__ctidptr __asm__("r9") = child_tidptr;
1741
1742 __asm__ __volatile__(
1743 /* fn and arg are saved across the syscall */
1744 "mr 28, %5\n\t"
1745 "mr 27, %8\n\t"
1746
1747 /* syscall
1748 r0 == __NR_clone
1749 r3 == flags
1750 r4 == child_stack
1751 r5 == parent_tidptr
1752 r6 == newtls
1753 r7 == child_tidptr */
1754 "mr 3, %7\n\t"
1755 "mr 5, %9\n\t"
1756 "mr 6, %10\n\t"
1757 "mr 7, %11\n\t"
1758 "li 0, %3\n\t"
1759 "sc\n\t"
1760
1761 /* Test if syscall was successful */
1762 "cmpdi cr1, 3, 0\n\t"
1763 "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
1764 "bne- cr1, 1f\n\t"
1765
1766 /* Set up stack frame */
1767 "li 29, 0\n\t"
1768 "stdu 29, -8(1)\n\t"
1769 "stdu 1, -%12(1)\n\t"
1770 /* Do the function call */
1771 "std 2, %13(1)\n\t"
1772# if SANITIZER_PPC64V1
1773 "ld 0, 0(28)\n\t"
1774 "ld 2, 8(28)\n\t"
1775 "mtctr 0\n\t"
1776# elif SANITIZER_PPC64V2
1777 "mr 12, 28\n\t"
1778 "mtctr 12\n\t"
1779# else
1780# error "Unsupported PPC64 ABI"
1781# endif
1782 "mr 3, 27\n\t"
1783 "bctrl\n\t"
1784 "ld 2, %13(1)\n\t"
1785
1786 /* Call _exit(r3) */
1787 "li 0, %4\n\t"
1788 "sc\n\t"
1789
1790 /* Return to parent */
1791 "1:\n\t"
1792 "mr %0, 3\n\t"
1793 : "=r"(res)
1794 : "0"(-1), "i"(EINVAL), "i"(__NR_clone), "i"(__NR_exit), "r"(__fn),
1795 "r"(__cstack), "r"(__flags), "r"(__arg), "r"(__ptidptr), "r"(__newtls),
1796 "r"(__ctidptr), "i"(FRAME_SIZE), "i"(FRAME_TOC_SAVE_OFFSET)
1797 : "cr0", "cr1", "memory", "ctr", "r0", "r27", "r28", "r29");
1798 return res;
1799}
1800# elif defined(__i386__)
1801uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
1802 int *parent_tidptr, void *newtls, int *child_tidptr) {
1803 int res;
1804 if (!fn || !child_stack)
1805 return -EINVAL;
1806 CHECK_EQ(0, (uptr)child_stack % 16);
1807 child_stack = (char *)child_stack - 7 * sizeof(unsigned int);
1808 ((unsigned int *)child_stack)[0] = (uptr)flags;
1809 ((unsigned int *)child_stack)[1] = (uptr)0;
1810 ((unsigned int *)child_stack)[2] = (uptr)fn;
1811 ((unsigned int *)child_stack)[3] = (uptr)arg;
1812 __asm__ __volatile__(
1813 /* %eax = syscall(%eax = SYSCALL(clone),
1814 * %ebx = flags,
1815 * %ecx = child_stack,
1816 * %edx = parent_tidptr,
1817 * %esi = new_tls,
1818 * %edi = child_tidptr)
1819 */
1820
1821 /* Obtain flags */
1822 "movl (%%ecx), %%ebx\n"
1823 /* Do the system call */
1824 "pushl %%ebx\n"
1825 "pushl %%esi\n"
1826 "pushl %%edi\n"
1827 /* Remember the flag value. */
1828 "movl %%ebx, (%%ecx)\n"
1829 "int $0x80\n"
1830 "popl %%edi\n"
1831 "popl %%esi\n"
1832 "popl %%ebx\n"
1833
1834 /* if (%eax != 0)
1835 * return;
1836 */
1837
1838 "test %%eax,%%eax\n"
1839 "jnz 1f\n"
1840
1841 /* terminate the stack frame */
1842 "xorl %%ebp,%%ebp\n"
1843 /* Call FN. */
1844 "call *%%ebx\n"
1845# ifdef PIC
1846 "call here\n"
1847 "here:\n"
1848 "popl %%ebx\n"
1849 "addl $_GLOBAL_OFFSET_TABLE_+[.-here], %%ebx\n"
1850# endif
1851 /* Call exit */
1852 "movl %%eax, %%ebx\n"
1853 "movl %2, %%eax\n"
1854 "int $0x80\n"
1855 "1:\n"
1856 : "=a"(res)
1857 : "a"(SYSCALL(clone)), "i"(SYSCALL(exit)), "c"(child_stack),
1858 "d"(parent_tidptr), "S"(newtls), "D"(child_tidptr)
1859 : "memory");
1860 return res;
1861}
1862# elif defined(__arm__)
1863uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
1864 int *parent_tidptr, void *newtls, int *child_tidptr) {
1865 unsigned int res;
1866 if (!fn || !child_stack)
1867 return -EINVAL;
1868 child_stack = (char *)child_stack - 2 * sizeof(unsigned int);
1869 ((unsigned int *)child_stack)[0] = (uptr)fn;
1870 ((unsigned int *)child_stack)[1] = (uptr)arg;
1871 register int r0 __asm__("r0") = flags;
1872 register void *r1 __asm__("r1") = child_stack;
1873 register int *r2 __asm__("r2") = parent_tidptr;
1874 register void *r3 __asm__("r3") = newtls;
1875 register int *r4 __asm__("r4") = child_tidptr;
1876 register int r7 __asm__("r7") = __NR_clone;
1877
1878# if __ARM_ARCH > 4 || defined(__ARM_ARCH_4T__)
1879# define ARCH_HAS_BX
1880# endif
1881# if __ARM_ARCH > 4
1882# define ARCH_HAS_BLX
1883# endif
1884
1885# ifdef ARCH_HAS_BX
1886# ifdef ARCH_HAS_BLX
1887# define BLX(R) "blx " #R "\n"
1888# else
1889# define BLX(R) "mov lr, pc; bx " #R "\n"
1890# endif
1891# else
1892# define BLX(R) "mov lr, pc; mov pc," #R "\n"
1893# endif
1894
1895 __asm__ __volatile__(
1896 /* %r0 = syscall(%r7 = SYSCALL(clone),
1897 * %r0 = flags,
1898 * %r1 = child_stack,
1899 * %r2 = parent_tidptr,
1900 * %r3 = new_tls,
1901 * %r4 = child_tidptr)
1902 */
1903
1904 /* Do the system call */
1905 "swi 0x0\n"
1906
1907 /* if (%r0 != 0)
1908 * return %r0;
1909 */
1910 "cmp r0, #0\n"
1911 "bne 1f\n"
1912
1913 /* In the child, now. Call "fn(arg)". */
1914 "ldr r0, [sp, #4]\n"
1915 "ldr ip, [sp], #8\n" BLX(ip)
1916 /* Call _exit(%r0). */
1917 "mov r7, %7\n"
1918 "swi 0x0\n"
1919 "1:\n"
1920 "mov %0, r0\n"
1921 : "=r"(res)
1922 : "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r7), "i"(__NR_exit)
1923 : "memory");
1924 return res;
1925}
1926# elif defined(__hexagon__)
1927uptr internal_clone(int (*fn)(void*), void* child_stack, int flags, void* arg,
1928 int* parent_tidptr, void* newtls, int* child_tidptr) {
1929 if (!fn || !child_stack)
1930 return -EINVAL;
1931 child_stack = (char*)child_stack - 2 * sizeof(unsigned int);
1932 ((unsigned int*)child_stack)[0] = (uptr)fn;
1933 ((unsigned int*)child_stack)[1] = (uptr)arg;
1934
1935 // Hexagon clone syscall uses the generic argument order (no
1936 // CONFIG_CLONE_BACKWARDS): flags, stack, ptid, ctid, tls.
1937 register int r0 __asm__("r0") = flags;
1938 register void* r1 __asm__("r1") = child_stack;
1939 register int* r2 __asm__("r2") = parent_tidptr;
1940 register int* r3 __asm__("r3") = child_tidptr;
1941 register void* r4 __asm__("r4") = newtls;
1942 register int r6 __asm__("r6") = __NR_clone;
1943
1944 __asm__ __volatile__(
1945 "trap0(#1)\n" /* syscall */
1946 "{ p0 = cmp.eq(r0, #0)\n" /* child? */
1947 " if (!p0.new) jump:nt 1f }\n"
1948 "r1 = memw(r29 + #0)\n" /* r1 = fn */
1949 "r0 = memw(r29 + #4)\n" /* r0 = arg */
1950 "callr r1\n" /* fn(arg) */
1951 "r6 = #%7\n" /* __NR_exit */
1952 "trap0(#1)\n"
1953 "1:\n"
1954 : "=r"(r0)
1955 : "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r6), "i"(__NR_exit)
1956 : "memory", "p0", "r1", "lr");
1957 return (uptr)r0;
1958}
1959# endif
1960# endif // SANITIZER_LINUX
1961
1962# if SANITIZER_LINUX
1963int internal_uname(struct utsname *buf) {
1964 return internal_syscall(SYSCALL(uname), arg1: buf);
1965}
1966# endif
1967
1968static HandleSignalMode GetHandleSignalModeImpl(int signum) {
1969 switch (signum) {
1970 case SIGABRT:
1971 return common_flags()->handle_abort;
1972 case SIGILL:
1973 return common_flags()->handle_sigill;
1974 case SIGTRAP:
1975 return common_flags()->handle_sigtrap;
1976 case SIGFPE:
1977 return common_flags()->handle_sigfpe;
1978 case SIGSEGV:
1979 return common_flags()->handle_segv;
1980 case SIGBUS:
1981 return common_flags()->handle_sigbus;
1982 }
1983 return kHandleSignalNo;
1984}
1985
1986HandleSignalMode GetHandleSignalMode(int signum) {
1987 HandleSignalMode result = GetHandleSignalModeImpl(signum);
1988 if (result == kHandleSignalYes && !common_flags()->allow_user_segv_handler)
1989 return kHandleSignalExclusive;
1990 return result;
1991}
1992
1993# if !SANITIZER_GO
1994void *internal_start_thread(void *(*func)(void *arg), void *arg) {
1995 if (&internal_pthread_create == 0)
1996 return nullptr;
1997 // Start the thread with signals blocked, otherwise it can steal user signals.
1998 ScopedBlockSignals block(nullptr);
1999 void *th;
2000 internal_pthread_create(th: &th, attr: nullptr, callback: func, param: arg);
2001 return th;
2002}
2003
2004void internal_join_thread(void *th) {
2005 if (&internal_pthread_join)
2006 internal_pthread_join(th, ret: nullptr);
2007}
2008# else
2009void *internal_start_thread(void *(*func)(void *), void *arg) { return 0; }
2010
2011void internal_join_thread(void *th) {}
2012# endif
2013
2014# if SANITIZER_LINUX && defined(__aarch64__)
2015// Android headers in the older NDK releases miss this definition.
2016struct __sanitizer_esr_context {
2017 struct _aarch64_ctx head;
2018 uint64_t esr;
2019};
2020
2021static bool Aarch64GetESR(ucontext_t *ucontext, u64 *esr) {
2022 static const u32 kEsrMagic = 0x45535201;
2023 u8 *aux = reinterpret_cast<u8 *>(ucontext->uc_mcontext.__reserved);
2024 while (true) {
2025 _aarch64_ctx *ctx = (_aarch64_ctx *)aux;
2026 if (ctx->size == 0)
2027 break;
2028 if (ctx->magic == kEsrMagic) {
2029 *esr = ((__sanitizer_esr_context *)ctx)->esr;
2030 return true;
2031 }
2032 aux += ctx->size;
2033 }
2034 return false;
2035}
2036# elif SANITIZER_FREEBSD && defined(__aarch64__)
2037// FreeBSD doesn't provide ESR in the ucontext.
2038static bool Aarch64GetESR(ucontext_t *ucontext, u64 *esr) { return false; }
2039# endif
2040
2041using Context = ucontext_t;
2042
2043SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
2044 Context *ucontext = (Context *)context;
2045# if defined(__x86_64__) || defined(__i386__)
2046# if !SANITIZER_HAIKU
2047 static const uptr PF_WRITE = 1U << 1;
2048# endif
2049# if SANITIZER_FREEBSD
2050 uptr err = ucontext->uc_mcontext.mc_err;
2051# elif SANITIZER_NETBSD
2052 uptr err = ucontext->uc_mcontext.__gregs[_REG_ERR];
2053# elif SANITIZER_HAIKU
2054 uptr err = 0; // FIXME: ucontext->uc_mcontext.r13;
2055 // The err register was added on the main branch and not
2056 // available with the current release. To be reverted later.
2057 // https://github.com/haiku/haiku/commit/11adda21aa4e6b24f71a496868a44d7607bc3764
2058# elif SANITIZER_SOLARIS && defined(__i386__)
2059 const int Err = 13;
2060 uptr err = ucontext->uc_mcontext.gregs[Err];
2061# else
2062 uptr err = ucontext->uc_mcontext.gregs[REG_ERR];
2063# endif // SANITIZER_FREEBSD
2064 return err & PF_WRITE ? Write : Read;
2065# elif defined(__mips__)
2066 uint32_t *exception_source;
2067 uint32_t faulty_instruction;
2068 uint32_t op_code;
2069
2070 exception_source = (uint32_t *)ucontext->uc_mcontext.pc;
2071 faulty_instruction = (uint32_t)(*exception_source);
2072
2073 op_code = (faulty_instruction >> 26) & 0x3f;
2074
2075 // FIXME: Add support for FPU, microMIPS, DSP, MSA memory instructions.
2076 switch (op_code) {
2077 case 0x28: // sb
2078 case 0x29: // sh
2079 case 0x2b: // sw
2080 case 0x3f: // sd
2081# if __mips_isa_rev < 6
2082 case 0x2c: // sdl
2083 case 0x2d: // sdr
2084 case 0x2a: // swl
2085 case 0x2e: // swr
2086# endif
2087 return SignalContext::Write;
2088
2089 case 0x20: // lb
2090 case 0x24: // lbu
2091 case 0x21: // lh
2092 case 0x25: // lhu
2093 case 0x23: // lw
2094 case 0x27: // lwu
2095 case 0x37: // ld
2096# if __mips_isa_rev < 6
2097 case 0x1a: // ldl
2098 case 0x1b: // ldr
2099 case 0x22: // lwl
2100 case 0x26: // lwr
2101# endif
2102 return SignalContext::Read;
2103# if __mips_isa_rev == 6
2104 case 0x3b: // pcrel
2105 op_code = (faulty_instruction >> 19) & 0x3;
2106 switch (op_code) {
2107 case 0x1: // lwpc
2108 case 0x2: // lwupc
2109 return SignalContext::Read;
2110 }
2111# endif
2112 }
2113 return SignalContext::Unknown;
2114# elif defined(__arm__)
2115 static const uptr FSR_WRITE = 1U << 11;
2116 uptr fsr = ucontext->uc_mcontext.error_code;
2117 return fsr & FSR_WRITE ? Write : Read;
2118# elif defined(__aarch64__)
2119 static const u64 ESR_ELx_WNR = 1U << 6;
2120 u64 esr;
2121 if (!Aarch64GetESR(ucontext, &esr))
2122 return Unknown;
2123 return esr & ESR_ELx_WNR ? Write : Read;
2124# elif defined(__loongarch__)
2125 // In the musl environment, the Linux kernel uapi sigcontext.h is not
2126 // included in signal.h. To avoid missing the SC_ADDRERR_{RD,WR} macros,
2127 // copy them here. The LoongArch Linux kernel uapi is already stable,
2128 // so there's no need to worry about the value changing.
2129# ifndef SC_ADDRERR_RD
2130 // Address error was due to memory load
2131# define SC_ADDRERR_RD (1 << 30)
2132# endif
2133# ifndef SC_ADDRERR_WR
2134 // Address error was due to memory store
2135# define SC_ADDRERR_WR (1 << 31)
2136# endif
2137 u32 flags = ucontext->uc_mcontext.__flags;
2138 if (flags & SC_ADDRERR_RD)
2139 return SignalContext::Read;
2140 if (flags & SC_ADDRERR_WR)
2141 return SignalContext::Write;
2142 return SignalContext::Unknown;
2143# elif defined(__sparc__)
2144 // Decode the instruction to determine the access type.
2145 // From OpenSolaris $SRC/uts/sun4/os/trap.c (get_accesstype).
2146# if SANITIZER_SOLARIS
2147 uptr pc = ucontext->uc_mcontext.gregs[REG_PC];
2148# else
2149 // Historical BSDism here.
2150 struct sigcontext *scontext = (struct sigcontext *)context;
2151# if defined(__arch64__)
2152 uptr pc = scontext->sigc_regs.tpc;
2153# else
2154 uptr pc = scontext->si_regs.pc;
2155# endif
2156# endif
2157 u32 instr = *(u32 *)pc;
2158 return (instr >> 21) & 1 ? Write : Read;
2159# elif defined(__riscv)
2160# if SANITIZER_FREEBSD
2161 unsigned long pc = ucontext->uc_mcontext.mc_gpregs.gp_sepc;
2162# else
2163 unsigned long pc = ucontext->uc_mcontext.__gregs[REG_PC];
2164# endif
2165 unsigned faulty_instruction = *(uint16_t *)pc;
2166
2167# if defined(__riscv_compressed)
2168 if ((faulty_instruction & 0x3) != 0x3) { // it's a compressed instruction
2169 // set op_bits to the instruction bits [1, 0, 15, 14, 13]
2170 unsigned op_bits =
2171 ((faulty_instruction & 0x3) << 3) | (faulty_instruction >> 13);
2172 unsigned rd = faulty_instruction & 0xF80; // bits 7-11, inclusive
2173 switch (op_bits) {
2174 case 0b10'010: // c.lwsp (rd != x0)
2175# if __riscv_xlen == 64
2176 case 0b10'011: // c.ldsp (rd != x0)
2177# endif
2178 return rd ? SignalContext::Read : SignalContext::Unknown;
2179 case 0b00'010: // c.lw
2180# if __riscv_flen >= 32 && __riscv_xlen == 32
2181 case 0b10'011: // c.flwsp
2182# endif
2183# if __riscv_flen >= 32 || __riscv_xlen == 64
2184 case 0b00'011: // c.flw / c.ld
2185# endif
2186# if __riscv_flen == 64
2187 case 0b00'001: // c.fld
2188 case 0b10'001: // c.fldsp
2189# endif
2190 return SignalContext::Read;
2191 case 0b00'110: // c.sw
2192 case 0b10'110: // c.swsp
2193# if __riscv_flen >= 32 || __riscv_xlen == 64
2194 case 0b00'111: // c.fsw / c.sd
2195 case 0b10'111: // c.fswsp / c.sdsp
2196# endif
2197# if __riscv_flen == 64
2198 case 0b00'101: // c.fsd
2199 case 0b10'101: // c.fsdsp
2200# endif
2201 return SignalContext::Write;
2202 default:
2203 return SignalContext::Unknown;
2204 }
2205 }
2206# endif
2207
2208 unsigned opcode = faulty_instruction & 0x7f; // lower 7 bits
2209 unsigned funct3 = (faulty_instruction >> 12) & 0x7; // bits 12-14, inclusive
2210 switch (opcode) {
2211 case 0b0000011: // loads
2212 switch (funct3) {
2213 case 0b000: // lb
2214 case 0b001: // lh
2215 case 0b010: // lw
2216# if __riscv_xlen == 64
2217 case 0b011: // ld
2218# endif
2219 case 0b100: // lbu
2220 case 0b101: // lhu
2221 return SignalContext::Read;
2222 default:
2223 return SignalContext::Unknown;
2224 }
2225 case 0b0100011: // stores
2226 switch (funct3) {
2227 case 0b000: // sb
2228 case 0b001: // sh
2229 case 0b010: // sw
2230# if __riscv_xlen == 64
2231 case 0b011: // sd
2232# endif
2233 return SignalContext::Write;
2234 default:
2235 return SignalContext::Unknown;
2236 }
2237# if __riscv_flen >= 32
2238 case 0b0000111: // floating-point loads
2239 switch (funct3) {
2240 case 0b010: // flw
2241# if __riscv_flen == 64
2242 case 0b011: // fld
2243# endif
2244 return SignalContext::Read;
2245 default:
2246 return SignalContext::Unknown;
2247 }
2248 case 0b0100111: // floating-point stores
2249 switch (funct3) {
2250 case 0b010: // fsw
2251# if __riscv_flen == 64
2252 case 0b011: // fsd
2253# endif
2254 return SignalContext::Write;
2255 default:
2256 return SignalContext::Unknown;
2257 }
2258# endif
2259 default:
2260 return SignalContext::Unknown;
2261 }
2262# else
2263 (void)ucontext;
2264 return Unknown; // FIXME: Implement.
2265# endif
2266}
2267
2268bool SignalContext::IsTrueFaultingAddress() const {
2269 auto si = static_cast<const siginfo_t *>(siginfo);
2270 // SIGSEGV signals without a true fault address have si_code set to 128.
2271 return si->si_signo == SIGSEGV && si->si_code != 128;
2272}
2273
2274UNUSED
2275static const char *RegNumToRegName(int reg) {
2276 switch (reg) {
2277# if SANITIZER_LINUX && SANITIZER_GLIBC || SANITIZER_NETBSD
2278# if defined(__x86_64__)
2279# if SANITIZER_NETBSD
2280# define REG_RAX _REG_RAX
2281# define REG_RBX _REG_RBX
2282# define REG_RCX _REG_RCX
2283# define REG_RDX _REG_RDX
2284# define REG_RDI _REG_RDI
2285# define REG_RSI _REG_RSI
2286# define REG_RBP _REG_RBP
2287# define REG_RSP _REG_RSP
2288# define REG_R8 _REG_R8
2289# define REG_R9 _REG_R9
2290# define REG_R10 _REG_R10
2291# define REG_R11 _REG_R11
2292# define REG_R12 _REG_R12
2293# define REG_R13 _REG_R13
2294# define REG_R14 _REG_R14
2295# define REG_R15 _REG_R15
2296# endif
2297 case REG_RAX:
2298 return "rax";
2299 case REG_RBX:
2300 return "rbx";
2301 case REG_RCX:
2302 return "rcx";
2303 case REG_RDX:
2304 return "rdx";
2305 case REG_RDI:
2306 return "rdi";
2307 case REG_RSI:
2308 return "rsi";
2309 case REG_RBP:
2310 return "rbp";
2311 case REG_RSP:
2312 return "rsp";
2313 case REG_R8:
2314 return "r8";
2315 case REG_R9:
2316 return "r9";
2317 case REG_R10:
2318 return "r10";
2319 case REG_R11:
2320 return "r11";
2321 case REG_R12:
2322 return "r12";
2323 case REG_R13:
2324 return "r13";
2325 case REG_R14:
2326 return "r14";
2327 case REG_R15:
2328 return "r15";
2329# elif defined(__i386__)
2330# if SANITIZER_NETBSD
2331# define REG_EAX _REG_EAX
2332# define REG_EBX _REG_EBX
2333# define REG_ECX _REG_ECX
2334# define REG_EDX _REG_EDX
2335# define REG_EDI _REG_EDI
2336# define REG_ESI _REG_ESI
2337# define REG_EBP _REG_EBP
2338# define REG_ESP _REG_ESP
2339# endif
2340 case REG_EAX:
2341 return "eax";
2342 case REG_EBX:
2343 return "ebx";
2344 case REG_ECX:
2345 return "ecx";
2346 case REG_EDX:
2347 return "edx";
2348 case REG_EDI:
2349 return "edi";
2350 case REG_ESI:
2351 return "esi";
2352 case REG_EBP:
2353 return "ebp";
2354 case REG_ESP:
2355 return "esp";
2356# elif defined(__arm__)
2357# ifdef MAKE_CASE
2358# undef MAKE_CASE
2359# endif
2360# define REG_STR(reg) #reg
2361# define MAKE_CASE(N) \
2362 case REG_R##N: \
2363 return REG_STR(r##N)
2364 MAKE_CASE(0);
2365 MAKE_CASE(1);
2366 MAKE_CASE(2);
2367 MAKE_CASE(3);
2368 MAKE_CASE(4);
2369 MAKE_CASE(5);
2370 MAKE_CASE(6);
2371 MAKE_CASE(7);
2372 MAKE_CASE(8);
2373 MAKE_CASE(9);
2374 MAKE_CASE(10);
2375 MAKE_CASE(11);
2376 MAKE_CASE(12);
2377 case REG_R13:
2378 return "sp";
2379 case REG_R14:
2380 return "lr";
2381 case REG_R15:
2382 return "pc";
2383# elif defined(__aarch64__)
2384# define REG_STR(reg) #reg
2385# define MAKE_CASE(N) \
2386 case N: \
2387 return REG_STR(x##N)
2388 MAKE_CASE(0);
2389 MAKE_CASE(1);
2390 MAKE_CASE(2);
2391 MAKE_CASE(3);
2392 MAKE_CASE(4);
2393 MAKE_CASE(5);
2394 MAKE_CASE(6);
2395 MAKE_CASE(7);
2396 MAKE_CASE(8);
2397 MAKE_CASE(9);
2398 MAKE_CASE(10);
2399 MAKE_CASE(11);
2400 MAKE_CASE(12);
2401 MAKE_CASE(13);
2402 MAKE_CASE(14);
2403 MAKE_CASE(15);
2404 MAKE_CASE(16);
2405 MAKE_CASE(17);
2406 MAKE_CASE(18);
2407 MAKE_CASE(19);
2408 MAKE_CASE(20);
2409 MAKE_CASE(21);
2410 MAKE_CASE(22);
2411 MAKE_CASE(23);
2412 MAKE_CASE(24);
2413 MAKE_CASE(25);
2414 MAKE_CASE(26);
2415 MAKE_CASE(27);
2416 MAKE_CASE(28);
2417 case 29:
2418 return "fp";
2419 case 30:
2420 return "lr";
2421 case 31:
2422 return "sp";
2423# endif
2424# endif // SANITIZER_LINUX && SANITIZER_GLIBC
2425 default:
2426 return NULL;
2427 }
2428 return NULL;
2429}
2430
2431# if ((SANITIZER_LINUX && SANITIZER_GLIBC) || SANITIZER_NETBSD) && \
2432 (defined(__arm__) || defined(__aarch64__))
2433static uptr GetArmRegister(ucontext_t *ctx, int RegNum) {
2434 switch (RegNum) {
2435# if defined(__arm__) && !SANITIZER_NETBSD
2436# ifdef MAKE_CASE
2437# undef MAKE_CASE
2438# endif
2439# define MAKE_CASE(N) \
2440 case REG_R##N: \
2441 return ctx->uc_mcontext.arm_r##N
2442 MAKE_CASE(0);
2443 MAKE_CASE(1);
2444 MAKE_CASE(2);
2445 MAKE_CASE(3);
2446 MAKE_CASE(4);
2447 MAKE_CASE(5);
2448 MAKE_CASE(6);
2449 MAKE_CASE(7);
2450 MAKE_CASE(8);
2451 MAKE_CASE(9);
2452 MAKE_CASE(10);
2453 case REG_R11:
2454 return ctx->uc_mcontext.arm_fp;
2455 case REG_R12:
2456 return ctx->uc_mcontext.arm_ip;
2457 case REG_R13:
2458 return ctx->uc_mcontext.arm_sp;
2459 case REG_R14:
2460 return ctx->uc_mcontext.arm_lr;
2461 case REG_R15:
2462 return ctx->uc_mcontext.arm_pc;
2463# elif defined(__aarch64__)
2464# if SANITIZER_LINUX
2465 case 0 ... 30:
2466 return ctx->uc_mcontext.regs[RegNum];
2467 case 31:
2468 return ctx->uc_mcontext.sp;
2469# elif SANITIZER_NETBSD
2470 case 0 ... 31:
2471 return ctx->uc_mcontext.__gregs[RegNum];
2472# endif
2473# endif
2474 default:
2475 return 0;
2476 }
2477 return 0;
2478}
2479# endif // SANITIZER_LINUX && SANITIZER_GLIBC && (defined(__arm__) ||
2480 // defined(__aarch64__))
2481
2482UNUSED
2483static void DumpSingleReg(ucontext_t *ctx, int RegNum) {
2484 const char *RegName = RegNumToRegName(reg: RegNum);
2485# if SANITIZER_LINUX && SANITIZER_GLIBC || SANITIZER_NETBSD
2486# if defined(__x86_64__)
2487 Printf(format: "%s%s = 0x%016llx ", internal_strlen(s: RegName) == 2 ? " " : "",
2488 RegName,
2489# if SANITIZER_LINUX
2490 ctx->uc_mcontext.gregs[RegNum]
2491# elif SANITIZER_NETBSD
2492 ctx->uc_mcontext.__gregs[RegNum]
2493# endif
2494 );
2495# elif defined(__i386__)
2496 Printf("%s = 0x%08x ", RegName,
2497# if SANITIZER_LINUX
2498 ctx->uc_mcontext.gregs[RegNum]
2499# elif SANITIZER_NETBSD
2500 ctx->uc_mcontext.__gregs[RegNum]
2501# endif
2502 );
2503# elif defined(__arm__)
2504 Printf("%s%s = 0x%08zx ", internal_strlen(RegName) == 2 ? " " : "", RegName,
2505 GetArmRegister(ctx, RegNum));
2506# elif defined(__aarch64__)
2507 Printf("%s%s = 0x%016zx ", internal_strlen(RegName) == 2 ? " " : "", RegName,
2508 GetArmRegister(ctx, RegNum));
2509# else
2510 (void)RegName;
2511# endif
2512# else
2513 (void)RegName;
2514# endif
2515}
2516
2517void SignalContext::DumpAllRegisters(void *context) {
2518 ucontext_t *ucontext = (ucontext_t *)context;
2519# if SANITIZER_LINUX && SANITIZER_GLIBC || SANITIZER_NETBSD
2520# if defined(__x86_64__)
2521 Report(format: "Register values:\n");
2522 DumpSingleReg(ctx: ucontext, REG_RAX);
2523 DumpSingleReg(ctx: ucontext, REG_RBX);
2524 DumpSingleReg(ctx: ucontext, REG_RCX);
2525 DumpSingleReg(ctx: ucontext, REG_RDX);
2526 Printf(format: "\n");
2527 DumpSingleReg(ctx: ucontext, REG_RDI);
2528 DumpSingleReg(ctx: ucontext, REG_RSI);
2529 DumpSingleReg(ctx: ucontext, REG_RBP);
2530 DumpSingleReg(ctx: ucontext, REG_RSP);
2531 Printf(format: "\n");
2532 DumpSingleReg(ctx: ucontext, REG_R8);
2533 DumpSingleReg(ctx: ucontext, REG_R9);
2534 DumpSingleReg(ctx: ucontext, REG_R10);
2535 DumpSingleReg(ctx: ucontext, REG_R11);
2536 Printf(format: "\n");
2537 DumpSingleReg(ctx: ucontext, REG_R12);
2538 DumpSingleReg(ctx: ucontext, REG_R13);
2539 DumpSingleReg(ctx: ucontext, REG_R14);
2540 DumpSingleReg(ctx: ucontext, REG_R15);
2541 Printf(format: "\n");
2542# elif defined(__i386__)
2543 // Duplication of this report print is caused by partial support
2544 // of register values dumping. In case of unsupported yet architecture let's
2545 // avoid printing 'Register values:' without actual values in the following
2546 // output.
2547 Report("Register values:\n");
2548 DumpSingleReg(ucontext, REG_EAX);
2549 DumpSingleReg(ucontext, REG_EBX);
2550 DumpSingleReg(ucontext, REG_ECX);
2551 DumpSingleReg(ucontext, REG_EDX);
2552 Printf("\n");
2553 DumpSingleReg(ucontext, REG_EDI);
2554 DumpSingleReg(ucontext, REG_ESI);
2555 DumpSingleReg(ucontext, REG_EBP);
2556 DumpSingleReg(ucontext, REG_ESP);
2557 Printf("\n");
2558# elif defined(__arm__) && !SANITIZER_NETBSD
2559 Report("Register values:\n");
2560 DumpSingleReg(ucontext, REG_R0);
2561 DumpSingleReg(ucontext, REG_R1);
2562 DumpSingleReg(ucontext, REG_R2);
2563 DumpSingleReg(ucontext, REG_R3);
2564 Printf("\n");
2565 DumpSingleReg(ucontext, REG_R4);
2566 DumpSingleReg(ucontext, REG_R5);
2567 DumpSingleReg(ucontext, REG_R6);
2568 DumpSingleReg(ucontext, REG_R7);
2569 Printf("\n");
2570 DumpSingleReg(ucontext, REG_R8);
2571 DumpSingleReg(ucontext, REG_R9);
2572 DumpSingleReg(ucontext, REG_R10);
2573 DumpSingleReg(ucontext, REG_R11);
2574 Printf("\n");
2575 DumpSingleReg(ucontext, REG_R12);
2576 DumpSingleReg(ucontext, REG_R13);
2577 DumpSingleReg(ucontext, REG_R14);
2578 DumpSingleReg(ucontext, REG_R15);
2579 Printf("\n");
2580# elif defined(__aarch64__)
2581 Report("Register values:\n");
2582 for (int i = 0; i <= 31; ++i) {
2583 DumpSingleReg(ucontext, i);
2584 if (i % 4 == 3)
2585 Printf("\n");
2586 }
2587# else
2588 (void)ucontext;
2589# endif
2590# elif SANITIZER_FREEBSD
2591# if defined(__x86_64__)
2592 Report("Register values:\n");
2593 Printf("rax = 0x%016lx ", ucontext->uc_mcontext.mc_rax);
2594 Printf("rbx = 0x%016lx ", ucontext->uc_mcontext.mc_rbx);
2595 Printf("rcx = 0x%016lx ", ucontext->uc_mcontext.mc_rcx);
2596 Printf("rdx = 0x%016lx ", ucontext->uc_mcontext.mc_rdx);
2597 Printf("\n");
2598 Printf("rdi = 0x%016lx ", ucontext->uc_mcontext.mc_rdi);
2599 Printf("rsi = 0x%016lx ", ucontext->uc_mcontext.mc_rsi);
2600 Printf("rbp = 0x%016lx ", ucontext->uc_mcontext.mc_rbp);
2601 Printf("rsp = 0x%016lx ", ucontext->uc_mcontext.mc_rsp);
2602 Printf("\n");
2603 Printf(" r8 = 0x%016lx ", ucontext->uc_mcontext.mc_r8);
2604 Printf(" r9 = 0x%016lx ", ucontext->uc_mcontext.mc_r9);
2605 Printf("r10 = 0x%016lx ", ucontext->uc_mcontext.mc_r10);
2606 Printf("r11 = 0x%016lx ", ucontext->uc_mcontext.mc_r11);
2607 Printf("\n");
2608 Printf("r12 = 0x%016lx ", ucontext->uc_mcontext.mc_r12);
2609 Printf("r13 = 0x%016lx ", ucontext->uc_mcontext.mc_r13);
2610 Printf("r14 = 0x%016lx ", ucontext->uc_mcontext.mc_r14);
2611 Printf("r15 = 0x%016lx ", ucontext->uc_mcontext.mc_r15);
2612 Printf("\n");
2613# elif defined(__i386__)
2614 Report("Register values:\n");
2615 Printf("eax = 0x%08x ", ucontext->uc_mcontext.mc_eax);
2616 Printf("ebx = 0x%08x ", ucontext->uc_mcontext.mc_ebx);
2617 Printf("ecx = 0x%08x ", ucontext->uc_mcontext.mc_ecx);
2618 Printf("edx = 0x%08x ", ucontext->uc_mcontext.mc_edx);
2619 Printf("\n");
2620 Printf("edi = 0x%08x ", ucontext->uc_mcontext.mc_edi);
2621 Printf("esi = 0x%08x ", ucontext->uc_mcontext.mc_esi);
2622 Printf("ebp = 0x%08x ", ucontext->uc_mcontext.mc_ebp);
2623 Printf("esp = 0x%08x ", ucontext->uc_mcontext.mc_esp);
2624 Printf("\n");
2625# else
2626 (void)ucontext;
2627# endif
2628# else
2629 (void)ucontext;
2630# endif
2631 // FIXME: Implement this for other OSes and architectures.
2632}
2633
2634static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
2635# if SANITIZER_NETBSD
2636 // This covers all NetBSD architectures
2637 ucontext_t *ucontext = (ucontext_t *)context;
2638 *pc = _UC_MACHINE_PC(ucontext);
2639 *bp = _UC_MACHINE_FP(ucontext);
2640 *sp = _UC_MACHINE_SP(ucontext);
2641# elif defined(__arm__)
2642 ucontext_t *ucontext = (ucontext_t *)context;
2643 *pc = ucontext->uc_mcontext.arm_pc;
2644 *bp = ucontext->uc_mcontext.arm_fp;
2645 *sp = ucontext->uc_mcontext.arm_sp;
2646# elif defined(__aarch64__)
2647# if SANITIZER_FREEBSD
2648 ucontext_t *ucontext = (ucontext_t *)context;
2649 *pc = ucontext->uc_mcontext.mc_gpregs.gp_elr;
2650 *bp = ucontext->uc_mcontext.mc_gpregs.gp_x[29];
2651 *sp = ucontext->uc_mcontext.mc_gpregs.gp_sp;
2652# else
2653 ucontext_t *ucontext = (ucontext_t *)context;
2654 *pc = ucontext->uc_mcontext.pc;
2655 *bp = ucontext->uc_mcontext.regs[29];
2656 *sp = ucontext->uc_mcontext.sp;
2657# endif
2658# elif defined(__hppa__)
2659 ucontext_t *ucontext = (ucontext_t *)context;
2660 *pc = ucontext->uc_mcontext.sc_iaoq[0];
2661 /* GCC uses %r3 whenever a frame pointer is needed. */
2662 *bp = ucontext->uc_mcontext.sc_gr[3];
2663 *sp = ucontext->uc_mcontext.sc_gr[30];
2664# elif defined(__x86_64__)
2665# if SANITIZER_FREEBSD
2666 ucontext_t *ucontext = (ucontext_t *)context;
2667 *pc = ucontext->uc_mcontext.mc_rip;
2668 *bp = ucontext->uc_mcontext.mc_rbp;
2669 *sp = ucontext->uc_mcontext.mc_rsp;
2670# elif SANITIZER_HAIKU
2671 ucontext_t *ucontext = (ucontext_t *)context;
2672 *pc = ucontext->uc_mcontext.rip;
2673 *bp = ucontext->uc_mcontext.rbp;
2674 *sp = ucontext->uc_mcontext.rsp;
2675# else
2676 ucontext_t *ucontext = (ucontext_t *)context;
2677 *pc = ucontext->uc_mcontext.gregs[REG_RIP];
2678 *bp = ucontext->uc_mcontext.gregs[REG_RBP];
2679 *sp = ucontext->uc_mcontext.gregs[REG_RSP];
2680# endif
2681# elif defined(__i386__)
2682# if SANITIZER_FREEBSD
2683 ucontext_t *ucontext = (ucontext_t *)context;
2684 *pc = ucontext->uc_mcontext.mc_eip;
2685 *bp = ucontext->uc_mcontext.mc_ebp;
2686 *sp = ucontext->uc_mcontext.mc_esp;
2687# elif SANITIZER_HAIKU
2688 ucontext_t *ucontext = (ucontext_t *)context;
2689 *pc = ucontext->uc_mcontext.eip;
2690 *bp = ucontext->uc_mcontext.ebp;
2691 *sp = ucontext->uc_mcontext.esp;
2692# else
2693 ucontext_t *ucontext = (ucontext_t *)context;
2694# if SANITIZER_SOLARIS
2695 /* Use the numeric values: the symbolic ones are undefined by llvm
2696 include/llvm/Support/Solaris.h. */
2697# ifndef REG_EIP
2698# define REG_EIP 14 // REG_PC
2699# endif
2700# ifndef REG_EBP
2701# define REG_EBP 6 // REG_FP
2702# endif
2703# ifndef REG_UESP
2704# define REG_UESP 17 // REG_SP
2705# endif
2706# endif
2707 *pc = ucontext->uc_mcontext.gregs[REG_EIP];
2708 *bp = ucontext->uc_mcontext.gregs[REG_EBP];
2709 *sp = ucontext->uc_mcontext.gregs[REG_UESP];
2710# endif
2711# elif defined(__powerpc__) || defined(__powerpc64__)
2712# if SANITIZER_FREEBSD
2713 ucontext_t *ucontext = (ucontext_t *)context;
2714 *pc = ucontext->uc_mcontext.mc_srr0;
2715 *sp = ucontext->uc_mcontext.mc_frame[1];
2716 *bp = ucontext->uc_mcontext.mc_frame[31];
2717# else
2718 ucontext_t *ucontext = (ucontext_t *)context;
2719 *pc = ucontext->uc_mcontext.regs->nip;
2720 *sp = ucontext->uc_mcontext.regs->gpr[PT_R1];
2721 // The powerpc{,64}-linux ABIs do not specify r31 as the frame
2722 // pointer, but GCC always uses r31 when we need a frame pointer.
2723 *bp = ucontext->uc_mcontext.regs->gpr[PT_R31];
2724# endif
2725# elif defined(__sparc__)
2726# if defined(__arch64__) || defined(__sparcv9)
2727# define STACK_BIAS 2047
2728# else
2729# define STACK_BIAS 0
2730# endif
2731# if SANITIZER_SOLARIS
2732 ucontext_t *ucontext = (ucontext_t *)context;
2733 *pc = ucontext->uc_mcontext.gregs[REG_PC];
2734 *sp = ucontext->uc_mcontext.gregs[REG_SP] + STACK_BIAS;
2735 // Avoid SEGV when dereferencing sp on stack overflow with non-faulting load.
2736 // This requires a SPARC V9 CPU. Cannot use #ASI_PNF here: only supported
2737 // since clang-19.
2738# if defined(__sparcv9)
2739 asm("ldxa [%[fp]] 0x82, %[bp]"
2740# else
2741 asm("lduwa [%[fp]] 0x82, %[bp]"
2742# endif
2743 : [bp] "=r"(*bp)
2744 : [fp] "r"(&((struct frame *)*sp)->fr_savfp));
2745 if (*bp)
2746 *bp += STACK_BIAS;
2747# else
2748 // Historical BSDism here.
2749 struct sigcontext *scontext = (struct sigcontext *)context;
2750# if defined(__arch64__)
2751 *pc = scontext->sigc_regs.tpc;
2752 *sp = scontext->sigc_regs.u_regs[14] + STACK_BIAS;
2753# else
2754 *pc = scontext->si_regs.pc;
2755 *sp = scontext->si_regs.u_regs[14];
2756# endif
2757 *bp = (uptr)((uhwptr *)*sp)[14] + STACK_BIAS;
2758# endif
2759# elif defined(__mips__)
2760 ucontext_t *ucontext = (ucontext_t *)context;
2761 *pc = ucontext->uc_mcontext.pc;
2762 *bp = ucontext->uc_mcontext.gregs[30];
2763 *sp = ucontext->uc_mcontext.gregs[29];
2764# elif defined(__s390__)
2765 ucontext_t *ucontext = (ucontext_t *)context;
2766# if defined(__s390x__)
2767 *pc = ucontext->uc_mcontext.psw.addr;
2768# else
2769 *pc = ucontext->uc_mcontext.psw.addr & 0x7fffffff;
2770# endif
2771 *bp = ucontext->uc_mcontext.gregs[11];
2772 *sp = ucontext->uc_mcontext.gregs[15];
2773# elif defined(__riscv)
2774 ucontext_t *ucontext = (ucontext_t *)context;
2775# if SANITIZER_FREEBSD
2776 *pc = ucontext->uc_mcontext.mc_gpregs.gp_sepc;
2777 *bp = ucontext->uc_mcontext.mc_gpregs.gp_s[0];
2778 *sp = ucontext->uc_mcontext.mc_gpregs.gp_sp;
2779# else
2780 *pc = ucontext->uc_mcontext.__gregs[REG_PC];
2781 *bp = ucontext->uc_mcontext.__gregs[REG_S0];
2782 *sp = ucontext->uc_mcontext.__gregs[REG_SP];
2783# endif
2784# elif defined(__hexagon__)
2785 ucontext_t *ucontext = (ucontext_t *)context;
2786 *pc = ucontext->uc_mcontext.pc;
2787 *bp = ucontext->uc_mcontext.r30;
2788 *sp = ucontext->uc_mcontext.r29;
2789# elif defined(__loongarch__)
2790 ucontext_t *ucontext = (ucontext_t *)context;
2791 *pc = ucontext->uc_mcontext.__pc;
2792 *bp = ucontext->uc_mcontext.__gregs[22];
2793 *sp = ucontext->uc_mcontext.__gregs[3];
2794# elif defined(__alpha__)
2795 ucontext_t* ucontext = (ucontext_t*)context;
2796 *pc = ucontext->uc_mcontext.sc_pc;
2797 *bp = ucontext->uc_mcontext.sc_regs[15]; // $fp / $s6
2798 *sp = ucontext->uc_mcontext.sc_regs[30]; // $sp
2799# else
2800# error "Unsupported arch"
2801# endif
2802}
2803
2804void SignalContext::InitPcSpBp() { GetPcSpBp(context, pc: &pc, sp: &sp, bp: &bp); }
2805
2806void InitializePlatformEarly() { InitTlsSize(); }
2807
2808void CheckASLR() {
2809# if SANITIZER_NETBSD
2810 int mib[3];
2811 int paxflags;
2812 uptr len = sizeof(paxflags);
2813
2814 mib[0] = CTL_PROC;
2815 mib[1] = internal_getpid();
2816 mib[2] = PROC_PID_PAXFLAGS;
2817
2818 if (UNLIKELY(internal_sysctl(mib, 3, &paxflags, &len, NULL, 0) == -1)) {
2819 Printf("sysctl failed\n");
2820 Die();
2821 }
2822
2823 if (UNLIKELY(paxflags & CTL_PROC_PAXFLAGS_ASLR)) {
2824 Printf(
2825 "This sanitizer is not compatible with enabled ASLR.\n"
2826 "To disable ASLR, please run \"paxctl +a %s\" and try again.\n",
2827 GetArgv()[0]);
2828 Die();
2829 }
2830# elif SANITIZER_FREEBSD
2831 int aslr_status;
2832 int r = internal_procctl(P_PID, 0, PROC_ASLR_STATUS, &aslr_status);
2833 if (UNLIKELY(r == -1)) {
2834 // We're making things less 'dramatic' here since
2835 // the cmd is not necessarily guaranteed to be here
2836 // just yet regarding FreeBSD release
2837 return;
2838 }
2839 if ((aslr_status & PROC_ASLR_ACTIVE) != 0) {
2840 VReport(1,
2841 "This sanitizer is not compatible with enabled ASLR "
2842 "and binaries compiled with PIE\n"
2843 "ASLR will be disabled and the program re-executed.\n");
2844 int aslr_ctl = PROC_ASLR_FORCE_DISABLE;
2845 CHECK_NE(internal_procctl(P_PID, 0, PROC_ASLR_CTL, &aslr_ctl), -1);
2846 ReExec();
2847 }
2848# elif SANITIZER_PPC64V2
2849 // Disable ASLR for Linux PPC64LE.
2850 int old_personality = personality(0xffffffff);
2851 if (old_personality != -1 && (old_personality & ADDR_NO_RANDOMIZE) == 0) {
2852 VReport(1,
2853 "WARNING: Program is being run with address space layout "
2854 "randomization (ASLR) enabled which prevents the thread and "
2855 "memory sanitizers from working on powerpc64le.\n"
2856 "ASLR will be disabled and the program re-executed.\n");
2857 CHECK_NE(personality(old_personality | ADDR_NO_RANDOMIZE), -1);
2858 ReExec();
2859 }
2860# else
2861 // Do nothing
2862# endif
2863}
2864
2865void CheckMPROTECT() {
2866# if SANITIZER_NETBSD
2867 int mib[3];
2868 int paxflags;
2869 uptr len = sizeof(paxflags);
2870
2871 mib[0] = CTL_PROC;
2872 mib[1] = internal_getpid();
2873 mib[2] = PROC_PID_PAXFLAGS;
2874
2875 if (UNLIKELY(internal_sysctl(mib, 3, &paxflags, &len, NULL, 0) == -1)) {
2876 Printf("sysctl failed\n");
2877 Die();
2878 }
2879
2880 if (UNLIKELY(paxflags & CTL_PROC_PAXFLAGS_MPROTECT)) {
2881 Printf("This sanitizer is not compatible with enabled MPROTECT\n");
2882 Die();
2883 }
2884# else
2885 // Do nothing
2886# endif
2887}
2888
2889void OnDlOpen(const char* filename, int flag) {
2890# ifdef RTLD_DEEPBIND
2891 if (flag & RTLD_DEEPBIND) {
2892 Report(
2893 format: "You are trying to dlopen a %s shared library with RTLD_DEEPBIND flag"
2894 " which is incompatible with sanitizer runtime "
2895 "(see https://github.com/google/sanitizers/issues/611 for details"
2896 "). If you want to run %s library under sanitizers please remove "
2897 "RTLD_DEEPBIND from dlopen flags.\n",
2898 filename, filename);
2899 Die();
2900 }
2901# endif
2902}
2903
2904uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
2905 uptr *largest_gap_found,
2906 uptr *max_occupied_addr) {
2907 UNREACHABLE("FindAvailableMemoryRange is not available");
2908 return 0;
2909}
2910
2911bool GetRandom(void *buffer, uptr length, bool blocking) {
2912 if (!buffer || !length || length > 256)
2913 return false;
2914# if SANITIZER_USE_GETENTROPY
2915 uptr rnd = getentropy(buffer, length);
2916 int rverrno = 0;
2917 if (internal_iserror(rnd, &rverrno) && rverrno == EFAULT)
2918 return false;
2919 else if (rnd == 0)
2920 return true;
2921# endif // SANITIZER_USE_GETENTROPY
2922
2923# if SANITIZER_USE_GETRANDOM
2924 static atomic_uint8_t skip_getrandom_syscall;
2925 if (!atomic_load_relaxed(a: &skip_getrandom_syscall)) {
2926 // Up to 256 bytes, getrandom will not be interrupted.
2927 uptr res = internal_syscall(SYSCALL(getrandom), arg1: buffer, arg2: length,
2928 arg3: blocking ? 0 : GRND_NONBLOCK);
2929 int rverrno = 0;
2930 if (internal_iserror(retval: res, rverrno: &rverrno) && rverrno == ENOSYS)
2931 atomic_store_relaxed(a: &skip_getrandom_syscall, v: 1);
2932 else if (res == length)
2933 return true;
2934 }
2935# endif // SANITIZER_USE_GETRANDOM
2936 // Up to 256 bytes, a read off /dev/urandom will not be interrupted.
2937 // blocking is moot here, O_NONBLOCK has no effect when opening /dev/urandom.
2938 uptr fd = internal_open(filename: "/dev/urandom", O_RDONLY);
2939 if (internal_iserror(retval: fd))
2940 return false;
2941 uptr res = internal_read(fd, buf: buffer, count: length);
2942 if (internal_iserror(retval: res))
2943 return false;
2944 internal_close(fd);
2945 return true;
2946}
2947
2948} // namespace __sanitizer
2949
2950#endif
2951