1 //===-- sanitizer_linux.cc ------------------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is shared between AddressSanitizer and ThreadSanitizer
9 // run-time libraries and implements linux-specific functions from
11 //===----------------------------------------------------------------------===//
13 #include "sanitizer_platform.h"
16 #include "sanitizer_common.h"
17 #include "sanitizer_internal_defs.h"
18 #include "sanitizer_libc.h"
19 #include "sanitizer_linux.h"
20 #include "sanitizer_mutex.h"
21 #include "sanitizer_placement_new.h"
22 #include "sanitizer_procmaps.h"
23 #include "sanitizer_stacktrace.h"
24 #include "sanitizer_symbolizer.h"
26 #include <asm/param.h>
30 #if !SANITIZER_ANDROID
36 #include <sys/ptrace.h>
37 #include <sys/resource.h>
39 #include <sys/syscall.h>
41 #include <sys/types.h>
45 #if !SANITIZER_ANDROID
46 #include <sys/signal.h>
50 struct kernel_timeval
{
55 // <linux/futex.h> is broken on some linux distributions.
56 const int FUTEX_WAIT
= 0;
57 const int FUTEX_WAKE
= 1;
59 // Are we using 32-bit or 64-bit syscalls?
60 // x32 (which defines __x86_64__) has SANITIZER_WORDSIZE == 32
61 // but it still needs to use 64-bit syscalls.
62 #if defined(__x86_64__) || SANITIZER_WORDSIZE == 64
63 # define SANITIZER_LINUX_USES_64BIT_SYSCALLS 1
65 # define SANITIZER_LINUX_USES_64BIT_SYSCALLS 0
68 namespace __sanitizer
{
71 #include "sanitizer_syscall_linux_x86_64.inc"
73 #include "sanitizer_syscall_generic.inc"
76 // --------------- sanitizer_libc.h
77 uptr
internal_mmap(void *addr
, uptr length
, int prot
, int flags
,
79 #if SANITIZER_LINUX_USES_64BIT_SYSCALLS
80 return internal_syscall(__NR_mmap
, (uptr
)addr
, length
, prot
, flags
, fd
,
83 return internal_syscall(__NR_mmap2
, addr
, length
, prot
, flags
, fd
, offset
);
87 uptr
internal_munmap(void *addr
, uptr length
) {
88 return internal_syscall(__NR_munmap
, (uptr
)addr
, length
);
91 uptr
internal_close(fd_t fd
) {
92 return internal_syscall(__NR_close
, fd
);
95 uptr
internal_open(const char *filename
, int flags
) {
96 return internal_syscall(__NR_open
, (uptr
)filename
, flags
);
99 uptr
internal_open(const char *filename
, int flags
, u32 mode
) {
100 return internal_syscall(__NR_open
, (uptr
)filename
, flags
, mode
);
103 uptr
OpenFile(const char *filename
, bool write
) {
104 return internal_open(filename
,
105 write
? O_WRONLY
| O_CREAT
/*| O_CLOEXEC*/ : O_RDONLY
, 0660);
108 uptr
internal_read(fd_t fd
, void *buf
, uptr count
) {
110 HANDLE_EINTR(res
, (sptr
)internal_syscall(__NR_read
, fd
, (uptr
)buf
, count
));
114 uptr
internal_write(fd_t fd
, const void *buf
, uptr count
) {
116 HANDLE_EINTR(res
, (sptr
)internal_syscall(__NR_write
, fd
, (uptr
)buf
, count
));
120 #if !SANITIZER_LINUX_USES_64BIT_SYSCALLS
121 static void stat64_to_stat(struct stat64
*in
, struct stat
*out
) {
122 internal_memset(out
, 0, sizeof(*out
));
123 out
->st_dev
= in
->st_dev
;
124 out
->st_ino
= in
->st_ino
;
125 out
->st_mode
= in
->st_mode
;
126 out
->st_nlink
= in
->st_nlink
;
127 out
->st_uid
= in
->st_uid
;
128 out
->st_gid
= in
->st_gid
;
129 out
->st_rdev
= in
->st_rdev
;
130 out
->st_size
= in
->st_size
;
131 out
->st_blksize
= in
->st_blksize
;
132 out
->st_blocks
= in
->st_blocks
;
133 out
->st_atime
= in
->st_atime
;
134 out
->st_mtime
= in
->st_mtime
;
135 out
->st_ctime
= in
->st_ctime
;
136 out
->st_ino
= in
->st_ino
;
140 uptr
internal_stat(const char *path
, void *buf
) {
141 #if SANITIZER_LINUX_USES_64BIT_SYSCALLS
142 return internal_syscall(__NR_stat
, (uptr
)path
, (uptr
)buf
);
145 int res
= internal_syscall(__NR_stat64
, path
, &buf64
);
146 stat64_to_stat(&buf64
, (struct stat
*)buf
);
151 uptr
internal_lstat(const char *path
, void *buf
) {
152 #if SANITIZER_LINUX_USES_64BIT_SYSCALLS
153 return internal_syscall(__NR_lstat
, (uptr
)path
, (uptr
)buf
);
156 int res
= internal_syscall(__NR_lstat64
, path
, &buf64
);
157 stat64_to_stat(&buf64
, (struct stat
*)buf
);
162 uptr
internal_fstat(fd_t fd
, void *buf
) {
163 #if SANITIZER_LINUX_USES_64BIT_SYSCALLS
164 return internal_syscall(__NR_fstat
, fd
, (uptr
)buf
);
167 int res
= internal_syscall(__NR_fstat64
, fd
, &buf64
);
168 stat64_to_stat(&buf64
, (struct stat
*)buf
);
173 uptr
internal_filesize(fd_t fd
) {
175 if (internal_fstat(fd
, &st
))
177 return (uptr
)st
.st_size
;
180 uptr
internal_dup2(int oldfd
, int newfd
) {
181 return internal_syscall(__NR_dup2
, oldfd
, newfd
);
184 uptr
internal_readlink(const char *path
, char *buf
, uptr bufsize
) {
185 return internal_syscall(__NR_readlink
, (uptr
)path
, (uptr
)buf
, bufsize
);
188 uptr
internal_unlink(const char *path
) {
189 return internal_syscall(__NR_unlink
, (uptr
)path
);
192 uptr
internal_sched_yield() {
193 return internal_syscall(__NR_sched_yield
);
196 void internal__exit(int exitcode
) {
197 internal_syscall(__NR_exit_group
, exitcode
);
198 Die(); // Unreachable.
201 uptr
internal_execve(const char *filename
, char *const argv
[],
202 char *const envp
[]) {
203 return internal_syscall(__NR_execve
, (uptr
)filename
, (uptr
)argv
, (uptr
)envp
);
206 // ----------------- sanitizer_common.h
207 bool FileExists(const char *filename
) {
209 if (internal_stat(filename
, &st
))
211 // Sanity check: filename is a regular file.
212 return S_ISREG(st
.st_mode
);
216 return internal_syscall(__NR_gettid
);
221 internal_memset(&tv
, 0, sizeof(tv
));
222 internal_syscall(__NR_gettimeofday
, (uptr
)&tv
, 0);
223 return (u64
)tv
.tv_sec
* 1000*1000*1000 + tv
.tv_usec
* 1000;
226 // Like getenv, but reads env directly from /proc and does not use libc.
227 // This function should be called first inside __asan_init.
228 const char *GetEnv(const char *name
) {
229 static char *environ
;
235 len
= ReadFileToBuffer("/proc/self/environ",
236 &environ
, &environ_size
, 1 << 26);
238 if (!environ
|| len
== 0) return 0;
239 uptr namelen
= internal_strlen(name
);
240 const char *p
= environ
;
241 while (*p
!= '\0') { // will happen at the \0\0 that terminates the buffer
242 // proc file has the format NAME=value\0NAME=value\0NAME=value\0...
244 (char*)internal_memchr(p
, '\0', len
- (p
- environ
));
245 if (endp
== 0) // this entry isn't NUL terminated
247 else if (!internal_memcmp(p
, name
, namelen
) && p
[namelen
] == '=') // Match.
248 return p
+ namelen
+ 1; // point after =
251 return 0; // Not found.
255 SANITIZER_WEAK_ATTRIBUTE
extern void *__libc_stack_end
;
259 static void ReadNullSepFileToArray(const char *path
, char ***arr
,
263 *arr
= (char **)MmapOrDie(arr_size
* sizeof(char *), "NullSepFileArray");
264 ReadFileToBuffer(path
, &buff
, &buff_size
, 1024 * 1024);
267 for (count
= 1, i
= 1; ; i
++) {
269 if (buff
[i
+1] == 0) break;
270 (*arr
)[count
] = &buff
[i
+1];
271 CHECK_LE(count
, arr_size
- 1); // FIXME: make this more flexible.
279 static void GetArgsAndEnv(char*** argv
, char*** envp
) {
281 if (&__libc_stack_end
) {
283 uptr
* stack_end
= (uptr
*)__libc_stack_end
;
284 int argc
= *stack_end
;
285 *argv
= (char**)(stack_end
+ 1);
286 *envp
= (char**)(stack_end
+ argc
+ 2);
289 static const int kMaxArgv
= 2000, kMaxEnvp
= 2000;
290 ReadNullSepFileToArray("/proc/self/cmdline", argv
, kMaxArgv
);
291 ReadNullSepFileToArray("/proc/self/environ", envp
, kMaxEnvp
);
298 GetArgsAndEnv(&argv
, &envp
);
299 uptr rv
= internal_execve("/proc/self/exe", argv
, envp
);
301 CHECK_EQ(internal_iserror(rv
, &rverrno
), true);
302 Printf("execve failed, errno %d\n", rverrno
);
306 void PrepareForSandboxing() {
307 // Some kinds of sandboxes may forbid filesystem access, so we won't be able
308 // to read the file mappings from /proc/self/maps. Luckily, neither the
309 // process will be able to load additional libraries, so it's fine to use the
311 MemoryMappingLayout::CacheMemoryMappings();
312 // Same for /proc/self/exe in the symbolizer.
314 if (Symbolizer
*sym
= Symbolizer::GetOrNull())
315 sym
->PrepareForSandboxing();
319 // ----------------- sanitizer_procmaps.h
320 // Linker initialized.
321 ProcSelfMapsBuff
MemoryMappingLayout::cached_proc_self_maps_
;
322 StaticSpinMutex
MemoryMappingLayout::cache_lock_
; // Linker initialized.
324 MemoryMappingLayout::MemoryMappingLayout(bool cache_enabled
) {
325 proc_self_maps_
.len
=
326 ReadFileToBuffer("/proc/self/maps", &proc_self_maps_
.data
,
327 &proc_self_maps_
.mmaped_size
, 1 << 26);
329 if (proc_self_maps_
.mmaped_size
== 0) {
331 CHECK_GT(proc_self_maps_
.len
, 0);
334 CHECK_GT(proc_self_maps_
.mmaped_size
, 0);
337 // FIXME: in the future we may want to cache the mappings on demand only.
339 CacheMemoryMappings();
342 MemoryMappingLayout::~MemoryMappingLayout() {
343 // Only unmap the buffer if it is different from the cached one. Otherwise
344 // it will be unmapped when the cache is refreshed.
345 if (proc_self_maps_
.data
!= cached_proc_self_maps_
.data
) {
346 UnmapOrDie(proc_self_maps_
.data
, proc_self_maps_
.mmaped_size
);
350 void MemoryMappingLayout::Reset() {
351 current_
= proc_self_maps_
.data
;
355 void MemoryMappingLayout::CacheMemoryMappings() {
356 SpinMutexLock
l(&cache_lock_
);
357 // Don't invalidate the cache if the mappings are unavailable.
358 ProcSelfMapsBuff old_proc_self_maps
;
359 old_proc_self_maps
= cached_proc_self_maps_
;
360 cached_proc_self_maps_
.len
=
361 ReadFileToBuffer("/proc/self/maps", &cached_proc_self_maps_
.data
,
362 &cached_proc_self_maps_
.mmaped_size
, 1 << 26);
363 if (cached_proc_self_maps_
.mmaped_size
== 0) {
364 cached_proc_self_maps_
= old_proc_self_maps
;
366 if (old_proc_self_maps
.mmaped_size
) {
367 UnmapOrDie(old_proc_self_maps
.data
,
368 old_proc_self_maps
.mmaped_size
);
373 void MemoryMappingLayout::LoadFromCache() {
374 SpinMutexLock
l(&cache_lock_
);
375 if (cached_proc_self_maps_
.data
) {
376 proc_self_maps_
= cached_proc_self_maps_
;
380 // Parse a hex value in str and update str.
381 static uptr
ParseHex(char **str
) {
384 for (s
= *str
; ; s
++) {
387 if (c
>= '0' && c
<= '9')
389 else if (c
>= 'a' && c
<= 'f')
391 else if (c
>= 'A' && c
<= 'F')
401 static bool IsOneOf(char c
, char c1
, char c2
) {
402 return c
== c1
|| c
== c2
;
405 static bool IsDecimal(char c
) {
406 return c
>= '0' && c
<= '9';
409 static bool IsHex(char c
) {
410 return (c
>= '0' && c
<= '9')
411 || (c
>= 'a' && c
<= 'f');
414 static uptr
ReadHex(const char *p
) {
416 for (; IsHex(p
[0]); p
++) {
417 if (p
[0] >= '0' && p
[0] <= '9')
418 v
= v
* 16 + p
[0] - '0';
420 v
= v
* 16 + p
[0] - 'a' + 10;
425 static uptr
ReadDecimal(const char *p
) {
427 for (; IsDecimal(p
[0]); p
++)
428 v
= v
* 10 + p
[0] - '0';
433 bool MemoryMappingLayout::Next(uptr
*start
, uptr
*end
, uptr
*offset
,
434 char filename
[], uptr filename_size
,
436 char *last
= proc_self_maps_
.data
+ proc_self_maps_
.len
;
437 if (current_
>= last
) return false;
439 if (!start
) start
= &dummy
;
440 if (!end
) end
= &dummy
;
441 if (!offset
) offset
= &dummy
;
442 char *next_line
= (char*)internal_memchr(current_
, '\n', last
- current_
);
445 // Example: 08048000-08056000 r-xp 00000000 03:0c 64593 /foo/bar
446 *start
= ParseHex(¤t_
);
447 CHECK_EQ(*current_
++, '-');
448 *end
= ParseHex(¤t_
);
449 CHECK_EQ(*current_
++, ' ');
450 uptr local_protection
= 0;
451 CHECK(IsOneOf(*current_
, '-', 'r'));
452 if (*current_
++ == 'r')
453 local_protection
|= kProtectionRead
;
454 CHECK(IsOneOf(*current_
, '-', 'w'));
455 if (*current_
++ == 'w')
456 local_protection
|= kProtectionWrite
;
457 CHECK(IsOneOf(*current_
, '-', 'x'));
458 if (*current_
++ == 'x')
459 local_protection
|= kProtectionExecute
;
460 CHECK(IsOneOf(*current_
, 's', 'p'));
461 if (*current_
++ == 's')
462 local_protection
|= kProtectionShared
;
464 *protection
= local_protection
;
466 CHECK_EQ(*current_
++, ' ');
467 *offset
= ParseHex(¤t_
);
468 CHECK_EQ(*current_
++, ' ');
470 CHECK_EQ(*current_
++, ':');
472 CHECK_EQ(*current_
++, ' ');
473 while (IsDecimal(*current_
))
475 // Qemu may lack the trailing space.
476 // http://code.google.com/p/address-sanitizer/issues/detail?id=160
477 // CHECK_EQ(*current_++, ' ');
479 while (current_
< next_line
&& *current_
== ' ')
481 // Fill in the filename.
483 while (current_
< next_line
) {
484 if (filename
&& i
< filename_size
- 1)
485 filename
[i
++] = *current_
;
488 if (filename
&& i
< filename_size
)
490 current_
= next_line
+ 1;
494 // Gets the object name and the offset by walking MemoryMappingLayout.
495 bool MemoryMappingLayout::GetObjectNameAndOffset(uptr addr
, uptr
*offset
,
499 return IterateForObjectNameAndOffset(addr
, offset
, filename
, filename_size
,
503 void GetMemoryProfile(fill_profile_f cb
, uptr
*stats
, uptr stats_size
) {
506 uptr smaps_len
= ReadFileToBuffer("/proc/self/smaps",
507 &smaps
, &smaps_cap
, 64<<20);
510 const char *pos
= smaps
;
511 while (pos
< smaps
+ smaps_len
) {
513 start
= ReadHex(pos
);
514 for (; *pos
!= '/' && *pos
> '\n'; pos
++) {}
516 } else if (internal_strncmp(pos
, "Rss:", 4) == 0) {
517 for (; *pos
< '0' || *pos
> '9'; pos
++) {}
518 uptr rss
= ReadDecimal(pos
) * 1024;
519 cb(start
, rss
, file
, stats
, stats_size
);
521 while (*pos
++ != '\n') {}
523 UnmapOrDie(smaps
, smaps_cap
);
532 BlockingMutex::BlockingMutex(LinkerInitialized
) {
536 BlockingMutex::BlockingMutex() {
537 internal_memset(this, 0, sizeof(*this));
540 void BlockingMutex::Lock() {
541 atomic_uint32_t
*m
= reinterpret_cast<atomic_uint32_t
*>(&opaque_storage_
);
542 if (atomic_exchange(m
, MtxLocked
, memory_order_acquire
) == MtxUnlocked
)
544 while (atomic_exchange(m
, MtxSleeping
, memory_order_acquire
) != MtxUnlocked
)
545 internal_syscall(__NR_futex
, (uptr
)m
, FUTEX_WAIT
, MtxSleeping
, 0, 0, 0);
548 void BlockingMutex::Unlock() {
549 atomic_uint32_t
*m
= reinterpret_cast<atomic_uint32_t
*>(&opaque_storage_
);
550 u32 v
= atomic_exchange(m
, MtxUnlocked
, memory_order_relaxed
);
551 CHECK_NE(v
, MtxUnlocked
);
552 if (v
== MtxSleeping
)
553 internal_syscall(__NR_futex
, (uptr
)m
, FUTEX_WAKE
, 1, 0, 0, 0);
556 void BlockingMutex::CheckLocked() {
557 atomic_uint32_t
*m
= reinterpret_cast<atomic_uint32_t
*>(&opaque_storage_
);
558 CHECK_NE(MtxUnlocked
, atomic_load(m
, memory_order_relaxed
));
561 // ----------------- sanitizer_linux.h
562 // The actual size of this structure is specified by d_reclen.
563 // Note that getdents64 uses a different structure format. We only provide the
564 // 32-bit syscall here.
565 struct linux_dirent
{
568 unsigned short d_reclen
;
573 uptr
internal_ptrace(int request
, int pid
, void *addr
, void *data
) {
574 return internal_syscall(__NR_ptrace
, request
, pid
, (uptr
)addr
, (uptr
)data
);
577 uptr
internal_waitpid(int pid
, int *status
, int options
) {
578 return internal_syscall(__NR_wait4
, pid
, (uptr
)status
, options
,
582 uptr
internal_getpid() {
583 return internal_syscall(__NR_getpid
);
586 uptr
internal_getppid() {
587 return internal_syscall(__NR_getppid
);
590 uptr
internal_getdents(fd_t fd
, struct linux_dirent
*dirp
, unsigned int count
) {
591 return internal_syscall(__NR_getdents
, fd
, (uptr
)dirp
, count
);
594 uptr
internal_lseek(fd_t fd
, OFF_T offset
, int whence
) {
595 return internal_syscall(__NR_lseek
, fd
, offset
, whence
);
598 uptr
internal_prctl(int option
, uptr arg2
, uptr arg3
, uptr arg4
, uptr arg5
) {
599 return internal_syscall(__NR_prctl
, option
, arg2
, arg3
, arg4
, arg5
);
602 uptr
internal_sigaltstack(const struct sigaltstack
*ss
,
603 struct sigaltstack
*oss
) {
604 return internal_syscall(__NR_sigaltstack
, (uptr
)ss
, (uptr
)oss
);
607 uptr
internal_sigaction(int signum
, const __sanitizer_kernel_sigaction_t
*act
,
608 __sanitizer_kernel_sigaction_t
*oldact
) {
609 return internal_syscall(__NR_rt_sigaction
, signum
, act
, oldact
,
610 sizeof(__sanitizer_kernel_sigset_t
));
613 uptr
internal_sigprocmask(int how
, __sanitizer_kernel_sigset_t
*set
,
614 __sanitizer_kernel_sigset_t
*oldset
) {
615 return internal_syscall(__NR_rt_sigprocmask
, (uptr
)how
, &set
->sig
[0],
616 &oldset
->sig
[0], sizeof(__sanitizer_kernel_sigset_t
));
619 void internal_sigfillset(__sanitizer_kernel_sigset_t
*set
) {
620 internal_memset(set
, 0xff, sizeof(*set
));
623 void internal_sigdelset(__sanitizer_kernel_sigset_t
*set
, int signum
) {
626 CHECK_LT(signum
, sizeof(*set
) * 8);
627 const uptr idx
= signum
/ (sizeof(set
->sig
[0]) * 8);
628 const uptr bit
= signum
% (sizeof(set
->sig
[0]) * 8);
629 set
->sig
[idx
] &= ~(1 << bit
);
632 // ThreadLister implementation.
633 ThreadLister::ThreadLister(int pid
)
638 entry_((struct linux_dirent
*)buffer_
.data()),
640 char task_directory_path
[80];
641 internal_snprintf(task_directory_path
, sizeof(task_directory_path
),
642 "/proc/%d/task/", pid
);
643 uptr openrv
= internal_open(task_directory_path
, O_RDONLY
| O_DIRECTORY
);
644 if (internal_iserror(openrv
)) {
646 Report("Can't open /proc/%d/task for reading.\n", pid
);
649 descriptor_
= openrv
;
653 int ThreadLister::GetNextTID() {
658 if ((char *)entry_
>= &buffer_
[bytes_read_
] && !GetDirectoryEntries())
660 if (entry_
->d_ino
!= 0 && entry_
->d_name
[0] >= '0' &&
661 entry_
->d_name
[0] <= '9') {
662 // Found a valid tid.
663 tid
= (int)internal_atoll(entry_
->d_name
);
665 entry_
= (struct linux_dirent
*)(((char *)entry_
) + entry_
->d_reclen
);
670 void ThreadLister::Reset() {
671 if (error_
|| descriptor_
< 0)
673 internal_lseek(descriptor_
, 0, SEEK_SET
);
676 ThreadLister::~ThreadLister() {
677 if (descriptor_
>= 0)
678 internal_close(descriptor_
);
681 bool ThreadLister::error() { return error_
; }
683 bool ThreadLister::GetDirectoryEntries() {
684 CHECK_GE(descriptor_
, 0);
685 CHECK_NE(error_
, true);
686 bytes_read_
= internal_getdents(descriptor_
,
687 (struct linux_dirent
*)buffer_
.data(),
689 if (internal_iserror(bytes_read_
)) {
690 Report("Can't read directory entries from /proc/%d/task.\n", pid_
);
693 } else if (bytes_read_
== 0) {
696 entry_
= (struct linux_dirent
*)buffer_
.data();
701 #if defined(__x86_64__) || defined(__i386__)
702 return EXEC_PAGESIZE
;
704 return sysconf(_SC_PAGESIZE
); // EXEC_PAGESIZE may not be trustworthy.
708 static char proc_self_exe_cache_str
[kMaxPathLength
];
709 static uptr proc_self_exe_cache_len
= 0;
711 uptr
ReadBinaryName(/*out*/char *buf
, uptr buf_len
) {
712 uptr module_name_len
= internal_readlink(
713 "/proc/self/exe", buf
, buf_len
);
715 if (internal_iserror(module_name_len
, &readlink_error
)) {
716 if (proc_self_exe_cache_len
) {
717 // If available, use the cached module name.
718 CHECK_LE(proc_self_exe_cache_len
, buf_len
);
719 internal_strncpy(buf
, proc_self_exe_cache_str
, buf_len
);
720 module_name_len
= internal_strlen(proc_self_exe_cache_str
);
722 // We can't read /proc/self/exe for some reason, assume the name of the
723 // binary is unknown.
724 Report("WARNING: readlink(\"/proc/self/exe\") failed with errno %d, "
725 "some stack frames may not be symbolized\n", readlink_error
);
726 module_name_len
= internal_snprintf(buf
, buf_len
, "/proc/self/exe");
728 CHECK_LT(module_name_len
, buf_len
);
729 buf
[module_name_len
] = '\0';
731 return module_name_len
;
734 void CacheBinaryName() {
735 if (!proc_self_exe_cache_len
) {
736 proc_self_exe_cache_len
=
737 ReadBinaryName(proc_self_exe_cache_str
, kMaxPathLength
);
741 // Match full names of the form /path/to/base_name{-,.}*
742 bool LibraryNameIs(const char *full_name
, const char *base_name
) {
743 const char *name
= full_name
;
745 while (*name
!= '\0') name
++;
746 while (name
> full_name
&& *name
!= '/') name
--;
747 if (*name
== '/') name
++;
748 uptr base_name_length
= internal_strlen(base_name
);
749 if (internal_strncmp(name
, base_name
, base_name_length
)) return false;
750 return (name
[base_name_length
] == '-' || name
[base_name_length
] == '.');
753 #if !SANITIZER_ANDROID
754 // Call cb for each region mapped by map.
755 void ForEachMappedRegion(link_map
*map
, void (*cb
)(const void *, uptr
)) {
756 typedef ElfW(Phdr
) Elf_Phdr
;
757 typedef ElfW(Ehdr
) Elf_Ehdr
;
758 char *base
= (char *)map
->l_addr
;
759 Elf_Ehdr
*ehdr
= (Elf_Ehdr
*)base
;
760 char *phdrs
= base
+ ehdr
->e_phoff
;
761 char *phdrs_end
= phdrs
+ ehdr
->e_phnum
* ehdr
->e_phentsize
;
763 // Find the segment with the minimum base so we can "relocate" the p_vaddr
764 // fields. Typically ET_DYN objects (DSOs) have base of zero and ET_EXEC
765 // objects have a non-zero base.
766 uptr preferred_base
= (uptr
)-1;
767 for (char *iter
= phdrs
; iter
!= phdrs_end
; iter
+= ehdr
->e_phentsize
) {
768 Elf_Phdr
*phdr
= (Elf_Phdr
*)iter
;
769 if (phdr
->p_type
== PT_LOAD
&& preferred_base
> (uptr
)phdr
->p_vaddr
)
770 preferred_base
= (uptr
)phdr
->p_vaddr
;
773 // Compute the delta from the real base to get a relocation delta.
774 sptr delta
= (uptr
)base
- preferred_base
;
775 // Now we can figure out what the loader really mapped.
776 for (char *iter
= phdrs
; iter
!= phdrs_end
; iter
+= ehdr
->e_phentsize
) {
777 Elf_Phdr
*phdr
= (Elf_Phdr
*)iter
;
778 if (phdr
->p_type
== PT_LOAD
) {
779 uptr seg_start
= phdr
->p_vaddr
+ delta
;
780 uptr seg_end
= seg_start
+ phdr
->p_memsz
;
781 // None of these values are aligned. We consider the ragged edges of the
782 // load command as defined, since they are mapped from the file.
783 seg_start
= RoundDownTo(seg_start
, GetPageSizeCached());
784 seg_end
= RoundUpTo(seg_end
, GetPageSizeCached());
785 cb((void *)seg_start
, seg_end
- seg_start
);
791 #if defined(__x86_64__)
792 // We cannot use glibc's clone wrapper, because it messes with the child
793 // task's TLS. It writes the PID and TID of the child task to its thread
794 // descriptor, but in our case the child task shares the thread descriptor with
795 // the parent (because we don't know how to allocate a new thread
796 // descriptor to keep glibc happy). So the stock version of clone(), when
797 // used with CLONE_VM, would end up corrupting the parent's thread descriptor.
798 uptr
internal_clone(int (*fn
)(void *), void *child_stack
, int flags
, void *arg
,
799 int *parent_tidptr
, void *newtls
, int *child_tidptr
) {
801 if (!fn
|| !child_stack
)
803 CHECK_EQ(0, (uptr
)child_stack
% 16);
804 child_stack
= (char *)child_stack
- 2 * sizeof(unsigned long long);
805 ((unsigned long long *)child_stack
)[0] = (uptr
)fn
;
806 ((unsigned long long *)child_stack
)[1] = (uptr
)arg
;
807 register void *r8
__asm__("r8") = newtls
;
808 register int *r10
__asm__("r10") = child_tidptr
;
809 __asm__
__volatile__(
810 /* %rax = syscall(%rax = __NR_clone,
812 * %rsi = child_stack,
813 * %rdx = parent_tidptr,
815 * %r10 = child_tidptr)
822 "testq %%rax,%%rax\n"
825 /* In the child. Terminate unwind chain. */
826 // XXX: We should also terminate the CFI unwind chain
827 // here. Unfortunately clang 3.2 doesn't support the
828 // necessary CFI directives, so we skip that part.
831 /* Call "fn(arg)". */
836 /* Call _exit(%rax). */
841 /* Return to parent. */
844 : "a"(__NR_clone
), "i"(__NR_exit
),
850 : "rsp", "memory", "r11", "rcx");
853 #endif // defined(__x86_64__)
854 } // namespace __sanitizer
856 #endif // SANITIZER_LINUX