sanitizer_posix.cc revision fa3daaf1d66314658e7c05bf63dc825d179f2faf
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 301f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonovnamespace __sanitizer { 311f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov 32be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov// ------------- sanitizer_common.h 33be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov 34230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovint GetPid() { 35230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov return getpid(); 36230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov} 37230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov 38fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovuptr GetThreadSelf() { 39fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov return (uptr)pthread_self(); 40fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov} 41fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov 42a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonovvoid *MmapOrDie(uptr size, const char *mem_type) { 43230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov size = RoundUpTo(size, kPageSize); 44230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov void *res = internal_mmap(0, size, 45230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov PROT_READ | PROT_WRITE, 46230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov MAP_PRIVATE | MAP_ANON, -1, 0); 47230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov if (res == (void*)-1) { 48a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov Report("ERROR: Failed to allocate 0x%zx (%zd) bytes of %s\n", 49a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov size, size, mem_type); 50a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov CHECK("unable to mmap" && 0); 51230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov } 52230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov return res; 53230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov} 54230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov 55230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovvoid UnmapOrDie(void *addr, uptr size) { 56230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov if (!addr || !size) return; 57230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov int res = internal_munmap(addr, size); 58230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov if (res != 0) { 59a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov Report("ERROR: Failed to deallocate 0x%zx (%zd) bytes at address %p\n", 60a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov size, size, addr); 61a25b3463477d2a825df4f656001fc07c594b35acAlexey Samsonov CHECK("unable to unmap" && 0); 62230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov } 63230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov} 64230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov 65f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonovvoid *MmapFixedNoReserve(uptr fixed_addr, uptr size) { 66f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov return internal_mmap((void*)fixed_addr, size, 67f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov PROT_READ | PROT_WRITE, 68f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, 69f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov 0, 0); 70f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov} 71f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov 72f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonovvoid *Mprotect(uptr fixed_addr, uptr size) { 73f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov return internal_mmap((void*)fixed_addr, size, 74f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov PROT_NONE, 75f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, 76f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov 0, 0); 77f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov} 78f607fc1c67a613a59a1db3c80c5d1322e1978102Alexey Samsonov 79be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonovvoid DumpProcessMap() { 80be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov ProcessMaps proc_maps; 81be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov uptr start, end; 82be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov const sptr kBufSize = 4095; 83be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov char filename[kBufSize]; 84be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov Report("Process memory map follows:\n"); 85be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov while (proc_maps.Next(&start, &end, /* file_offset */0, 86be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov filename, kBufSize)) { 87be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov Printf("\t%p-%p\t%s\n", (void*)start, (void*)end, filename); 88be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov } 89be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov Report("End of process memory map.\n"); 90be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov} 91be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov 92be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonovvoid DisableCoreDumper() { 93be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov struct rlimit nocore; 94be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov nocore.rlim_cur = 0; 95be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov nocore.rlim_max = 0; 96be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov setrlimit(RLIMIT_CORE, &nocore); 97be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov} 98be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov 99fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovvoid SleepForSeconds(int seconds) { 100fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov sleep(seconds); 101fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov} 102fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov 103fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovvoid Exit(int exitcode) { 104fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov _exit(exitcode); 105fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov} 106fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov 107fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovvoid Abort() { 108fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov abort(); 109fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov} 110fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov 111fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonovint Atexit(void (*function)(void)) { 112fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov return atexit(function); 113fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov} 114fa3daaf1d66314658e7c05bf63dc825d179f2fafAlexey Samsonov 115be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov// -------------- sanitizer_libc.h 116be7420cc79d8580eb354666eef638d39ee9cff80Alexey Samsonov 1171f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonovint internal_sscanf(const char *str, const char *format, ...) { 1181f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov va_list args; 1191f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov va_start(args, format); 1201f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov int res = vsscanf(str, format, args); 1211f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov va_end(args); 1221f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov return res; 1231f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov} 1241f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov 1251f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov} // namespace __sanitizer 1261f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov 1271f11d31faa5ed89b74f7d543b1182fe8de198be5Alexey Samsonov#endif // __linux__ || __APPLE_ 128