sanitizer_posix.cc revision 0969bcf2c936126b1f6e636b978aade8fc207437
11f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//===-- sanitizer_posix.cc ------------------------------------------------===// 21f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// 31f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// The LLVM Compiler Infrastructure 41f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// 51f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// This file is distributed under the University of Illinois Open Source 61f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// License. See LICENSE.TXT for details. 71f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// 81f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//===----------------------------------------------------------------------===// 91f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// 101f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// This file is shared between AddressSanitizer and ThreadSanitizer 111f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// run-time libraries and implements POSIX-specific functions from 121f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov// sanitizer_libc.h. 131f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov//===----------------------------------------------------------------------===// 141f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov#if defined(__linux__) || defined(__APPLE__) 151f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov 16230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include "sanitizer_common.h" 171f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov#include "sanitizer_libc.h" 18be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov#include "sanitizer_procmaps.h" 191f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov 20fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov#include <pthread.h> 211f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov#include <stdarg.h> 221f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov#include <stdio.h> 23fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov#include <stdlib.h> 24230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include <sys/mman.h> 25be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov#include <sys/resource.h> 26be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov#include <sys/time.h> 27230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include <sys/types.h> 28230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include <unistd.h> 291f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov 304c49666e611f06241bb8462cea7674d877241492Alexey Samsonov#ifdef ANDROID 314c49666e611f06241bb8462cea7674d877241492Alexey Samsonov#include <sys/atomics.h> 324c49666e611f06241bb8462cea7674d877241492Alexey Samsonov#endif 334c49666e611f06241bb8462cea7674d877241492Alexey Samsonov 341f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonovnamespace __sanitizer { 351f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov 36be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov// ------------- sanitizer_common.h 37be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov 38230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovint GetPid() { 39230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov return getpid(); 40230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov} 41230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov 42fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovuptr GetThreadSelf() { 43fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov return (uptr)pthread_self(); 44fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov} 45fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov 46a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonovvoid *MmapOrDie(uptr size, const char *mem_type) { 47230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov size = RoundUpTo(size, kPageSize); 48230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov void *res = internal_mmap(0, size, 49230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov PROT_READ | PROT_WRITE, 50230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov MAP_PRIVATE | MAP_ANON, -1, 0); 51230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov if (res == (void*)-1) { 52a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov Report("ERROR: Failed to allocate 0x%zx (%zd) bytes of %s\n", 53a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov size, size, mem_type); 54a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov CHECK("unable to mmap" && 0); 55230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov } 56230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov return res; 57230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov} 58230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov 59230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovvoid UnmapOrDie(void *addr, uptr size) { 60230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov if (!addr || !size) return; 61230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov int res = internal_munmap(addr, size); 62230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov if (res != 0) { 63a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov Report("ERROR: Failed to deallocate 0x%zx (%zd) bytes at address %p\n", 64a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov size, size, addr); 65a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov CHECK("unable to unmap" && 0); 66230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov } 67230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov} 68230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov 69f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonovvoid *MmapFixedNoReserve(uptr fixed_addr, uptr size) { 70f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov return internal_mmap((void*)fixed_addr, size, 71f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov PROT_READ | PROT_WRITE, 72f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, 73f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov 0, 0); 74f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov} 75f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov 76f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonovvoid *Mprotect(uptr fixed_addr, uptr size) { 77f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov return internal_mmap((void*)fixed_addr, size, 78f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov PROT_NONE, 79f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, 80f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov 0, 0); 81f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov} 82f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov 83dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonovstatic inline bool IntervalsAreSeparate(uptr start1, uptr end1, 84dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov uptr start2, uptr end2) { 85dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov CHECK(start1 <= end1); 86dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov CHECK(start2 <= end2); 87dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov return (end1 < start2) || (end2 < start1); 88dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov} 89dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov 90dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov// FIXME: this is thread-unsafe, but should not cause problems most of the time. 91dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov// When the shadow is mapped only a single thread usually exists (plus maybe 92dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov// several worker threads on Mac, which aren't expected to map big chunks of 93dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov// memory). 94dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonovbool MemoryRangeIsAvailable(uptr range_start, uptr range_end) { 95dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov ProcessMaps procmaps; 96dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov uptr start, end; 97dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov while (procmaps.Next(&start, &end, 98dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov /*offset*/0, /*filename*/0, /*filename_size*/0)) { 99dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov if (!IntervalsAreSeparate(start, end, range_start, range_end)) 100dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov return false; 101dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov } 102dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov return true; 103dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov} 104dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov 105be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonovvoid DumpProcessMap() { 106be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov ProcessMaps proc_maps; 107be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov uptr start, end; 108be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov const sptr kBufSize = 4095; 109b84ee029ada36949c30c57c5f701191783990574Alexey Samsonov char *filename = (char*)MmapOrDie(kBufSize, __FUNCTION__); 110be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov Report("Process memory map follows:\n"); 111be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov while (proc_maps.Next(&start, &end, /* file_offset */0, 112be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov filename, kBufSize)) { 113be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov Printf("\t%p-%p\t%s\n", (void*)start, (void*)end, filename); 114be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov } 115be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov Report("End of process memory map.\n"); 116b84ee029ada36949c30c57c5f701191783990574Alexey Samsonov UnmapOrDie(filename, kBufSize); 117be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov} 118be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov 1190969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonovconst char *GetPwd() { 1200969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov return GetEnv("PWD"); 1210969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov} 1220969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov 123be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonovvoid DisableCoreDumper() { 124be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov struct rlimit nocore; 125be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov nocore.rlim_cur = 0; 126be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov nocore.rlim_max = 0; 127be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov setrlimit(RLIMIT_CORE, &nocore); 128be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov} 129be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov 130fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovvoid SleepForSeconds(int seconds) { 131fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov sleep(seconds); 132fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov} 133fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov 1340969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonovvoid SleepForMillis(int millis) { 1350969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov usleep(millis * 1000); 1360969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov} 1370969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov 138fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovvoid Exit(int exitcode) { 139fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov _exit(exitcode); 140fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov} 141fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov 142fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovvoid Abort() { 143fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov abort(); 144fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov} 145fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov 146fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovint Atexit(void (*function)(void)) { 147fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov return atexit(function); 148fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov} 149fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov 1504c49666e611f06241bb8462cea7674d877241492Alexey Samsonovint AtomicInc(int *a) { 1514c49666e611f06241bb8462cea7674d877241492Alexey Samsonov#ifdef ANDROID 1524c49666e611f06241bb8462cea7674d877241492Alexey Samsonov return __atomic_inc(a) + 1; 1534c49666e611f06241bb8462cea7674d877241492Alexey Samsonov#else 1544c49666e611f06241bb8462cea7674d877241492Alexey Samsonov return __sync_add_and_fetch(a, 1); 1554c49666e611f06241bb8462cea7674d877241492Alexey Samsonov#endif 1564c49666e611f06241bb8462cea7674d877241492Alexey Samsonov} 1574c49666e611f06241bb8462cea7674d877241492Alexey Samsonov 1584c49666e611f06241bb8462cea7674d877241492Alexey Samsonovu16 AtomicExchange(u16 *a, u16 new_val) { 1594c49666e611f06241bb8462cea7674d877241492Alexey Samsonov return __sync_lock_test_and_set(a, new_val); 1604c49666e611f06241bb8462cea7674d877241492Alexey Samsonov} 1614c49666e611f06241bb8462cea7674d877241492Alexey Samsonov 1624c49666e611f06241bb8462cea7674d877241492Alexey Samsonovu8 AtomicExchange(u8 *a, u8 new_val) { 1634c49666e611f06241bb8462cea7674d877241492Alexey Samsonov return __sync_lock_test_and_set(a, new_val); 1644c49666e611f06241bb8462cea7674d877241492Alexey Samsonov} 1654c49666e611f06241bb8462cea7674d877241492Alexey Samsonov 166be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov// -------------- sanitizer_libc.h 167be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov 1681f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonovint internal_sscanf(const char *str, const char *format, ...) { 1691f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov va_list args; 1701f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov va_start(args, format); 1711f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov int res = vsscanf(str, format, args); 1721f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov va_end(args); 1731f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov return res; 1741f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov} 1751f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov 1761f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov} // namespace __sanitizer 1771f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov 1781f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov#endif // __linux__ || __APPLE_ 179