sanitizer_posix.cc revision b78caa645f70eff2f037f1f8bb43ca9129dbd8d9
1//===-- sanitizer_posix.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 POSIX-specific functions from 12// sanitizer_libc.h. 13//===----------------------------------------------------------------------===// 14#if defined(__linux__) || defined(__APPLE__) 15 16#include "sanitizer_common.h" 17#include "sanitizer_libc.h" 18#include "sanitizer_procmaps.h" 19 20#include <pthread.h> 21#include <stdarg.h> 22#include <stdio.h> 23#include <stdlib.h> 24#include <sys/mman.h> 25#include <sys/resource.h> 26#include <sys/time.h> 27#include <sys/types.h> 28#include <unistd.h> 29 30namespace __sanitizer { 31 32// ------------- sanitizer_common.h 33 34int GetPid() { 35 return getpid(); 36} 37 38uptr GetThreadSelf() { 39 return (uptr)pthread_self(); 40} 41 42void *MmapOrDie(uptr size, const char *mem_type) { 43 size = RoundUpTo(size, kPageSize); 44 void *res = internal_mmap(0, size, 45 PROT_READ | PROT_WRITE, 46 MAP_PRIVATE | MAP_ANON, -1, 0); 47 if (res == (void*)-1) { 48 Report("ERROR: Failed to allocate 0x%zx (%zd) bytes of %s\n", 49 size, size, mem_type); 50 CHECK("unable to mmap" && 0); 51 } 52 return res; 53} 54 55void UnmapOrDie(void *addr, uptr size) { 56 if (!addr || !size) return; 57 int res = internal_munmap(addr, size); 58 if (res != 0) { 59 Report("ERROR: Failed to deallocate 0x%zx (%zd) bytes at address %p\n", 60 size, size, addr); 61 CHECK("unable to unmap" && 0); 62 } 63} 64 65void *MmapFixedNoReserve(uptr fixed_addr, uptr size) { 66 return internal_mmap((void*)fixed_addr, size, 67 PROT_READ | PROT_WRITE, 68 MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, 69 -1, 0); 70} 71 72void *Mprotect(uptr fixed_addr, uptr size) { 73 return internal_mmap((void*)fixed_addr, size, 74 PROT_NONE, 75 MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, 76 -1, 0); 77} 78 79void *MapFileToMemory(const char *file_name, uptr *buff_size) { 80 fd_t fd = internal_open(file_name, false); 81 CHECK_NE(fd, kInvalidFd); 82 uptr fsize = internal_filesize(fd); 83 CHECK_NE(fsize, (uptr)-1); 84 CHECK_GT(fsize, 0); 85 *buff_size = RoundUpTo(fsize, kPageSize); 86 void *map = internal_mmap(0, *buff_size, PROT_READ, MAP_PRIVATE, fd, 0); 87 return (map == MAP_FAILED) ? 0 : map; 88} 89 90 91static inline bool IntervalsAreSeparate(uptr start1, uptr end1, 92 uptr start2, uptr end2) { 93 CHECK(start1 <= end1); 94 CHECK(start2 <= end2); 95 return (end1 < start2) || (end2 < start1); 96} 97 98// FIXME: this is thread-unsafe, but should not cause problems most of the time. 99// When the shadow is mapped only a single thread usually exists (plus maybe 100// several worker threads on Mac, which aren't expected to map big chunks of 101// memory). 102bool MemoryRangeIsAvailable(uptr range_start, uptr range_end) { 103 ProcessMaps procmaps; 104 uptr start, end; 105 while (procmaps.Next(&start, &end, 106 /*offset*/0, /*filename*/0, /*filename_size*/0)) { 107 if (!IntervalsAreSeparate(start, end, range_start, range_end)) 108 return false; 109 } 110 return true; 111} 112 113void DumpProcessMap() { 114 ProcessMaps proc_maps; 115 uptr start, end; 116 const sptr kBufSize = 4095; 117 char *filename = (char*)MmapOrDie(kBufSize, __FUNCTION__); 118 Report("Process memory map follows:\n"); 119 while (proc_maps.Next(&start, &end, /* file_offset */0, 120 filename, kBufSize)) { 121 Printf("\t%p-%p\t%s\n", (void*)start, (void*)end, filename); 122 } 123 Report("End of process memory map.\n"); 124 UnmapOrDie(filename, kBufSize); 125} 126 127const char *GetPwd() { 128 return GetEnv("PWD"); 129} 130 131void DisableCoreDumper() { 132 struct rlimit nocore; 133 nocore.rlim_cur = 0; 134 nocore.rlim_max = 0; 135 setrlimit(RLIMIT_CORE, &nocore); 136} 137 138void SleepForSeconds(int seconds) { 139 sleep(seconds); 140} 141 142void SleepForMillis(int millis) { 143 usleep(millis * 1000); 144} 145 146void Exit(int exitcode) { 147 _exit(exitcode); 148} 149 150void Abort() { 151 abort(); 152} 153 154int Atexit(void (*function)(void)) { 155#ifndef SANITIZER_GO 156 return atexit(function); 157#else 158 return 0; 159#endif 160} 161 162} // namespace __sanitizer 163 164#endif // __linux__ || __APPLE_ 165