1251034Sed//===-- sanitizer_linux.h ---------------------------------------*- C++ -*-===// 2251034Sed// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6251034Sed// 7251034Sed//===----------------------------------------------------------------------===// 8251034Sed// 9251034Sed// Linux-specific syscall wrappers and classes. 10251034Sed// 11251034Sed//===----------------------------------------------------------------------===// 12251034Sed#ifndef SANITIZER_LINUX_H 13251034Sed#define SANITIZER_LINUX_H 14251034Sed 15274201Sdim#include "sanitizer_platform.h" 16341825Sdim#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ 17341825Sdim SANITIZER_OPENBSD || SANITIZER_SOLARIS 18251034Sed#include "sanitizer_common.h" 19251034Sed#include "sanitizer_internal_defs.h" 20344779Sdim#include "sanitizer_platform_limits_freebsd.h" 21327952Sdim#include "sanitizer_platform_limits_netbsd.h" 22341825Sdim#include "sanitizer_platform_limits_openbsd.h" 23327952Sdim#include "sanitizer_platform_limits_posix.h" 24327952Sdim#include "sanitizer_platform_limits_solaris.h" 25288943Sdim#include "sanitizer_posix.h" 26251034Sed 27274201Sdimstruct link_map; // Opaque type returned by dlopen(). 28251034Sed 29251034Sednamespace __sanitizer { 30251034Sed// Dirent structure for getdents(). Note that this structure is different from 31251034Sed// the one in <dirent.h>, which is used by readdir(). 32251034Sedstruct linux_dirent; 33251034Sed 34327952Sdimstruct ProcSelfMapsBuff { 35327952Sdim char *data; 36327952Sdim uptr mmaped_size; 37327952Sdim uptr len; 38327952Sdim}; 39327952Sdim 40327952Sdimstruct MemoryMappingLayoutData { 41327952Sdim ProcSelfMapsBuff proc_self_maps; 42327952Sdim const char *current; 43327952Sdim}; 44327952Sdim 45327952Sdimvoid ReadProcMaps(ProcSelfMapsBuff *proc_maps); 46327952Sdim 47251034Sed// Syscall wrappers. 48251034Seduptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count); 49321369Sdimuptr internal_sigaltstack(const void* ss, void* oss); 50276789Sdimuptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, 51276789Sdim __sanitizer_sigset_t *oldset); 52327952Sdimuptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp); 53251034Sed 54276789Sdim// Linux-only syscalls. 55276789Sdim#if SANITIZER_LINUX 56276789Sdimuptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5); 57276789Sdim// Used only by sanitizer_stoptheworld. Signal handlers that are actually used 58276789Sdim// (like the process-wide error reporting SEGV handler) must use 59276789Sdim// internal_sigaction instead. 60276789Sdimint internal_sigaction_norestorer(int signum, const void *act, void *oldact); 61276789Sdimvoid internal_sigdelset(__sanitizer_sigset_t *set, int signum); 62296417Sdim#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) \ 63321369Sdim || defined(__powerpc64__) || defined(__s390__) || defined(__i386__) \ 64321369Sdim || defined(__arm__) 65274201Sdimuptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, 66274201Sdim int *parent_tidptr, void *newtls, int *child_tidptr); 67274201Sdim#endif 68344779Sdim#elif SANITIZER_FREEBSD 69344779Sdimvoid internal_sigdelset(__sanitizer_sigset_t *set, int signum); 70353358Sdim#elif SANITIZER_NETBSD 71353358Sdimvoid internal_sigdelset(__sanitizer_sigset_t *set, int signum); 72353358Sdimuptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg); 73276789Sdim#endif // SANITIZER_LINUX 74274201Sdim 75251034Sed// This class reads thread IDs from /proc/<pid>/task using only syscalls. 76251034Sedclass ThreadLister { 77251034Sed public: 78341825Sdim explicit ThreadLister(pid_t pid); 79251034Sed ~ThreadLister(); 80341825Sdim enum Result { 81341825Sdim Error, 82341825Sdim Incomplete, 83341825Sdim Ok, 84341825Sdim }; 85341825Sdim Result ListThreads(InternalMmapVector<tid_t> *threads); 86251034Sed 87251034Sed private: 88341825Sdim bool IsAlive(int tid); 89251034Sed 90341825Sdim pid_t pid_; 91341825Sdim int descriptor_ = -1; 92341825Sdim InternalMmapVector<char> buffer_; 93251034Sed}; 94251034Sed 95251034Sed// Exposed for testing. 96251034Seduptr ThreadDescriptorSize(); 97274201Sdimuptr ThreadSelf(); 98274201Sdimuptr ThreadSelfOffset(); 99251034Sed 100251034Sed// Matches a library's file name against a base name (stripping path and version 101251034Sed// information). 102251034Sedbool LibraryNameIs(const char *full_name, const char *base_name); 103251034Sed 104274201Sdim// Call cb for each region mapped by map. 105274201Sdimvoid ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)); 106321369Sdim 107353358Sdim// Releases memory pages entirely within the [beg, end] address range. 108353358Sdim// The pages no longer count toward RSS; reads are guaranteed to return 0. 109353358Sdim// Requires (but does not verify!) that pages are MAP_PRIVATE. 110353358SdimINLINE void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) { 111353358Sdim // man madvise on Linux promises zero-fill for anonymous private pages. 112353358Sdim // Testing shows the same behaviour for private (but not anonymous) mappings 113353358Sdim // of shm_open() files, as long as the underlying file is untouched. 114353358Sdim CHECK(SANITIZER_LINUX); 115353358Sdim ReleaseMemoryPagesToOS(beg, end); 116353358Sdim} 117353358Sdim 118321369Sdim#if SANITIZER_ANDROID 119321369Sdim 120321369Sdim#if defined(__aarch64__) 121321369Sdim# define __get_tls() \ 122321369Sdim ({ void** __v; __asm__("mrs %0, tpidr_el0" : "=r"(__v)); __v; }) 123321369Sdim#elif defined(__arm__) 124321369Sdim# define __get_tls() \ 125321369Sdim ({ void** __v; __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(__v)); __v; }) 126321369Sdim#elif defined(__mips__) 127321369Sdim// On mips32r1, this goes via a kernel illegal instruction trap that's 128321369Sdim// optimized for v1. 129321369Sdim# define __get_tls() \ 130321369Sdim ({ register void** __v asm("v1"); \ 131321369Sdim __asm__(".set push\n" \ 132321369Sdim ".set mips32r2\n" \ 133321369Sdim "rdhwr %0,$29\n" \ 134321369Sdim ".set pop\n" : "=r"(__v)); \ 135321369Sdim __v; }) 136321369Sdim#elif defined(__i386__) 137321369Sdim# define __get_tls() \ 138321369Sdim ({ void** __v; __asm__("movl %%gs:0, %0" : "=r"(__v)); __v; }) 139321369Sdim#elif defined(__x86_64__) 140321369Sdim# define __get_tls() \ 141321369Sdim ({ void** __v; __asm__("mov %%fs:0, %0" : "=r"(__v)); __v; }) 142321369Sdim#else 143321369Sdim#error "Unsupported architecture." 144321369Sdim#endif 145321369Sdim 146344779Sdim// The Android Bionic team has allocated a TLS slot for sanitizers starting 147344779Sdim// with Q, given that Android currently doesn't support ELF TLS. It is used to 148344779Sdim// store sanitizer thread specific data. 149344779Sdimstatic const int TLS_SLOT_SANITIZER = 6; 150321369Sdim 151321369SdimALWAYS_INLINE uptr *get_android_tls_ptr() { 152344779Sdim return reinterpret_cast<uptr *>(&__get_tls()[TLS_SLOT_SANITIZER]); 153321369Sdim} 154321369Sdim 155321369Sdim#endif // SANITIZER_ANDROID 156321369Sdim 157251034Sed} // namespace __sanitizer 158251034Sed 159341825Sdim#endif 160251034Sed#endif // SANITIZER_LINUX_H 161