Bug Summary

File:projects/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc
Warning:line 375, column 3
Undefined or garbage value returned to caller

Annotated Source Code

[?] Use j/k keys for keyboard navigation

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