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