1*7c3d14c8STreehugger Robot //===-- sanitizer_linux.h ---------------------------------------*- C++ -*-===// 2*7c3d14c8STreehugger Robot // 3*7c3d14c8STreehugger Robot // The LLVM Compiler Infrastructure 4*7c3d14c8STreehugger Robot // 5*7c3d14c8STreehugger Robot // This file is distributed under the University of Illinois Open Source 6*7c3d14c8STreehugger Robot // License. See LICENSE.TXT for details. 7*7c3d14c8STreehugger Robot // 8*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===// 9*7c3d14c8STreehugger Robot // 10*7c3d14c8STreehugger Robot // Linux-specific syscall wrappers and classes. 11*7c3d14c8STreehugger Robot // 12*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===// 13*7c3d14c8STreehugger Robot #ifndef SANITIZER_LINUX_H 14*7c3d14c8STreehugger Robot #define SANITIZER_LINUX_H 15*7c3d14c8STreehugger Robot 16*7c3d14c8STreehugger Robot #include "sanitizer_platform.h" 17*7c3d14c8STreehugger Robot #if SANITIZER_FREEBSD || SANITIZER_LINUX 18*7c3d14c8STreehugger Robot #include "sanitizer_common.h" 19*7c3d14c8STreehugger Robot #include "sanitizer_internal_defs.h" 20*7c3d14c8STreehugger Robot #include "sanitizer_posix.h" 21*7c3d14c8STreehugger Robot #include "sanitizer_platform_limits_posix.h" 22*7c3d14c8STreehugger Robot 23*7c3d14c8STreehugger Robot struct link_map; // Opaque type returned by dlopen(). 24*7c3d14c8STreehugger Robot struct sigaltstack; 25*7c3d14c8STreehugger Robot 26*7c3d14c8STreehugger Robot namespace __sanitizer { 27*7c3d14c8STreehugger Robot // Dirent structure for getdents(). Note that this structure is different from 28*7c3d14c8STreehugger Robot // the one in <dirent.h>, which is used by readdir(). 29*7c3d14c8STreehugger Robot struct linux_dirent; 30*7c3d14c8STreehugger Robot 31*7c3d14c8STreehugger Robot // Syscall wrappers. 32*7c3d14c8STreehugger Robot uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count); 33*7c3d14c8STreehugger Robot uptr internal_sigaltstack(const struct sigaltstack* ss, 34*7c3d14c8STreehugger Robot struct sigaltstack* oss); 35*7c3d14c8STreehugger Robot uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, 36*7c3d14c8STreehugger Robot __sanitizer_sigset_t *oldset); 37*7c3d14c8STreehugger Robot 38*7c3d14c8STreehugger Robot // Linux-only syscalls. 39*7c3d14c8STreehugger Robot #if SANITIZER_LINUX 40*7c3d14c8STreehugger Robot uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5); 41*7c3d14c8STreehugger Robot // Used only by sanitizer_stoptheworld. Signal handlers that are actually used 42*7c3d14c8STreehugger Robot // (like the process-wide error reporting SEGV handler) must use 43*7c3d14c8STreehugger Robot // internal_sigaction instead. 44*7c3d14c8STreehugger Robot int internal_sigaction_norestorer(int signum, const void *act, void *oldact); 45*7c3d14c8STreehugger Robot #if defined(__x86_64__) && !SANITIZER_GO 46*7c3d14c8STreehugger Robot // Uses a raw system call to avoid interceptors. 47*7c3d14c8STreehugger Robot int internal_sigaction_syscall(int signum, const void *act, void *oldact); 48*7c3d14c8STreehugger Robot #endif 49*7c3d14c8STreehugger Robot void internal_sigdelset(__sanitizer_sigset_t *set, int signum); 50*7c3d14c8STreehugger Robot #if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) \ 51*7c3d14c8STreehugger Robot || defined(__powerpc64__) || defined(__s390__) 52*7c3d14c8STreehugger Robot uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, 53*7c3d14c8STreehugger Robot int *parent_tidptr, void *newtls, int *child_tidptr); 54*7c3d14c8STreehugger Robot #endif 55*7c3d14c8STreehugger Robot #endif // SANITIZER_LINUX 56*7c3d14c8STreehugger Robot 57*7c3d14c8STreehugger Robot // This class reads thread IDs from /proc/<pid>/task using only syscalls. 58*7c3d14c8STreehugger Robot class ThreadLister { 59*7c3d14c8STreehugger Robot public: 60*7c3d14c8STreehugger Robot explicit ThreadLister(int pid); 61*7c3d14c8STreehugger Robot ~ThreadLister(); 62*7c3d14c8STreehugger Robot // GetNextTID returns -1 if the list of threads is exhausted, or if there has 63*7c3d14c8STreehugger Robot // been an error. 64*7c3d14c8STreehugger Robot int GetNextTID(); 65*7c3d14c8STreehugger Robot void Reset(); 66*7c3d14c8STreehugger Robot bool error(); 67*7c3d14c8STreehugger Robot 68*7c3d14c8STreehugger Robot private: 69*7c3d14c8STreehugger Robot bool GetDirectoryEntries(); 70*7c3d14c8STreehugger Robot 71*7c3d14c8STreehugger Robot int pid_; 72*7c3d14c8STreehugger Robot int descriptor_; 73*7c3d14c8STreehugger Robot InternalScopedBuffer<char> buffer_; 74*7c3d14c8STreehugger Robot bool error_; 75*7c3d14c8STreehugger Robot struct linux_dirent* entry_; 76*7c3d14c8STreehugger Robot int bytes_read_; 77*7c3d14c8STreehugger Robot }; 78*7c3d14c8STreehugger Robot 79*7c3d14c8STreehugger Robot // Exposed for testing. 80*7c3d14c8STreehugger Robot uptr ThreadDescriptorSize(); 81*7c3d14c8STreehugger Robot uptr ThreadSelf(); 82*7c3d14c8STreehugger Robot uptr ThreadSelfOffset(); 83*7c3d14c8STreehugger Robot 84*7c3d14c8STreehugger Robot // Matches a library's file name against a base name (stripping path and version 85*7c3d14c8STreehugger Robot // information). 86*7c3d14c8STreehugger Robot bool LibraryNameIs(const char *full_name, const char *base_name); 87*7c3d14c8STreehugger Robot 88*7c3d14c8STreehugger Robot // Call cb for each region mapped by map. 89*7c3d14c8STreehugger Robot void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)); 90*7c3d14c8STreehugger Robot } // namespace __sanitizer 91*7c3d14c8STreehugger Robot 92*7c3d14c8STreehugger Robot #endif // SANITIZER_FREEBSD || SANITIZER_LINUX 93*7c3d14c8STreehugger Robot #endif // SANITIZER_LINUX_H 94