Bug Summary

File:projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc
Warning:line 438, column 10
The left operand of '&' is a garbage value

Annotated Source Code

1//===-- sanitizer_linux.cc ------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is shared between AddressSanitizer and ThreadSanitizer
11// run-time libraries and implements linux-specific functions from
12// sanitizer_libc.h.
13//===----------------------------------------------------------------------===//
14
15#include "sanitizer_platform.h"
16
17#if SANITIZER_FREEBSD0 || SANITIZER_LINUX1 || SANITIZER_NETBSD0
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#include "sanitizer_stacktrace.h"
29#include "sanitizer_symbolizer.h"
30
31#if SANITIZER_LINUX1
32#include <asm/param.h>
33#endif
34
35#if SANITIZER_NETBSD0
36#include <lwp.h>
37#endif
38
39// For mips64, syscall(__NR_stat) fills the buffer in the 'struct kernel_stat'
40// format. Struct kernel_stat is defined as 'struct stat' in asm/stat.h. To
41// access stat from asm/stat.h, without conflicting with definition in
42// sys/stat.h, we use this trick.
43#if defined(__mips64)
44#include <asm/unistd.h>
45#include <sys/types.h>
46#define stat kernel_stat
47#include <asm/stat.h>
48#undef stat
49#endif
50
51#include <dlfcn.h>
52#include <errno(*__errno_location ()).h>
53#include <fcntl.h>
54#include <link.h>
55#include <pthread.h>
56#include <sched.h>
57#include <sys/mman.h>
58#include <sys/ptrace.h>
59#include <sys/resource.h>
60#include <sys/stat.h>
61#include <sys/syscall.h>
62#include <sys/time.h>
63#include <sys/types.h>
64#include <ucontext.h>
65#include <unistd.h>
66
67#if SANITIZER_LINUX1
68#include <sys/utsname.h>
69#endif
70
71#if SANITIZER_LINUX1 && !SANITIZER_ANDROID0
72#include <sys/personality.h>
73#endif
74
75#if SANITIZER_FREEBSD0
76#include <sys/exec.h>
77#include <sys/sysctl.h>
78#include <machine/atomic.h>
79extern "C" {
80// <sys/umtx.h> must be included after <errno.h> and <sys/types.h> on
81// FreeBSD 9.2 and 10.0.
82#include <sys/umtx.h>
83}
84extern char **environ; // provided by crt1
85#endif // SANITIZER_FREEBSD
86
87#if SANITIZER_NETBSD0
88#include <limits.h> // For NAME_MAX
89#include <sys/sysctl.h>
90extern char **environ; // provided by crt1
91#include <sys/exec.h>
92extern struct ps_strings *__ps_strings;
93#endif // SANITIZER_NETBSD
94
95#if !SANITIZER_ANDROID0
96#include <sys/signal.h>
97#endif
98
99#if SANITIZER_LINUX1
100// <linux/time.h>
101struct kernel_timeval {
102 long tv_sec;
103 long tv_usec;
104};
105
106// <linux/futex.h> is broken on some linux distributions.
107const int FUTEX_WAIT = 0;
108const int FUTEX_WAKE = 1;
109#endif // SANITIZER_LINUX
110
111// Are we using 32-bit or 64-bit Linux syscalls?
112// x32 (which defines __x86_64__) has SANITIZER_WORDSIZE == 32
113// but it still needs to use 64-bit syscalls.
114#if SANITIZER_LINUX1 && (defined(__x86_64__1) || defined(__powerpc64__) || \
115 SANITIZER_WORDSIZE64 == 64)
116# define SANITIZER_LINUX_USES_64BIT_SYSCALLS1 1
117#else
118# define SANITIZER_LINUX_USES_64BIT_SYSCALLS1 0
119#endif
120
121#if defined(__x86_64__1) || SANITIZER_MIPS640
122extern "C" {
123extern void internal_sigreturn();
124}
125#endif
126
127#if SANITIZER_LINUX1 && defined(__NR_getrandom318)
128# if !defined(GRND_NONBLOCK1)
129# define GRND_NONBLOCK1 1
130# endif
131# define SANITIZER_USE_GETRANDOM1 1
132#else
133# define SANITIZER_USE_GETRANDOM1 0
134#endif // SANITIZER_LINUX && defined(__NR_getrandom)
135
136namespace __sanitizer {
137
138#if SANITIZER_LINUX1 && defined(__x86_64__1)
139#include "sanitizer_syscall_linux_x86_64.inc"
140#elif SANITIZER_LINUX1 && defined(__aarch64__)
141#include "sanitizer_syscall_linux_aarch64.inc"
142#elif SANITIZER_LINUX1 && defined(__arm__)
143#include "sanitizer_syscall_linux_arm.inc"
144#else
145#include "sanitizer_syscall_generic.inc"
146#endif
147
148// --------------- sanitizer_libc.h
149#if !SANITIZER_S3900
150uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
151 OFF_T offset) {
152#if SANITIZER_NETBSD0
153 return internal_syscall_ptrinternal_syscall(SYSCALL(mmap)9, addr, length, prot, flags, fd,
154 (long)0, offset);
155#elif SANITIZER_FREEBSD0 || SANITIZER_LINUX_USES_64BIT_SYSCALLS1
156 return internal_syscall(SYSCALL(mmap)9, (uptr)addr, length, prot, flags, fd,
157 offset);
158#else
159 // mmap2 specifies file offset in 4096-byte units.
160 CHECK(IsAligned(offset, 4096))do { __sanitizer::u64 v1 = (__sanitizer::u64)((IsAligned(offset
, 4096))); __sanitizer::u64 v2 = (__sanitizer::u64)(0); if (__builtin_expect
(!!(!(v1 != v2)), 0)) __sanitizer::CheckFailed("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 160, "(" "(IsAligned(offset, 4096))" ") " "!=" " (" "0" ")"
, v1, v2); } while (false)
;
161 return internal_syscall(SYSCALL(mmap2)__NR_mmap2, addr, length, prot, flags, fd,
162 offset / 4096);
163#endif
164}
165#endif // !SANITIZER_S390
166
167uptr internal_munmap(void *addr, uptr length) {
168 return internal_syscall_ptrinternal_syscall(SYSCALL(munmap)11, (uptr)addr, length);
169}
170
171int internal_mprotect(void *addr, uptr length, int prot) {
172 return internal_syscall_ptrinternal_syscall(SYSCALL(mprotect)10, (uptr)addr, length, prot);
173}
174
175uptr internal_close(fd_t fd) {
176 return internal_syscall(SYSCALL(close)3, fd);
177}
178
179uptr internal_open(const char *filename, int flags) {
180#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS0
181 return internal_syscall(SYSCALL(openat)257, AT_FDCWD-100, (uptr)filename, flags);
182#else
183 return internal_syscall_ptrinternal_syscall(SYSCALL(open)2, (uptr)filename, flags);
184#endif
185}
186
187uptr internal_open(const char *filename, int flags, u32 mode) {
188#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS0
189 return internal_syscall(SYSCALL(openat)257, AT_FDCWD-100, (uptr)filename, flags,
190 mode);
191#else
192 return internal_syscall_ptrinternal_syscall(SYSCALL(open)2, (uptr)filename, flags, mode);
193#endif
194}
195
196uptr internal_read(fd_t fd, void *buf, uptr count) {
197 sptr res;
198 HANDLE_EINTR(res, (sptr)internal_syscall_ptr(SYSCALL(read), fd, (uptr)buf,{ int rverrno; do { res = ((sptr)internal_syscall(0, fd, (uptr
)buf, count)); } while (internal_iserror(res, &rverrno) &&
rverrno == 4); }
199 count)){ int rverrno; do { res = ((sptr)internal_syscall(0, fd, (uptr
)buf, count)); } while (internal_iserror(res, &rverrno) &&
rverrno == 4); }
;
200 return res;
201}
202
203uptr internal_write(fd_t fd, const void *buf, uptr count) {
204 sptr res;
205 HANDLE_EINTR(res, (sptr)internal_syscall_ptr(SYSCALL(write), fd, (uptr)buf,{ int rverrno; do { res = ((sptr)internal_syscall(1, fd, (uptr
)buf, count)); } while (internal_iserror(res, &rverrno) &&
rverrno == 4); }
206 count)){ int rverrno; do { res = ((sptr)internal_syscall(1, fd, (uptr
)buf, count)); } while (internal_iserror(res, &rverrno) &&
rverrno == 4); }
;
207 return res;
208}
209
210uptr internal_ftruncate(fd_t fd, uptr size) {
211 sptr res;
212#if SANITIZER_NETBSD0
213 HANDLE_EINTR(res, internal_syscall64(SYSCALL(ftruncate), fd, 0, (s64)size)){ int rverrno; do { res = (internal_syscall(77, fd, 0, (s64)size
)); } while (internal_iserror(res, &rverrno) && rverrno
== 4); }
;
214#else
215 HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(ftruncate), fd,{ int rverrno; do { res = ((sptr)internal_syscall(77, fd, (OFF_T
)size)); } while (internal_iserror(res, &rverrno) &&
rverrno == 4); }
216 (OFF_T)size)){ int rverrno; do { res = ((sptr)internal_syscall(77, fd, (OFF_T
)size)); } while (internal_iserror(res, &rverrno) &&
rverrno == 4); }
;
217#endif
218 return res;
219}
220
221#if !SANITIZER_LINUX_USES_64BIT_SYSCALLS1 && SANITIZER_LINUX1
222static void stat64_to_stat(struct stat64 *in, struct stat *out) {
223 internal_memset(out, 0, sizeof(*out));
224 out->st_dev = in->st_dev;
225 out->st_ino = in->st_ino;
226 out->st_mode = in->st_mode;
227 out->st_nlink = in->st_nlink;
228 out->st_uid = in->st_uid;
229 out->st_gid = in->st_gid;
230 out->st_rdev = in->st_rdev;
231 out->st_size = in->st_size;
232 out->st_blksize = in->st_blksize;
233 out->st_blocks = in->st_blocks;
234 out->st_atimest_atim.tv_sec = in->st_atimest_atim.tv_sec;
235 out->st_mtimest_mtim.tv_sec = in->st_mtimest_mtim.tv_sec;
236 out->st_ctimest_ctim.tv_sec = in->st_ctimest_ctim.tv_sec;
237}
238#endif
239
240#if defined(__mips64)
241// Undefine compatibility macros from <sys/stat.h>
242// so that they would not clash with the kernel_stat
243// st_[a|m|c]time fields
244#undef st_atimest_atim.tv_sec
245#undef st_mtimest_mtim.tv_sec
246#undef st_ctimest_ctim.tv_sec
247#if defined(SANITIZER_ANDROID0)
248// Bionic sys/stat.h defines additional macros
249// for compatibility with the old NDKs and
250// they clash with the kernel_stat structure
251// st_[a|m|c]time_nsec fields.
252#undef st_atime_nsec
253#undef st_mtime_nsec
254#undef st_ctime_nsec
255#endif
256static void kernel_stat_to_stat(struct kernel_stat *in, struct stat *out) {
257 internal_memset(out, 0, sizeof(*out));
258 out->st_dev = in->st_dev;
259 out->st_ino = in->st_ino;
260 out->st_mode = in->st_mode;
261 out->st_nlink = in->st_nlink;
262 out->st_uid = in->st_uid;
263 out->st_gid = in->st_gid;
264 out->st_rdev = in->st_rdev;
265 out->st_size = in->st_size;
266 out->st_blksize = in->st_blksize;
267 out->st_blocks = in->st_blocks;
268#if defined(__USE_MISC1) || \
269 defined(__USE_XOPEN2K81) || \
270 defined(SANITIZER_ANDROID0)
271 out->st_atim.tv_sec = in->st_atimest_atim.tv_sec;
272 out->st_atim.tv_nsec = in->st_atime_nsec;
273 out->st_mtim.tv_sec = in->st_mtimest_mtim.tv_sec;
274 out->st_mtim.tv_nsec = in->st_mtime_nsec;
275 out->st_ctim.tv_sec = in->st_ctimest_ctim.tv_sec;
276 out->st_ctim.tv_nsec = in->st_ctime_nsec;
277#else
278 out->st_atimest_atim.tv_sec = in->st_atimest_atim.tv_sec;
279 out->st_atimensec = in->st_atime_nsec;
280 out->st_mtimest_mtim.tv_sec = in->st_mtimest_mtim.tv_sec;
281 out->st_mtimensec = in->st_mtime_nsec;
282 out->st_ctimest_ctim.tv_sec = in->st_ctimest_ctim.tv_sec;
283 out->st_atimensec = in->st_ctime_nsec;
284#endif
285}
286#endif
287
288uptr internal_stat(const char *path, void *buf) {
289#if SANITIZER_FREEBSD0 || SANITIZER_NETBSD0
290 return internal_syscall_ptrinternal_syscall(SYSCALL(fstatat)__NR_fstatat, AT_FDCWD-100, (uptr)path,
291 (uptr)buf, 0);
292#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS0
293 return internal_syscall(SYSCALL(newfstatat)262, AT_FDCWD-100, (uptr)path,
294 (uptr)buf, 0);
295#elif SANITIZER_LINUX_USES_64BIT_SYSCALLS1
296# if defined(__mips64)
297 // For mips64, stat syscall fills buffer in the format of kernel_stat
298 struct kernel_stat kbuf;
299 int res = internal_syscall(SYSCALL(stat)4, path, &kbuf);
300 kernel_stat_to_stat(&kbuf, (struct stat *)buf);
301 return res;
302# else
303 return internal_syscall(SYSCALL(stat)4, (uptr)path, (uptr)buf);
2
Calling 'internal_syscall'
3
Returning from 'internal_syscall'
304# endif
305#else
306 struct stat64 buf64;
307 int res = internal_syscall(SYSCALL(stat64)__NR_stat64, path, &buf64);
308 stat64_to_stat(&buf64, (struct stat *)buf);
309 return res;
310#endif
311}
312
313uptr internal_lstat(const char *path, void *buf) {
314#if SANITIZER_NETBSD0
315 return internal_syscall_ptrinternal_syscall(SYSCALL(lstat)6, path, buf);
316#elif SANITIZER_FREEBSD0
317 return internal_syscall(SYSCALL(fstatat)__NR_fstatat, AT_FDCWD-100, (uptr)path,
318 (uptr)buf, AT_SYMLINK_NOFOLLOW0x100);
319#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS0
320 return internal_syscall(SYSCALL(newfstatat)262, AT_FDCWD-100, (uptr)path,
321 (uptr)buf, AT_SYMLINK_NOFOLLOW0x100);
322#elif SANITIZER_LINUX_USES_64BIT_SYSCALLS1
323# if SANITIZER_MIPS640
324 // For mips64, lstat syscall fills buffer in the format of kernel_stat
325 struct kernel_stat kbuf;
326 int res = internal_syscall(SYSCALL(lstat)6, path, &kbuf);
327 kernel_stat_to_stat(&kbuf, (struct stat *)buf);
328 return res;
329# else
330 return internal_syscall(SYSCALL(lstat)6, (uptr)path, (uptr)buf);
331# endif
332#else
333 struct stat64 buf64;
334 int res = internal_syscall(SYSCALL(lstat64)__NR_lstat64, path, &buf64);
335 stat64_to_stat(&buf64, (struct stat *)buf);
336 return res;
337#endif
338}
339
340uptr internal_fstat(fd_t fd, void *buf) {
341#if SANITIZER_FREEBSD0 || SANITIZER_NETBSD0 || SANITIZER_LINUX_USES_64BIT_SYSCALLS1
342# if SANITIZER_MIPS640 && !SANITIZER_NETBSD0
343 // For mips64, fstat syscall fills buffer in the format of kernel_stat
344 struct kernel_stat kbuf;
345 int res = internal_syscall(SYSCALL(fstat)5, fd, &kbuf);
346 kernel_stat_to_stat(&kbuf, (struct stat *)buf);
347 return res;
348# else
349 return internal_syscall_ptrinternal_syscall(SYSCALL(fstat)5, fd, (uptr)buf);
350# endif
351#else
352 struct stat64 buf64;
353 int res = internal_syscall(SYSCALL(fstat64)__NR_fstat64, fd, &buf64);
354 stat64_to_stat(&buf64, (struct stat *)buf);
355 return res;
356#endif
357}
358
359uptr internal_filesize(fd_t fd) {
360 struct stat st;
361 if (internal_fstat(fd, &st))
362 return -1;
363 return (uptr)st.st_size;
364}
365
366uptr internal_dup2(int oldfd, int newfd) {
367#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS0
368 return internal_syscall(SYSCALL(dup3)292, oldfd, newfd, 0);
369#else
370 return internal_syscall(SYSCALL(dup2)33, oldfd, newfd);
371#endif
372}
373
374uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
375#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS0
376 return internal_syscall(SYSCALL(readlinkat)267, AT_FDCWD-100,
377 (uptr)path, (uptr)buf, bufsize);
378#else
379 return internal_syscall_ptrinternal_syscall(SYSCALL(readlink)89, path, buf, bufsize);
380#endif
381}
382
383uptr internal_unlink(const char *path) {
384#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS0
385 return internal_syscall(SYSCALL(unlinkat)263, AT_FDCWD-100, (uptr)path, 0);
386#else
387 return internal_syscall_ptrinternal_syscall(SYSCALL(unlink)87, (uptr)path);
388#endif
389}
390
391uptr internal_rename(const char *oldpath, const char *newpath) {
392#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS0
393 return internal_syscall(SYSCALL(renameat)264, AT_FDCWD-100, (uptr)oldpath, AT_FDCWD-100,
394 (uptr)newpath);
395#else
396 return internal_syscall_ptrinternal_syscall(SYSCALL(rename)82, (uptr)oldpath, (uptr)newpath);
397#endif
398}
399
400uptr internal_sched_yield() {
401 return internal_syscall(SYSCALL(sched_yield)24);
402}
403
404void internal__exit(int exitcode) {
405#if SANITIZER_FREEBSD0 || SANITIZER_NETBSD0
406 internal_syscall(SYSCALL(exit)60, exitcode);
407#else
408 internal_syscall(SYSCALL(exit_group)231, exitcode);
409#endif
410 Die(); // Unreachable.
411}
412
413unsigned int internal_sleep(unsigned int seconds) {
414 struct timespec ts;
415 ts.tv_sec = 1;
416 ts.tv_nsec = 0;
417 int res = internal_syscall_ptrinternal_syscall(SYSCALL(nanosleep)35, &ts, &ts);
418 if (res) return ts.tv_sec;
419 return 0;
420}
421
422uptr internal_execve(const char *filename, char *const argv[],
423 char *const envp[]) {
424 return internal_syscall_ptrinternal_syscall(SYSCALL(execve)59, (uptr)filename, (uptr)argv,
425 (uptr)envp);
426}
427
428// ----------------- sanitizer_common.h
429bool FileExists(const char *filename) {
430 struct stat st;
431#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS0
432 if (internal_syscall(SYSCALL(newfstatat)262, AT_FDCWD-100, filename, &st, 0))
433#else
434 if (internal_stat(filename, &st))
1
Calling 'internal_stat'
4
Returning from 'internal_stat'
5
Taking false branch
435#endif
436 return false;
437 // Sanity check: filename is a regular file.
438 return S_ISREG(st.st_mode)((((st.st_mode)) & 0170000) == (0100000));
6
Within the expansion of the macro 'S_ISREG':
a
The left operand of '&' is a garbage value
439}
440
441tid_t GetTid() {
442#if SANITIZER_FREEBSD0
443 return (uptr)pthread_self();
444#elif SANITIZER_NETBSD0
445 return _lwp_self();
446#else
447 return internal_syscall(SYSCALL(gettid)186);
448#endif
449}
450
451u64 NanoTime() {
452#if SANITIZER_FREEBSD0 || SANITIZER_NETBSD0
453 timeval tv;
454#else
455 kernel_timeval tv;
456#endif
457 internal_memset(&tv, 0, sizeof(tv));
458 internal_syscall_ptrinternal_syscall(SYSCALL(gettimeofday)96, &tv, 0);
459 return (u64)tv.tv_sec * 1000*1000*1000 + tv.tv_usec * 1000;
460}
461
462// Like getenv, but reads env directly from /proc (on Linux) or parses the
463// 'environ' array (on FreeBSD) and does not use libc. This function should be
464// called first inside __asan_init.
465const char *GetEnv(const char *name) {
466#if SANITIZER_FREEBSD0 || SANITIZER_NETBSD0
467 if (::environ != 0) {
468 uptr NameLen = internal_strlen(name);
469 for (char **Env = ::environ; *Env != 0; Env++) {
470 if (internal_strncmp(*Env, name, NameLen) == 0 && (*Env)[NameLen] == '=')
471 return (*Env) + NameLen + 1;
472 }
473 }
474 return 0; // Not found.
475#elif SANITIZER_LINUX1
476 static char *environ;
477 static uptr len;
478 static bool inited;
479 if (!inited) {
480 inited = true;
481 uptr environ_size;
482 if (!ReadFileToBuffer("/proc/self/environ", &environ, &environ_size, &len))
483 environ = nullptr;
484 }
485 if (!environ || len == 0) return nullptr;
486 uptr namelen = internal_strlen(name);
487 const char *p = environ;
488 while (*p != '\0') { // will happen at the \0\0 that terminates the buffer
489 // proc file has the format NAME=value\0NAME=value\0NAME=value\0...
490 const char* endp =
491 (char*)internal_memchr(p, '\0', len - (p - environ));
492 if (!endp) // this entry isn't NUL terminated
493 return nullptr;
494 else if (!internal_memcmp(p, name, namelen) && p[namelen] == '=') // Match.
495 return p + namelen + 1; // point after =
496 p = endp + 1;
497 }
498 return nullptr; // Not found.
499#else
500#error "Unsupported platform"
501#endif
502}
503
504#if !SANITIZER_FREEBSD0 && !SANITIZER_NETBSD0
505extern "C" {
506 SANITIZER_WEAK_ATTRIBUTE__attribute__((weak)) extern void *__libc_stack_end;
507}
508#endif
509
510#if !SANITIZER_GO0 && !SANITIZER_FREEBSD0 && !SANITIZER_NETBSD0
511static void ReadNullSepFileToArray(const char *path, char ***arr,
512 int arr_size) {
513 char *buff;
514 uptr buff_size;
515 uptr buff_len;
516 *arr = (char **)MmapOrDie(arr_size * sizeof(char *), "NullSepFileArray");
517 if (!ReadFileToBuffer(path, &buff, &buff_size, &buff_len, 1024 * 1024)) {
518 (*arr)[0] = nullptr;
519 return;
520 }
521 (*arr)[0] = buff;
522 int count, i;
523 for (count = 1, i = 1; ; i++) {
524 if (buff[i] == 0) {
525 if (buff[i+1] == 0) break;
526 (*arr)[count] = &buff[i+1];
527 CHECK_LE(count, arr_size - 1)do { __sanitizer::u64 v1 = (__sanitizer::u64)((count)); __sanitizer
::u64 v2 = (__sanitizer::u64)((arr_size - 1)); if (__builtin_expect
(!!(!(v1 <= v2)), 0)) __sanitizer::CheckFailed("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 527, "(" "(count)" ") " "<=" " (" "(arr_size - 1)" ")", v1
, v2); } while (false)
; // FIXME: make this more flexible.
528 count++;
529 }
530 }
531 (*arr)[count] = nullptr;
532}
533#endif
534
535static void GetArgsAndEnv(char ***argv, char ***envp) {
536#if SANITIZER_FREEBSD0
537 // On FreeBSD, retrieving the argument and environment arrays is done via the
538 // kern.ps_strings sysctl, which returns a pointer to a structure containing
539 // this information. See also <sys/exec.h>.
540 ps_strings *pss;
541 size_t sz = sizeof(pss);
542 if (sysctlbyname("kern.ps_strings", &pss, &sz, NULL__null, 0) == -1) {
543 Printf("sysctl kern.ps_strings failed\n");
544 Die();
545 }
546 *argv = pss->ps_argvstr;
547 *envp = pss->ps_envstr;
548#elif SANITIZER_NETBSD0
549 *argv = __ps_strings->ps_argvstr;
550 *argv = __ps_strings->ps_envstr;
551#else
552#if !SANITIZER_GO0
553 if (&__libc_stack_end) {
554#endif
555 uptr* stack_end = (uptr*)__libc_stack_end;
556 int argc = *stack_end;
557 *argv = (char**)(stack_end + 1);
558 *envp = (char**)(stack_end + argc + 2);
559#if !SANITIZER_GO0
560 } else {
561 static const int kMaxArgv = 2000, kMaxEnvp = 2000;
562 ReadNullSepFileToArray("/proc/self/cmdline", argv, kMaxArgv);
563 ReadNullSepFileToArray("/proc/self/environ", envp, kMaxEnvp);
564 }
565#endif
566#endif
567}
568
569char **GetArgv() {
570 char **argv, **envp;
571 GetArgsAndEnv(&argv, &envp);
572 return argv;
573}
574
575void ReExec() {
576 char **argv, **envp;
577 const char *pathname = "/proc/self/exe";
578
579#if SANITIZER_NETBSD0
580 static const int name[] = {
581 CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME,
582 };
583 char path[400];
584 size_t len;
585
586 len = sizeof(path);
587 if (sysctl(name, ARRAY_SIZE(name)(sizeof(name)/sizeof((name)[0])), path, &len, NULL__null, 0) != -1)
588 pathname = path;
589#endif
590
591 GetArgsAndEnv(&argv, &envp);
592 uptr rv = internal_execve(pathname, argv, envp);
593 int rverrno;
594 CHECK_EQ(internal_iserror(rv, &rverrno), true)do { __sanitizer::u64 v1 = (__sanitizer::u64)((internal_iserror
(rv, &rverrno))); __sanitizer::u64 v2 = (__sanitizer::u64
)((true)); if (__builtin_expect(!!(!(v1 == v2)), 0)) __sanitizer
::CheckFailed("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 594, "(" "(internal_iserror(rv, &rverrno))" ") " "==" " ("
"(true)" ")", v1, v2); } while (false)
;
595 Printf("execve failed, errno %d\n", rverrno);
596 Die();
597}
598
599enum MutexState {
600 MtxUnlocked = 0,
601 MtxLocked = 1,
602 MtxSleeping = 2
603};
604
605BlockingMutex::BlockingMutex() {
606 internal_memset(this, 0, sizeof(*this));
607}
608
609void BlockingMutex::Lock() {
610 CHECK_EQ(owner_, 0)do { __sanitizer::u64 v1 = (__sanitizer::u64)((owner_)); __sanitizer
::u64 v2 = (__sanitizer::u64)((0)); if (__builtin_expect(!!(!
(v1 == v2)), 0)) __sanitizer::CheckFailed("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 610, "(" "(owner_)" ") " "==" " (" "(0)" ")", v1, v2); } while
(false)
;
611 atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
612 if (atomic_exchange(m, MtxLocked, memory_order_acquire) == MtxUnlocked)
613 return;
614 while (atomic_exchange(m, MtxSleeping, memory_order_acquire) != MtxUnlocked) {
615#if SANITIZER_FREEBSD0
616 _umtx_op(m, UMTX_OP_WAIT_UINT, MtxSleeping, 0, 0);
617#elif SANITIZER_NETBSD0
618 sched_yield(); /* No userspace futex-like synchromization */
619#else
620 internal_syscall(SYSCALL(futex)202, (uptr)m, FUTEX_WAIT, MtxSleeping, 0, 0, 0);
621#endif
622 }
623}
624
625void BlockingMutex::Unlock() {
626 atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
627 u32 v = atomic_exchange(m, MtxUnlocked, memory_order_release);
628 CHECK_NE(v, MtxUnlocked)do { __sanitizer::u64 v1 = (__sanitizer::u64)((v)); __sanitizer
::u64 v2 = (__sanitizer::u64)((MtxUnlocked)); if (__builtin_expect
(!!(!(v1 != v2)), 0)) __sanitizer::CheckFailed("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 628, "(" "(v)" ") " "!=" " (" "(MtxUnlocked)" ")", v1, v2);
} while (false)
;
629 if (v == MtxSleeping) {
630#if SANITIZER_FREEBSD0
631 _umtx_op(m, UMTX_OP_WAKE, 1, 0, 0);
632#elif SANITIZER_NETBSD0
633 /* No userspace futex-like synchromization */
634#else
635 internal_syscall(SYSCALL(futex)202, (uptr)m, FUTEX_WAKE, 1, 0, 0, 0);
636#endif
637 }
638}
639
640void BlockingMutex::CheckLocked() {
641 atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
642 CHECK_NE(MtxUnlocked, atomic_load(m, memory_order_relaxed))do { __sanitizer::u64 v1 = (__sanitizer::u64)((MtxUnlocked));
__sanitizer::u64 v2 = (__sanitizer::u64)((atomic_load(m, memory_order_relaxed
))); if (__builtin_expect(!!(!(v1 != v2)), 0)) __sanitizer::CheckFailed
("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 642, "(" "(MtxUnlocked)" ") " "!=" " (" "(atomic_load(m, memory_order_relaxed))"
")", v1, v2); } while (false)
;
643}
644
645// ----------------- sanitizer_linux.h
646// The actual size of this structure is specified by d_reclen.
647// Note that getdents64 uses a different structure format. We only provide the
648// 32-bit syscall here.
649#if SANITIZER_NETBSD0
650// struct dirent is different for Linux and us. At this moment, we use only
651// d_fileno (Linux call this d_ino), d_reclen, and d_name.
652struct linux_dirent {
653 u64 d_ino; // d_fileno
654 u16 d_reclen;
655 u16 d_namlen; // not used
656 u8 d_type; // not used
657 char d_name[NAME_MAX + 1];
658};
659#else
660struct linux_dirent {
661#if SANITIZER_X320 || defined(__aarch64__)
662 u64 d_ino;
663 u64 d_off;
664#else
665 unsigned long d_ino;
666 unsigned long d_off;
667#endif
668 unsigned short d_reclen;
669#ifdef __aarch64__
670 unsigned char d_type;
671#endif
672 char d_name[256];
673};
674#endif
675
676// Syscall wrappers.
677uptr internal_ptrace(int request, int pid, void *addr, void *data) {
678#if SANITIZER_NETBSD0
679 // XXX We need additional work for ptrace:
680 // - for request, we use PT_FOO whereas Linux uses PTRACE_FOO
681 // - data is int for us, but void * for Linux
682 // - Linux sometimes uses data in the case where we use addr instead
683 // At this moment, this function is used only within
684 // "#if SANITIZER_LINUX && defined(__x86_64__)" block in
685 // sanitizer_stoptheworld_linux_libcdep.cc.
686 return internal_syscall_ptrinternal_syscall(SYSCALL(ptrace)101, request, pid, (uptr)addr,
687 (uptr)data);
688#else
689 return internal_syscall(SYSCALL(ptrace)101, request, pid, (uptr)addr,
690 (uptr)data);
691#endif
692}
693
694uptr internal_waitpid(int pid, int *status, int options) {
695 return internal_syscall_ptrinternal_syscall(SYSCALL(wait4)61, pid, (uptr)status, options,
696 0 /* rusage */);
697}
698
699uptr internal_getpid() {
700 return internal_syscall(SYSCALL(getpid)39);
701}
702
703uptr internal_getppid() {
704 return internal_syscall(SYSCALL(getppid)110);
705}
706
707uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count) {
708#if SANITIZER_FREEBSD0
709 return internal_syscall(SYSCALL(getdirentries)__NR_getdirentries, fd, (uptr)dirp, count, NULL__null);
710#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS0
711 return internal_syscall(SYSCALL(getdents64)217, fd, (uptr)dirp, count);
712#else
713 return internal_syscall_ptrinternal_syscall(SYSCALL(getdents)78, fd, (uptr)dirp, count);
714#endif
715}
716
717uptr internal_lseek(fd_t fd, OFF_T offset, int whence) {
718#if SANITIZER_NETBSD0
719 return internal_syscall64internal_syscall(SYSCALL(lseek)8, fd, 0, offset, whence);
720#else
721 return internal_syscall(SYSCALL(lseek)8, fd, offset, whence);
722#endif
723}
724
725#if SANITIZER_LINUX1
726uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5) {
727 return internal_syscall(SYSCALL(prctl)157, option, arg2, arg3, arg4, arg5);
728}
729#endif
730
731uptr internal_sigaltstack(const void *ss, void *oss) {
732 return internal_syscall_ptrinternal_syscall(SYSCALL(sigaltstack)131, (uptr)ss, (uptr)oss);
733}
734
735int internal_fork() {
736#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS0
737 return internal_syscall(SYSCALL(clone)56, SIGCHLD17, 0);
738#else
739 return internal_syscall(SYSCALL(fork)57);
740#endif
741}
742
743#if SANITIZER_LINUX1
744#define SA_RESTORER0x04000000 0x04000000
745// Doesn't set sa_restorer if the caller did not set it, so use with caution
746//(see below).
747int internal_sigaction_norestorer(int signum, const void *act, void *oldact) {
748 __sanitizer_kernel_sigaction_t k_act, k_oldact;
749 internal_memset(&k_act, 0, sizeof(__sanitizer_kernel_sigaction_t));
750 internal_memset(&k_oldact, 0, sizeof(__sanitizer_kernel_sigaction_t));
751 const __sanitizer_sigaction *u_act = (const __sanitizer_sigaction *)act;
752 __sanitizer_sigaction *u_oldact = (__sanitizer_sigaction *)oldact;
753 if (u_act) {
754 k_act.handler = u_act->handler;
755 k_act.sigaction = u_act->sigaction;
756 internal_memcpy(&k_act.sa_mask, &u_act->sa_mask,
757 sizeof(__sanitizer_kernel_sigset_t));
758 // Without SA_RESTORER kernel ignores the calls (probably returns EINVAL).
759 k_act.sa_flags = u_act->sa_flags | SA_RESTORER0x04000000;
760 // FIXME: most often sa_restorer is unset, however the kernel requires it
761 // to point to a valid signal restorer that calls the rt_sigreturn syscall.
762 // If sa_restorer passed to the kernel is NULL, the program may crash upon
763 // signal delivery or fail to unwind the stack in the signal handler.
764 // libc implementation of sigaction() passes its own restorer to
765 // rt_sigaction, so we need to do the same (we'll need to reimplement the
766 // restorers; for x86_64 the restorer address can be obtained from
767 // oldact->sa_restorer upon a call to sigaction(xxx, NULL, oldact).
768#if !SANITIZER_ANDROID0 || !SANITIZER_MIPS320
769 k_act.sa_restorer = u_act->sa_restorer;
770#endif
771 }
772
773 uptr result = internal_syscall(SYSCALL(rt_sigaction)13, (uptr)signum,
774 (uptr)(u_act ? &k_act : nullptr),
775 (uptr)(u_oldact ? &k_oldact : nullptr),
776 (uptr)sizeof(__sanitizer_kernel_sigset_t));
777
778 if ((result == 0) && u_oldact) {
779 u_oldact->handler = k_oldact.handler;
780 u_oldact->sigaction = k_oldact.sigaction;
781 internal_memcpy(&u_oldact->sa_mask, &k_oldact.sa_mask,
782 sizeof(__sanitizer_kernel_sigset_t));
783 u_oldact->sa_flags = k_oldact.sa_flags;
784#if !SANITIZER_ANDROID0 || !SANITIZER_MIPS320
785 u_oldact->sa_restorer = k_oldact.sa_restorer;
786#endif
787 }
788 return result;
789}
790
791// Invokes sigaction via a raw syscall with a restorer, but does not support
792// all platforms yet.
793// We disable for Go simply because we have not yet added to buildgo.sh.
794#if (defined(__x86_64__1) || SANITIZER_MIPS640) && !SANITIZER_GO0
795int internal_sigaction_syscall(int signum, const void *act, void *oldact) {
796 if (act == nullptr)
797 return internal_sigaction_norestorer(signum, act, oldact);
798 __sanitizer_sigaction u_adjust;
799 internal_memcpy(&u_adjust, act, sizeof(u_adjust));
800#if !SANITIZER_ANDROID0 || !SANITIZER_MIPS320
801 if (u_adjust.sa_restorer == nullptr) {
802 u_adjust.sa_restorer = internal_sigreturn;
803 }
804#endif
805 return internal_sigaction_norestorer(signum, (const void *)&u_adjust,
806 oldact);
807}
808#endif // defined(__x86_64__) && !SANITIZER_GO
809#endif // SANITIZER_LINUX
810
811uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
812 __sanitizer_sigset_t *oldset) {
813#if SANITIZER_FREEBSD0 || SANITIZER_NETBSD0
814 return internal_syscall_ptrinternal_syscall(SYSCALL(sigprocmask)__NR_sigprocmask, how, set, oldset);
815#else
816 __sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;
817 __sanitizer_kernel_sigset_t *k_oldset = (__sanitizer_kernel_sigset_t *)oldset;
818 return internal_syscall(SYSCALL(rt_sigprocmask)14, (uptr)how,
819 (uptr)&k_set->sig[0], (uptr)&k_oldset->sig[0],
820 sizeof(__sanitizer_kernel_sigset_t));
821#endif
822}
823
824void internal_sigfillset(__sanitizer_sigset_t *set) {
825 internal_memset(set, 0xff, sizeof(*set));
826}
827
828void internal_sigemptyset(__sanitizer_sigset_t *set) {
829 internal_memset(set, 0, sizeof(*set));
830}
831
832#if SANITIZER_LINUX1
833void internal_sigdelset(__sanitizer_sigset_t *set, int signum) {
834 signum -= 1;
835 CHECK_GE(signum, 0)do { __sanitizer::u64 v1 = (__sanitizer::u64)((signum)); __sanitizer
::u64 v2 = (__sanitizer::u64)((0)); if (__builtin_expect(!!(!
(v1 >= v2)), 0)) __sanitizer::CheckFailed("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 835, "(" "(signum)" ") " ">=" " (" "(0)" ")", v1, v2); }
while (false)
;
836 CHECK_LT(signum, sizeof(*set) * 8)do { __sanitizer::u64 v1 = (__sanitizer::u64)((signum)); __sanitizer
::u64 v2 = (__sanitizer::u64)((sizeof(*set) * 8)); if (__builtin_expect
(!!(!(v1 < v2)), 0)) __sanitizer::CheckFailed("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 836, "(" "(signum)" ") " "<" " (" "(sizeof(*set) * 8)" ")"
, v1, v2); } while (false)
;
837 __sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;
838 const uptr idx = signum / (sizeof(k_set->sig[0]) * 8);
839 const uptr bit = signum % (sizeof(k_set->sig[0]) * 8);
840 k_set->sig[idx] &= ~(1 << bit);
841}
842
843bool internal_sigismember(__sanitizer_sigset_t *set, int signum) {
844 signum -= 1;
845 CHECK_GE(signum, 0)do { __sanitizer::u64 v1 = (__sanitizer::u64)((signum)); __sanitizer
::u64 v2 = (__sanitizer::u64)((0)); if (__builtin_expect(!!(!
(v1 >= v2)), 0)) __sanitizer::CheckFailed("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 845, "(" "(signum)" ") " ">=" " (" "(0)" ")", v1, v2); }
while (false)
;
846 CHECK_LT(signum, sizeof(*set) * 8)do { __sanitizer::u64 v1 = (__sanitizer::u64)((signum)); __sanitizer
::u64 v2 = (__sanitizer::u64)((sizeof(*set) * 8)); if (__builtin_expect
(!!(!(v1 < v2)), 0)) __sanitizer::CheckFailed("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 846, "(" "(signum)" ") " "<" " (" "(sizeof(*set) * 8)" ")"
, v1, v2); } while (false)
;
847 __sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;
848 const uptr idx = signum / (sizeof(k_set->sig[0]) * 8);
849 const uptr bit = signum % (sizeof(k_set->sig[0]) * 8);
850 return k_set->sig[idx] & (1 << bit);
851}
852#endif // SANITIZER_LINUX
853
854// ThreadLister implementation.
855ThreadLister::ThreadLister(int pid)
856 : pid_(pid),
857 descriptor_(-1),
858 buffer_(4096),
859 error_(true),
860 entry_((struct linux_dirent *)buffer_.data()),
861 bytes_read_(0) {
862 char task_directory_path[80];
863 internal_snprintf(task_directory_path, sizeof(task_directory_path),
864 "/proc/%d/task/", pid);
865 uptr openrv = internal_open(task_directory_path, O_RDONLY00 | O_DIRECTORY0200000);
866 if (internal_iserror(openrv)) {
867 error_ = true;
868 Report("Can't open /proc/%d/task for reading.\n", pid);
869 } else {
870 error_ = false;
871 descriptor_ = openrv;
872 }
873}
874
875int ThreadLister::GetNextTID() {
876 int tid = -1;
877 do {
878 if (error_)
879 return -1;
880 if ((char *)entry_ >= &buffer_[bytes_read_] && !GetDirectoryEntries())
881 return -1;
882 if (entry_->d_ino != 0 && entry_->d_name[0] >= '0' &&
883 entry_->d_name[0] <= '9') {
884 // Found a valid tid.
885 tid = (int)internal_atoll(entry_->d_name);
886 }
887 entry_ = (struct linux_dirent *)(((char *)entry_) + entry_->d_reclen);
888 } while (tid < 0);
889 return tid;
890}
891
892void ThreadLister::Reset() {
893 if (error_ || descriptor_ < 0)
894 return;
895 internal_lseek(descriptor_, 0, SEEK_SET0);
896}
897
898ThreadLister::~ThreadLister() {
899 if (descriptor_ >= 0)
900 internal_close(descriptor_);
901}
902
903bool ThreadLister::error() { return error_; }
904
905bool ThreadLister::GetDirectoryEntries() {
906 CHECK_GE(descriptor_, 0)do { __sanitizer::u64 v1 = (__sanitizer::u64)((descriptor_));
__sanitizer::u64 v2 = (__sanitizer::u64)((0)); if (__builtin_expect
(!!(!(v1 >= v2)), 0)) __sanitizer::CheckFailed("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 906, "(" "(descriptor_)" ") " ">=" " (" "(0)" ")", v1, v2
); } while (false)
;
907 CHECK_NE(error_, true)do { __sanitizer::u64 v1 = (__sanitizer::u64)((error_)); __sanitizer
::u64 v2 = (__sanitizer::u64)((true)); if (__builtin_expect(!
!(!(v1 != v2)), 0)) __sanitizer::CheckFailed("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 907, "(" "(error_)" ") " "!=" " (" "(true)" ")", v1, v2); }
while (false)
;
908 bytes_read_ = internal_getdents(descriptor_,
909 (struct linux_dirent *)buffer_.data(),
910 buffer_.size());
911 if (internal_iserror(bytes_read_)) {
912 Report("Can't read directory entries from /proc/%d/task.\n", pid_);
913 error_ = true;
914 return false;
915 } else if (bytes_read_ == 0) {
916 return false;
917 }
918 entry_ = (struct linux_dirent *)buffer_.data();
919 return true;
920}
921
922#if SANITIZER_WORDSIZE64 == 32
923// Take care of unusable kernel area in top gigabyte.
924static uptr GetKernelAreaSize() {
925#if SANITIZER_LINUX1 && !SANITIZER_X320
926 const uptr gbyte = 1UL << 30;
927
928 // Firstly check if there are writable segments
929 // mapped to top gigabyte (e.g. stack).
930 MemoryMappingLayout proc_maps(/*cache_enabled*/true);
931 MemoryMappedSegment segment;
932 while (proc_maps.Next(&segment)) {
933 if ((segment.end >= 3 * gbyte) && segment.IsWritable()) return 0;
934 }
935
936#if !SANITIZER_ANDROID0
937 // Even if nothing is mapped, top Gb may still be accessible
938 // if we are running on 64-bit kernel.
939 // Uname may report misleading results if personality type
940 // is modified (e.g. under schroot) so check this as well.
941 struct utsname uname_info;
942 int pers = personality(0xffffffffUL);
943 if (!(pers & PER_MASK)
944 && uname(&uname_info) == 0
945 && internal_strstr(uname_info.machine, "64"))
946 return 0;
947#endif // SANITIZER_ANDROID
948
949 // Top gigabyte is reserved for kernel.
950 return gbyte;
951#else
952 return 0;
953#endif // SANITIZER_LINUX && !SANITIZER_X32
954}
955#endif // SANITIZER_WORDSIZE == 32
956
957uptr GetMaxUserVirtualAddress() {
958#if SANITIZER_NETBSD0 && defined(__x86_64__1)
959 return 0x7f7ffffff000ULL; // (0x00007f8000000000 - PAGE_SIZE)
960#elif SANITIZER_WORDSIZE64 == 64
961# if defined(__powerpc64__) || defined(__aarch64__)
962 // On PowerPC64 we have two different address space layouts: 44- and 46-bit.
963 // We somehow need to figure out which one we are using now and choose
964 // one of 0x00000fffffffffffUL and 0x00003fffffffffffUL.
965 // Note that with 'ulimit -s unlimited' the stack is moved away from the top
966 // of the address space, so simply checking the stack address is not enough.
967 // This should (does) work for both PowerPC64 Endian modes.
968 // Similarly, aarch64 has multiple address space layouts: 39, 42 and 47-bit.
969 return (1ULL << (MostSignificantSetBitIndex(GET_CURRENT_FRAME()(__sanitizer::uptr) __builtin_frame_address(0)) + 1)) - 1;
970# elif defined(__mips64)
971 return (1ULL << 40) - 1; // 0x000000ffffffffffUL;
972# elif defined(__s390x__)
973 return (1ULL << 53) - 1; // 0x001fffffffffffffUL;
974# else
975 return (1ULL << 47) - 1; // 0x00007fffffffffffUL;
976# endif
977#else // SANITIZER_WORDSIZE == 32
978# if defined(__s390__)
979 return (1ULL << 31) - 1; // 0x7fffffff;
980# else
981 uptr res = (1ULL << 32) - 1; // 0xffffffff;
982 if (!common_flags()->full_address_space)
983 res -= GetKernelAreaSize();
984 CHECK_LT(reinterpret_cast<uptr>(&res), res)do { __sanitizer::u64 v1 = (__sanitizer::u64)((reinterpret_cast
<uptr>(&res))); __sanitizer::u64 v2 = (__sanitizer::
u64)((res)); if (__builtin_expect(!!(!(v1 < v2)), 0)) __sanitizer
::CheckFailed("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 984, "(" "(reinterpret_cast<uptr>(&res))" ") " "<"
" (" "(res)" ")", v1, v2); } while (false)
;
985 return res;
986# endif
987#endif // SANITIZER_WORDSIZE
988}
989
990uptr GetPageSize() {
991// Android post-M sysconf(_SC_PAGESIZE) crashes if called from .preinit_array.
992#if SANITIZER_ANDROID0
993 return 4096;
994#elif SANITIZER_LINUX1 && (defined(__x86_64__1) || defined(__i386__))
995 return EXEC_PAGESIZE4096;
996#elif SANITIZER_USE_GETAUXVAL1
997 return getauxval(AT_PAGESZ6);
998#else
999 return sysconf(_SC_PAGESIZE_SC_PAGESIZE); // EXEC_PAGESIZE may not be trustworthy.
1000#endif
1001}
1002
1003uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
1004#if SANITIZER_FREEBSD0 || SANITIZER_NETBSD0
1005#if SANITIZER_FREEBSD0
1006 const int Mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
1007#else
1008 const int Mib[4] = {CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME};
1009#endif
1010 const char *default_module_name = "kern.proc.pathname";
1011 size_t Size = buf_len;
1012 bool IsErr = (sysctl(Mib, ARRAY_SIZE(Mib)(sizeof(Mib)/sizeof((Mib)[0])), buf, &Size, NULL__null, 0) != 0);
1013 int readlink_error = IsErr ? errno(*__errno_location ()) : 0;
1014 uptr module_name_len = Size;
1015#else
1016 const char *default_module_name = "/proc/self/exe";
1017 uptr module_name_len = internal_readlink(
1018 default_module_name, buf, buf_len);
1019 int readlink_error;
1020 bool IsErr = internal_iserror(module_name_len, &readlink_error);
1021#endif
1022 if (IsErr) {
1023 // We can't read binary name for some reason, assume it's unknown.
1024 Report("WARNING: reading executable name failed with errno %d, "
1025 "some stack frames may not be symbolized\n", readlink_error);
1026 module_name_len = internal_snprintf(buf, buf_len, "%s",
1027 default_module_name);
1028 CHECK_LT(module_name_len, buf_len)do { __sanitizer::u64 v1 = (__sanitizer::u64)((module_name_len
)); __sanitizer::u64 v2 = (__sanitizer::u64)((buf_len)); if (
__builtin_expect(!!(!(v1 < v2)), 0)) __sanitizer::CheckFailed
("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 1028, "(" "(module_name_len)" ") " "<" " (" "(buf_len)" ")"
, v1, v2); } while (false)
;
1029 }
1030 return module_name_len;
1031}
1032
1033uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) {
1034#if SANITIZER_LINUX1
1035 char *tmpbuf;
1036 uptr tmpsize;
1037 uptr tmplen;
1038 if (ReadFileToBuffer("/proc/self/cmdline", &tmpbuf, &tmpsize, &tmplen,
1039 1024 * 1024)) {
1040 internal_strncpy(buf, tmpbuf, buf_len);
1041 UnmapOrDie(tmpbuf, tmpsize);
1042 return internal_strlen(buf);
1043 }
1044#endif
1045 return ReadBinaryName(buf, buf_len);
1046}
1047
1048// Match full names of the form /path/to/base_name{-,.}*
1049bool LibraryNameIs(const char *full_name, const char *base_name) {
1050 const char *name = full_name;
1051 // Strip path.
1052 while (*name != '\0') name++;
1053 while (name > full_name && *name != '/') name--;
1054 if (*name == '/') name++;
1055 uptr base_name_length = internal_strlen(base_name);
1056 if (internal_strncmp(name, base_name, base_name_length)) return false;
1057 return (name[base_name_length] == '-' || name[base_name_length] == '.');
1058}
1059
1060#if !SANITIZER_ANDROID0
1061// Call cb for each region mapped by map.
1062void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)) {
1063 CHECK_NE(map, nullptr)do { __sanitizer::u64 v1 = (__sanitizer::u64)((map)); __sanitizer
::u64 v2 = (__sanitizer::u64)((nullptr)); if (__builtin_expect
(!!(!(v1 != v2)), 0)) __sanitizer::CheckFailed("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 1063, "(" "(map)" ") " "!=" " (" "(nullptr)" ")", v1, v2); }
while (false)
;
1064#if !SANITIZER_FREEBSD0
1065 typedef ElfW(Phdr)Elf64_Phdr Elf_Phdr;
1066 typedef ElfW(Ehdr)Elf64_Ehdr Elf_Ehdr;
1067#endif // !SANITIZER_FREEBSD
1068 char *base = (char *)map->l_addr;
1069 Elf_Ehdr *ehdr = (Elf_Ehdr *)base;
1070 char *phdrs = base + ehdr->e_phoff;
1071 char *phdrs_end = phdrs + ehdr->e_phnum * ehdr->e_phentsize;
1072
1073 // Find the segment with the minimum base so we can "relocate" the p_vaddr
1074 // fields. Typically ET_DYN objects (DSOs) have base of zero and ET_EXEC
1075 // objects have a non-zero base.
1076 uptr preferred_base = (uptr)-1;
1077 for (char *iter = phdrs; iter != phdrs_end; iter += ehdr->e_phentsize) {
1078 Elf_Phdr *phdr = (Elf_Phdr *)iter;
1079 if (phdr->p_type == PT_LOAD1 && preferred_base > (uptr)phdr->p_vaddr)
1080 preferred_base = (uptr)phdr->p_vaddr;
1081 }
1082
1083 // Compute the delta from the real base to get a relocation delta.
1084 sptr delta = (uptr)base - preferred_base;
1085 // Now we can figure out what the loader really mapped.
1086 for (char *iter = phdrs; iter != phdrs_end; iter += ehdr->e_phentsize) {
1087 Elf_Phdr *phdr = (Elf_Phdr *)iter;
1088 if (phdr->p_type == PT_LOAD1) {
1089 uptr seg_start = phdr->p_vaddr + delta;
1090 uptr seg_end = seg_start + phdr->p_memsz;
1091 // None of these values are aligned. We consider the ragged edges of the
1092 // load command as defined, since they are mapped from the file.
1093 seg_start = RoundDownTo(seg_start, GetPageSizeCached());
1094 seg_end = RoundUpTo(seg_end, GetPageSizeCached());
1095 cb((void *)seg_start, seg_end - seg_start);
1096 }
1097 }
1098}
1099#endif
1100
1101#if defined(__x86_64__1) && SANITIZER_LINUX1
1102// We cannot use glibc's clone wrapper, because it messes with the child
1103// task's TLS. It writes the PID and TID of the child task to its thread
1104// descriptor, but in our case the child task shares the thread descriptor with
1105// the parent (because we don't know how to allocate a new thread
1106// descriptor to keep glibc happy). So the stock version of clone(), when
1107// used with CLONE_VM, would end up corrupting the parent's thread descriptor.
1108uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
1109 int *parent_tidptr, void *newtls, int *child_tidptr) {
1110 long long res;
1111 if (!fn || !child_stack)
1112 return -EINVAL22;
1113 CHECK_EQ(0, (uptr)child_stack % 16)do { __sanitizer::u64 v1 = (__sanitizer::u64)((0)); __sanitizer
::u64 v2 = (__sanitizer::u64)(((uptr)child_stack % 16)); if (
__builtin_expect(!!(!(v1 == v2)), 0)) __sanitizer::CheckFailed
("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 1113, "(" "(0)" ") " "==" " (" "((uptr)child_stack % 16)" ")"
, v1, v2); } while (false)
;
1114 child_stack = (char *)child_stack - 2 * sizeof(unsigned long long);
1115 ((unsigned long long *)child_stack)[0] = (uptr)fn;
1116 ((unsigned long long *)child_stack)[1] = (uptr)arg;
1117 register void *r8 __asm__("r8") = newtls;
1118 register int *r10 __asm__("r10") = child_tidptr;
1119 __asm__ __volatile__(
1120 /* %rax = syscall(%rax = SYSCALL(clone),
1121 * %rdi = flags,
1122 * %rsi = child_stack,
1123 * %rdx = parent_tidptr,
1124 * %r8 = new_tls,
1125 * %r10 = child_tidptr)
1126 */
1127 "syscall\n"
1128
1129 /* if (%rax != 0)
1130 * return;
1131 */
1132 "testq %%rax,%%rax\n"
1133 "jnz 1f\n"
1134
1135 /* In the child. Terminate unwind chain. */
1136 // XXX: We should also terminate the CFI unwind chain
1137 // here. Unfortunately clang 3.2 doesn't support the
1138 // necessary CFI directives, so we skip that part.
1139 "xorq %%rbp,%%rbp\n"
1140
1141 /* Call "fn(arg)". */
1142 "popq %%rax\n"
1143 "popq %%rdi\n"
1144 "call *%%rax\n"
1145
1146 /* Call _exit(%rax). */
1147 "movq %%rax,%%rdi\n"
1148 "movq %2,%%rax\n"
1149 "syscall\n"
1150
1151 /* Return to parent. */
1152 "1:\n"
1153 : "=a" (res)
1154 : "a"(SYSCALL(clone)56), "i"(SYSCALL(exit)60),
1155 "S"(child_stack),
1156 "D"(flags),
1157 "d"(parent_tidptr),
1158 "r"(r8),
1159 "r"(r10)
1160 : "rsp", "memory", "r11", "rcx");
1161 return res;
1162}
1163#elif defined(__mips__)
1164uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
1165 int *parent_tidptr, void *newtls, int *child_tidptr) {
1166 long long res;
1167 if (!fn || !child_stack)
1168 return -EINVAL22;
1169 CHECK_EQ(0, (uptr)child_stack % 16)do { __sanitizer::u64 v1 = (__sanitizer::u64)((0)); __sanitizer
::u64 v2 = (__sanitizer::u64)(((uptr)child_stack % 16)); if (
__builtin_expect(!!(!(v1 == v2)), 0)) __sanitizer::CheckFailed
("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 1169, "(" "(0)" ") " "==" " (" "((uptr)child_stack % 16)" ")"
, v1, v2); } while (false)
;
1170 child_stack = (char *)child_stack - 2 * sizeof(unsigned long long);
1171 ((unsigned long long *)child_stack)[0] = (uptr)fn;
1172 ((unsigned long long *)child_stack)[1] = (uptr)arg;
1173 register void *a3 __asm__("$7") = newtls;
1174 register int *a4 __asm__("$8") = child_tidptr;
1175 // We don't have proper CFI directives here because it requires alot of code
1176 // for very marginal benefits.
1177 __asm__ __volatile__(
1178 /* $v0 = syscall($v0 = __NR_clone,
1179 * $a0 = flags,
1180 * $a1 = child_stack,
1181 * $a2 = parent_tidptr,
1182 * $a3 = new_tls,
1183 * $a4 = child_tidptr)
1184 */
1185 ".cprestore 16;\n"
1186 "move $4,%1;\n"
1187 "move $5,%2;\n"
1188 "move $6,%3;\n"
1189 "move $7,%4;\n"
1190 /* Store the fifth argument on stack
1191 * if we are using 32-bit abi.
1192 */
1193#if SANITIZER_WORDSIZE64 == 32
1194 "lw %5,16($29);\n"
1195#else
1196 "move $8,%5;\n"
1197#endif
1198 "li $2,%6;\n"
1199 "syscall;\n"
1200
1201 /* if ($v0 != 0)
1202 * return;
1203 */
1204 "bnez $2,1f;\n"
1205
1206 /* Call "fn(arg)". */
1207#if SANITIZER_WORDSIZE64 == 32
1208#ifdef __BIG_ENDIAN__
1209 "lw $25,4($29);\n"
1210 "lw $4,12($29);\n"
1211#else
1212 "lw $25,0($29);\n"
1213 "lw $4,8($29);\n"
1214#endif
1215#else
1216 "ld $25,0($29);\n"
1217 "ld $4,8($29);\n"
1218#endif
1219 "jal $25;\n"
1220
1221 /* Call _exit($v0). */
1222 "move $4,$2;\n"
1223 "li $2,%7;\n"
1224 "syscall;\n"
1225
1226 /* Return to parent. */
1227 "1:\n"
1228 : "=r" (res)
1229 : "r"(flags),
1230 "r"(child_stack),
1231 "r"(parent_tidptr),
1232 "r"(a3),
1233 "r"(a4),
1234 "i"(__NR_clone56),
1235 "i"(__NR_exit60)
1236 : "memory", "$29" );
1237 return res;
1238}
1239#elif defined(__aarch64__)
1240uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
1241 int *parent_tidptr, void *newtls, int *child_tidptr) {
1242 long long res;
1243 if (!fn || !child_stack)
1244 return -EINVAL22;
1245 CHECK_EQ(0, (uptr)child_stack % 16)do { __sanitizer::u64 v1 = (__sanitizer::u64)((0)); __sanitizer
::u64 v2 = (__sanitizer::u64)(((uptr)child_stack % 16)); if (
__builtin_expect(!!(!(v1 == v2)), 0)) __sanitizer::CheckFailed
("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 1245, "(" "(0)" ") " "==" " (" "((uptr)child_stack % 16)" ")"
, v1, v2); } while (false)
;
1246 child_stack = (char *)child_stack - 2 * sizeof(unsigned long long);
1247 ((unsigned long long *)child_stack)[0] = (uptr)fn;
1248 ((unsigned long long *)child_stack)[1] = (uptr)arg;
1249
1250 register int (*__fn)(void *) __asm__("x0") = fn;
1251 register void *__stack __asm__("x1") = child_stack;
1252 register int __flags __asm__("x2") = flags;
1253 register void *__arg __asm__("x3") = arg;
1254 register int *__ptid __asm__("x4") = parent_tidptr;
1255 register void *__tls __asm__("x5") = newtls;
1256 register int *__ctid __asm__("x6") = child_tidptr;
1257
1258 __asm__ __volatile__(
1259 "mov x0,x2\n" /* flags */
1260 "mov x2,x4\n" /* ptid */
1261 "mov x3,x5\n" /* tls */
1262 "mov x4,x6\n" /* ctid */
1263 "mov x8,%9\n" /* clone */
1264
1265 "svc 0x0\n"
1266
1267 /* if (%r0 != 0)
1268 * return %r0;
1269 */
1270 "cmp x0, #0\n"
1271 "bne 1f\n"
1272
1273 /* In the child, now. Call "fn(arg)". */
1274 "ldp x1, x0, [sp], #16\n"
1275 "blr x1\n"
1276
1277 /* Call _exit(%r0). */
1278 "mov x8, %10\n"
1279 "svc 0x0\n"
1280 "1:\n"
1281
1282 : "=r" (res)
1283 : "i"(-EINVAL22),
1284 "r"(__fn), "r"(__stack), "r"(__flags), "r"(__arg),
1285 "r"(__ptid), "r"(__tls), "r"(__ctid),
1286 "i"(__NR_clone56), "i"(__NR_exit60)
1287 : "x30", "memory");
1288 return res;
1289}
1290#elif defined(__powerpc64__)
1291uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
1292 int *parent_tidptr, void *newtls, int *child_tidptr) {
1293 long long res;
1294// Stack frame structure.
1295#if SANITIZER_PPC64V10
1296// Back chain == 0 (SP + 112)
1297// Frame (112 bytes):
1298// Parameter save area (SP + 48), 8 doublewords
1299// TOC save area (SP + 40)
1300// Link editor doubleword (SP + 32)
1301// Compiler doubleword (SP + 24)
1302// LR save area (SP + 16)
1303// CR save area (SP + 8)
1304// Back chain (SP + 0)
1305# define FRAME_SIZE 112
1306# define FRAME_TOC_SAVE_OFFSET 40
1307#elif SANITIZER_PPC64V20
1308// Back chain == 0 (SP + 32)
1309// Frame (32 bytes):
1310// TOC save area (SP + 24)
1311// LR save area (SP + 16)
1312// CR save area (SP + 8)
1313// Back chain (SP + 0)
1314# define FRAME_SIZE 32
1315# define FRAME_TOC_SAVE_OFFSET 24
1316#else
1317# error "Unsupported PPC64 ABI"
1318#endif
1319 if (!fn || !child_stack)
1320 return -EINVAL22;
1321 CHECK_EQ(0, (uptr)child_stack % 16)do { __sanitizer::u64 v1 = (__sanitizer::u64)((0)); __sanitizer
::u64 v2 = (__sanitizer::u64)(((uptr)child_stack % 16)); if (
__builtin_expect(!!(!(v1 == v2)), 0)) __sanitizer::CheckFailed
("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 1321, "(" "(0)" ") " "==" " (" "((uptr)child_stack % 16)" ")"
, v1, v2); } while (false)
;
1322
1323 register int (*__fn)(void *) __asm__("r3") = fn;
1324 register void *__cstack __asm__("r4") = child_stack;
1325 register int __flags __asm__("r5") = flags;
1326 register void *__arg __asm__("r6") = arg;
1327 register int *__ptidptr __asm__("r7") = parent_tidptr;
1328 register void *__newtls __asm__("r8") = newtls;
1329 register int *__ctidptr __asm__("r9") = child_tidptr;
1330
1331 __asm__ __volatile__(
1332 /* fn and arg are saved across the syscall */
1333 "mr 28, %5\n\t"
1334 "mr 27, %8\n\t"
1335
1336 /* syscall
1337 r0 == __NR_clone
1338 r3 == flags
1339 r4 == child_stack
1340 r5 == parent_tidptr
1341 r6 == newtls
1342 r7 == child_tidptr */
1343 "mr 3, %7\n\t"
1344 "mr 5, %9\n\t"
1345 "mr 6, %10\n\t"
1346 "mr 7, %11\n\t"
1347 "li 0, %3\n\t"
1348 "sc\n\t"
1349
1350 /* Test if syscall was successful */
1351 "cmpdi cr1, 3, 0\n\t"
1352 "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
1353 "bne- cr1, 1f\n\t"
1354
1355 /* Set up stack frame */
1356 "li 29, 0\n\t"
1357 "stdu 29, -8(1)\n\t"
1358 "stdu 1, -%12(1)\n\t"
1359 /* Do the function call */
1360 "std 2, %13(1)\n\t"
1361#if SANITIZER_PPC64V10
1362 "ld 0, 0(28)\n\t"
1363 "ld 2, 8(28)\n\t"
1364 "mtctr 0\n\t"
1365#elif SANITIZER_PPC64V20
1366 "mr 12, 28\n\t"
1367 "mtctr 12\n\t"
1368#else
1369# error "Unsupported PPC64 ABI"
1370#endif
1371 "mr 3, 27\n\t"
1372 "bctrl\n\t"
1373 "ld 2, %13(1)\n\t"
1374
1375 /* Call _exit(r3) */
1376 "li 0, %4\n\t"
1377 "sc\n\t"
1378
1379 /* Return to parent */
1380 "1:\n\t"
1381 "mr %0, 3\n\t"
1382 : "=r" (res)
1383 : "0" (-1),
1384 "i" (EINVAL22),
1385 "i" (__NR_clone56),
1386 "i" (__NR_exit60),
1387 "r" (__fn),
1388 "r" (__cstack),
1389 "r" (__flags),
1390 "r" (__arg),
1391 "r" (__ptidptr),
1392 "r" (__newtls),
1393 "r" (__ctidptr),
1394 "i" (FRAME_SIZE),
1395 "i" (FRAME_TOC_SAVE_OFFSET)
1396 : "cr0", "cr1", "memory", "ctr", "r0", "r27", "r28", "r29");
1397 return res;
1398}
1399#elif defined(__i386__) && SANITIZER_LINUX1
1400uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
1401 int *parent_tidptr, void *newtls, int *child_tidptr) {
1402 int res;
1403 if (!fn || !child_stack)
1404 return -EINVAL22;
1405 CHECK_EQ(0, (uptr)child_stack % 16)do { __sanitizer::u64 v1 = (__sanitizer::u64)((0)); __sanitizer
::u64 v2 = (__sanitizer::u64)(((uptr)child_stack % 16)); if (
__builtin_expect(!!(!(v1 == v2)), 0)) __sanitizer::CheckFailed
("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 1405, "(" "(0)" ") " "==" " (" "((uptr)child_stack % 16)" ")"
, v1, v2); } while (false)
;
1406 child_stack = (char *)child_stack - 7 * sizeof(unsigned int);
1407 ((unsigned int *)child_stack)[0] = (uptr)flags;
1408 ((unsigned int *)child_stack)[1] = (uptr)0;
1409 ((unsigned int *)child_stack)[2] = (uptr)fn;
1410 ((unsigned int *)child_stack)[3] = (uptr)arg;
1411 __asm__ __volatile__(
1412 /* %eax = syscall(%eax = SYSCALL(clone),
1413 * %ebx = flags,
1414 * %ecx = child_stack,
1415 * %edx = parent_tidptr,
1416 * %esi = new_tls,
1417 * %edi = child_tidptr)
1418 */
1419
1420 /* Obtain flags */
1421 "movl (%%ecx), %%ebx\n"
1422 /* Do the system call */
1423 "pushl %%ebx\n"
1424 "pushl %%esi\n"
1425 "pushl %%edi\n"
1426 /* Remember the flag value. */
1427 "movl %%ebx, (%%ecx)\n"
1428 "int $0x80\n"
1429 "popl %%edi\n"
1430 "popl %%esi\n"
1431 "popl %%ebx\n"
1432
1433 /* if (%eax != 0)
1434 * return;
1435 */
1436
1437 "test %%eax,%%eax\n"
1438 "jnz 1f\n"
1439
1440 /* terminate the stack frame */
1441 "xorl %%ebp,%%ebp\n"
1442 /* Call FN. */
1443 "call *%%ebx\n"
1444#ifdef PIC
1445 "call here\n"
1446 "here:\n"
1447 "popl %%ebx\n"
1448 "addl $_GLOBAL_OFFSET_TABLE_+[.-here], %%ebx\n"
1449#endif
1450 /* Call exit */
1451 "movl %%eax, %%ebx\n"
1452 "movl %2, %%eax\n"
1453 "int $0x80\n"
1454 "1:\n"
1455 : "=a" (res)
1456 : "a"(SYSCALL(clone)56), "i"(SYSCALL(exit)60),
1457 "c"(child_stack),
1458 "d"(parent_tidptr),
1459 "S"(newtls),
1460 "D"(child_tidptr)
1461 : "memory");
1462 return res;
1463}
1464#elif defined(__arm__) && SANITIZER_LINUX1
1465uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
1466 int *parent_tidptr, void *newtls, int *child_tidptr) {
1467 unsigned int res;
1468 if (!fn || !child_stack)
1469 return -EINVAL22;
1470 child_stack = (char *)child_stack - 2 * sizeof(unsigned int);
1471 ((unsigned int *)child_stack)[0] = (uptr)fn;
1472 ((unsigned int *)child_stack)[1] = (uptr)arg;
1473 register int r0 __asm__("r0") = flags;
1474 register void *r1 __asm__("r1") = child_stack;
1475 register int *r2 __asm__("r2") = parent_tidptr;
1476 register void *r3 __asm__("r3") = newtls;
1477 register int *r4 __asm__("r4") = child_tidptr;
1478 register int r7 __asm__("r7") = __NR_clone56;
1479
1480#if __ARM_ARCH > 4 || defined (__ARM_ARCH_4T__)
1481# define ARCH_HAS_BX
1482#endif
1483#if __ARM_ARCH > 4
1484# define ARCH_HAS_BLX
1485#endif
1486
1487#ifdef ARCH_HAS_BX
1488# ifdef ARCH_HAS_BLX
1489# define BLX(R) "blx " #R "\n"
1490# else
1491# define BLX(R) "mov lr, pc; bx " #R "\n"
1492# endif
1493#else
1494# define BLX(R) "mov lr, pc; mov pc," #R "\n"
1495#endif
1496
1497 __asm__ __volatile__(
1498 /* %r0 = syscall(%r7 = SYSCALL(clone),
1499 * %r0 = flags,
1500 * %r1 = child_stack,
1501 * %r2 = parent_tidptr,
1502 * %r3 = new_tls,
1503 * %r4 = child_tidptr)
1504 */
1505
1506 /* Do the system call */
1507 "swi 0x0\n"
1508
1509 /* if (%r0 != 0)
1510 * return %r0;
1511 */
1512 "cmp r0, #0\n"
1513 "bne 1f\n"
1514
1515 /* In the child, now. Call "fn(arg)". */
1516 "ldr r0, [sp, #4]\n"
1517 "ldr ip, [sp], #8\n"
1518 BLX(ip)
1519 /* Call _exit(%r0). */
1520 "mov r7, %7\n"
1521 "swi 0x0\n"
1522 "1:\n"
1523 "mov %0, r0\n"
1524 : "=r"(res)
1525 : "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r7),
1526 "i"(__NR_exit60)
1527 : "memory");
1528 return res;
1529}
1530#endif // defined(__x86_64__) && SANITIZER_LINUX
1531
1532#if SANITIZER_ANDROID0
1533#if __ANDROID_API__ < 21
1534extern "C" __attribute__((weak)) int dl_iterate_phdr(
1535 int (*)(struct dl_phdr_info *, size_t, void *), void *);
1536#endif
1537
1538static int dl_iterate_phdr_test_cb(struct dl_phdr_info *info, size_t size,
1539 void *data) {
1540 // Any name starting with "lib" indicates a bug in L where library base names
1541 // are returned instead of paths.
1542 if (info->dlpi_name && info->dlpi_name[0] == 'l' &&
1543 info->dlpi_name[1] == 'i' && info->dlpi_name[2] == 'b') {
1544 *(bool *)data = true;
1545 return 1;
1546 }
1547 return 0;
1548}
1549
1550static atomic_uint32_t android_api_level;
1551
1552static AndroidApiLevel AndroidDetectApiLevel() {
1553 if (!&dl_iterate_phdr)
1554 return ANDROID_KITKAT; // K or lower
1555 bool base_name_seen = false;
1556 dl_iterate_phdr(dl_iterate_phdr_test_cb, &base_name_seen);
1557 if (base_name_seen)
1558 return ANDROID_LOLLIPOP_MR1; // L MR1
1559 return ANDROID_POST_LOLLIPOP; // post-L
1560 // Plain L (API level 21) is completely broken wrt ASan and not very
1561 // interesting to detect.
1562}
1563
1564AndroidApiLevel AndroidGetApiLevel() {
1565 AndroidApiLevel level =
1566 (AndroidApiLevel)atomic_load(&android_api_level, memory_order_relaxed);
1567 if (level) return level;
1568 level = AndroidDetectApiLevel();
1569 atomic_store(&android_api_level, level, memory_order_relaxed);
1570 return level;
1571}
1572
1573#endif
1574
1575static HandleSignalMode GetHandleSignalModeImpl(int signum) {
1576 switch (signum) {
1577 case SIGABRT6:
1578 return common_flags()->handle_abort;
1579 case SIGILL4:
1580 return common_flags()->handle_sigill;
1581 case SIGFPE8:
1582 return common_flags()->handle_sigfpe;
1583 case SIGSEGV11:
1584 return common_flags()->handle_segv;
1585 case SIGBUS7:
1586 return common_flags()->handle_sigbus;
1587 }
1588 return kHandleSignalNo;
1589}
1590
1591HandleSignalMode GetHandleSignalMode(int signum) {
1592 HandleSignalMode result = GetHandleSignalModeImpl(signum);
1593 if (result == kHandleSignalYes && !common_flags()->allow_user_segv_handler)
1594 return kHandleSignalExclusive;
1595 return result;
1596}
1597
1598#if !SANITIZER_GO0
1599void *internal_start_thread(void(*func)(void *arg), void *arg) {
1600 // Start the thread with signals blocked, otherwise it can steal user signals.
1601 __sanitizer_sigset_t set, old;
1602 internal_sigfillset(&set);
1603#if SANITIZER_LINUX1 && !SANITIZER_ANDROID0
1604 // Glibc uses SIGSETXID signal during setuid call. If this signal is blocked
1605 // on any thread, setuid call hangs (see test/tsan/setuid.c).
1606 internal_sigdelset(&set, 33);
1607#endif
1608 internal_sigprocmask(SIG_SETMASK2, &set, &old);
1609 void *th;
1610 real_pthread_create(&th, nullptr, (void*(*)(void *arg))func, arg);
1611 internal_sigprocmask(SIG_SETMASK2, &old, nullptr);
1612 return th;
1613}
1614
1615void internal_join_thread(void *th) {
1616 real_pthread_join(th, nullptr);
1617}
1618#else
1619void *internal_start_thread(void (*func)(void *), void *arg) { return 0; }
1620
1621void internal_join_thread(void *th) {}
1622#endif
1623
1624#if defined(__aarch64__)
1625// Android headers in the older NDK releases miss this definition.
1626struct __sanitizer_esr_context {
1627 struct _aarch64_ctx head;
1628 uint64_t esr;
1629};
1630
1631static bool Aarch64GetESR(ucontext_t *ucontext, u64 *esr) {
1632 static const u32 kEsrMagic = 0x45535201;
1633 u8 *aux = ucontext->uc_mcontext.__reserved;
1634 while (true) {
1635 _aarch64_ctx *ctx = (_aarch64_ctx *)aux;
1636 if (ctx->size == 0) break;
1637 if (ctx->magic == kEsrMagic) {
1638 *esr = ((__sanitizer_esr_context *)ctx)->esr;
1639 return true;
1640 }
1641 aux += ctx->size;
1642 }
1643 return false;
1644}
1645#endif
1646
1647SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
1648 ucontext_t *ucontext = (ucontext_t *)context;
1649#if defined(__x86_64__1) || defined(__i386__)
1650 static const uptr PF_WRITE = 1U << 1;
1651#if SANITIZER_FREEBSD0
1652 uptr err = ucontext->uc_mcontext.mc_err;
1653#elif SANITIZER_NETBSD0
1654 uptr err = ucontext->uc_mcontext.__gregs[_REG_ERR];
1655#else
1656 uptr err = ucontext->uc_mcontext.gregs[REG_ERRREG_ERR];
1657#endif
1658 return err & PF_WRITE ? WRITE : READ;
1659#elif defined(__arm__)
1660 static const uptr FSR_WRITE = 1U << 11;
1661 uptr fsr = ucontext->uc_mcontext.error_code;
1662 return fsr & FSR_WRITE ? WRITE : READ;
1663#elif defined(__aarch64__)
1664 static const u64 ESR_ELx_WNR = 1U << 6;
1665 u64 esr;
1666 if (!Aarch64GetESR(ucontext, &esr)) return UNKNOWN;
1667 return esr & ESR_ELx_WNR ? WRITE : READ;
1668#else
1669 (void)ucontext;
1670 return UNKNOWN; // FIXME: Implement.
1671#endif
1672}
1673
1674void SignalContext::DumpAllRegisters(void *context) {
1675 // FIXME: Implement this.
1676}
1677
1678static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
1679#if defined(__arm__)
1680 ucontext_t *ucontext = (ucontext_t*)context;
1681 *pc = ucontext->uc_mcontext.arm_pc;
1682 *bp = ucontext->uc_mcontext.arm_fp;
1683 *sp = ucontext->uc_mcontext.arm_sp;
1684#elif defined(__aarch64__)
1685 ucontext_t *ucontext = (ucontext_t*)context;
1686 *pc = ucontext->uc_mcontext.pc;
1687 *bp = ucontext->uc_mcontext.regs[29];
1688 *sp = ucontext->uc_mcontext.sp;
1689#elif defined(__hppa__)
1690 ucontext_t *ucontext = (ucontext_t*)context;
1691 *pc = ucontext->uc_mcontext.sc_iaoq[0];
1692 /* GCC uses %r3 whenever a frame pointer is needed. */
1693 *bp = ucontext->uc_mcontext.sc_gr[3];
1694 *sp = ucontext->uc_mcontext.sc_gr[30];
1695#elif defined(__x86_64__1)
1696# if SANITIZER_FREEBSD0
1697 ucontext_t *ucontext = (ucontext_t*)context;
1698 *pc = ucontext->uc_mcontext.mc_rip;
1699 *bp = ucontext->uc_mcontext.mc_rbp;
1700 *sp = ucontext->uc_mcontext.mc_rsp;
1701#elif SANITIZER_NETBSD0
1702 ucontext_t *ucontext = (ucontext_t *)context;
1703 *pc = ucontext->uc_mcontext.__gregs[_REG_RIP];
1704 *bp = ucontext->uc_mcontext.__gregs[_REG_RBP];
1705 *sp = ucontext->uc_mcontext.__gregs[_REG_RSP];
1706# else
1707 ucontext_t *ucontext = (ucontext_t*)context;
1708 *pc = ucontext->uc_mcontext.gregs[REG_RIPREG_RIP];
1709 *bp = ucontext->uc_mcontext.gregs[REG_RBPREG_RBP];
1710 *sp = ucontext->uc_mcontext.gregs[REG_RSPREG_RSP];
1711# endif
1712#elif defined(__i386__)
1713# if SANITIZER_FREEBSD0
1714 ucontext_t *ucontext = (ucontext_t*)context;
1715 *pc = ucontext->uc_mcontext.mc_eip;
1716 *bp = ucontext->uc_mcontext.mc_ebp;
1717 *sp = ucontext->uc_mcontext.mc_esp;
1718#elif SANITIZER_NETBSD0
1719 ucontext_t *ucontext = (ucontext_t *)context;
1720 *pc = ucontext->uc_mcontext.__gregs[_REG_EIP];
1721 *bp = ucontext->uc_mcontext.__gregs[_REG_EBP];
1722 *sp = ucontext->uc_mcontext.__gregs[_REG_ESP];
1723# else
1724 ucontext_t *ucontext = (ucontext_t*)context;
1725 *pc = ucontext->uc_mcontext.gregs[REG_EIP];
1726 *bp = ucontext->uc_mcontext.gregs[REG_EBP];
1727 *sp = ucontext->uc_mcontext.gregs[REG_ESP];
1728# endif
1729#elif defined(__powerpc__) || defined(__powerpc64__)
1730 ucontext_t *ucontext = (ucontext_t*)context;
1731 *pc = ucontext->uc_mcontext.regs->nip;
1732 *sp = ucontext->uc_mcontext.regs->gpr[PT_R1];
1733 // The powerpc{,64}-linux ABIs do not specify r31 as the frame
1734 // pointer, but GCC always uses r31 when we need a frame pointer.
1735 *bp = ucontext->uc_mcontext.regs->gpr[PT_R31];
1736#elif defined(__sparc__)
1737 ucontext_t *ucontext = (ucontext_t*)context;
1738 uptr *stk_ptr;
1739# if defined (__arch64__)
1740 *pc = ucontext->uc_mcontext.mc_gregs[MC_PC];
1741 *sp = ucontext->uc_mcontext.mc_gregs[MC_O6];
1742 stk_ptr = (uptr *) (*sp + 2047);
1743 *bp = stk_ptr[15];
1744# else
1745 *pc = ucontext->uc_mcontext.gregs[REG_PC];
1746 *sp = ucontext->uc_mcontext.gregs[REG_O6];
1747 stk_ptr = (uptr *) *sp;
1748 *bp = stk_ptr[15];
1749# endif
1750#elif defined(__mips__)
1751 ucontext_t *ucontext = (ucontext_t*)context;
1752 *pc = ucontext->uc_mcontext.pc;
1753 *bp = ucontext->uc_mcontext.gregs[30];
1754 *sp = ucontext->uc_mcontext.gregs[29];
1755#elif defined(__s390__)
1756 ucontext_t *ucontext = (ucontext_t*)context;
1757# if defined(__s390x__)
1758 *pc = ucontext->uc_mcontext.psw.addr;
1759# else
1760 *pc = ucontext->uc_mcontext.psw.addr & 0x7fffffff;
1761# endif
1762 *bp = ucontext->uc_mcontext.gregs[11];
1763 *sp = ucontext->uc_mcontext.gregs[15];
1764#else
1765# error "Unsupported arch"
1766#endif
1767}
1768
1769void SignalContext::InitPcSpBp() { GetPcSpBp(context, &pc, &sp, &bp); }
1770
1771void MaybeReexec() {
1772 // No need to re-exec on Linux.
1773}
1774
1775void PrintModuleMap() { }
1776
1777void CheckNoDeepBind(const char *filename, int flag) {
1778#ifdef RTLD_DEEPBIND0x00008
1779 if (flag & RTLD_DEEPBIND0x00008) {
1780 Report(
1781 "You are trying to dlopen a %s shared library with RTLD_DEEPBIND flag"
1782 " which is incompatibe with sanitizer runtime "
1783 "(see https://github.com/google/sanitizers/issues/611 for details"
1784 "). If you want to run %s library under sanitizers please remove "
1785 "RTLD_DEEPBIND from dlopen flags.\n",
1786 filename, filename);
1787 Die();
1788 }
1789#endif
1790}
1791
1792uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
1793 uptr *largest_gap_found) {
1794 UNREACHABLE("FindAvailableMemoryRange is not available")do { do { __sanitizer::u64 v1 = (__sanitizer::u64)((0 &&
"FindAvailableMemoryRange is not available")); __sanitizer::
u64 v2 = (__sanitizer::u64)(0); if (__builtin_expect(!!(!(v1 !=
v2)), 0)) __sanitizer::CheckFailed("/build/llvm-toolchain-snapshot-6.0~svn318601/projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc"
, 1794, "(" "(0 && \"FindAvailableMemoryRange is not available\")"
") " "!=" " (" "0" ")", v1, v2); } while (false); Die(); } while
(0)
;
1795 return 0;
1796}
1797
1798bool GetRandom(void *buffer, uptr length, bool blocking) {
1799 if (!buffer || !length || length > 256)
1800 return false;
1801#if SANITIZER_USE_GETRANDOM1
1802 static atomic_uint8_t skip_getrandom_syscall;
1803 if (!atomic_load_relaxed(&skip_getrandom_syscall)) {
1804 // Up to 256 bytes, getrandom will not be interrupted.
1805 uptr res = internal_syscall(SYSCALL(getrandom)318, buffer, length,
1806 blocking ? 0 : GRND_NONBLOCK1);
1807 int rverrno = 0;
1808 if (internal_iserror(res, &rverrno) && rverrno == ENOSYS38)
1809 atomic_store_relaxed(&skip_getrandom_syscall, 1);
1810 else if (res == length)
1811 return true;
1812 }
1813#endif // SANITIZER_USE_GETRANDOM
1814 // Up to 256 bytes, a read off /dev/urandom will not be interrupted.
1815 // blocking is moot here, O_NONBLOCK has no effect when opening /dev/urandom.
1816 uptr fd = internal_open("/dev/urandom", O_RDONLY00);
1817 if (internal_iserror(fd))
1818 return false;
1819 uptr res = internal_read(fd, buffer, length);
1820 if (internal_iserror(res))
1821 return false;
1822 internal_close(fd);
1823 return true;
1824}
1825
1826} // namespace __sanitizer
1827
1828#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD