msan_linux.cc revision 5d71de26cedae3dafc17449fe0182045c0bd20e8
1//===-- msan_linux.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 a part of MemorySanitizer. 11// 12// Linux-specific code. 13//===----------------------------------------------------------------------===// 14 15#include "sanitizer_common/sanitizer_platform.h" 16#if SANITIZER_LINUX 17 18#include "msan.h" 19#include "msan_thread.h" 20 21#include <elf.h> 22#include <link.h> 23#include <pthread.h> 24#include <stdio.h> 25#include <stdlib.h> 26#include <signal.h> 27#include <unistd.h> 28#include <unwind.h> 29#include <execinfo.h> 30#include <sys/time.h> 31#include <sys/resource.h> 32 33#include "sanitizer_common/sanitizer_common.h" 34#include "sanitizer_common/sanitizer_procmaps.h" 35 36namespace __msan { 37 38static const uptr kMemBeg = 0x600000000000; 39static const uptr kMemEnd = 0x7fffffffffff; 40static const uptr kShadowBeg = MEM_TO_SHADOW(kMemBeg); 41static const uptr kShadowEnd = MEM_TO_SHADOW(kMemEnd); 42static const uptr kBad1Beg = 0; 43static const uptr kBad1End = kShadowBeg - 1; 44static const uptr kBad2Beg = kShadowEnd + 1; 45static const uptr kBad2End = kMemBeg - 1; 46static const uptr kOriginsBeg = kBad2Beg; 47static const uptr kOriginsEnd = kBad2End; 48 49bool InitShadow(bool prot1, bool prot2, bool map_shadow, bool init_origins) { 50 if ((uptr) & InitShadow < kMemBeg) { 51 Printf("FATAL: Code below application range: %p < %p. Non-PIE build?\n", 52 &InitShadow, (void *)kMemBeg); 53 return false; 54 } 55 56 VPrintf(1, "__msan_init %p\n", &__msan_init); 57 VPrintf(1, "Memory : %p %p\n", kMemBeg, kMemEnd); 58 VPrintf(1, "Bad2 : %p %p\n", kBad2Beg, kBad2End); 59 VPrintf(1, "Origins : %p %p\n", kOriginsBeg, kOriginsEnd); 60 VPrintf(1, "Shadow : %p %p\n", kShadowBeg, kShadowEnd); 61 VPrintf(1, "Bad1 : %p %p\n", kBad1Beg, kBad1End); 62 63 if (!MemoryRangeIsAvailable(kShadowBeg, 64 init_origins ? kOriginsEnd : kShadowEnd) || 65 (prot1 && !MemoryRangeIsAvailable(kBad1Beg, kBad1End)) || 66 (prot2 && !MemoryRangeIsAvailable(kBad2Beg, kBad2End))) { 67 Printf("FATAL: Shadow memory range is not available.\n"); 68 return false; 69 } 70 71 if (prot1 && !Mprotect(kBad1Beg, kBad1End - kBad1Beg)) 72 return false; 73 if (prot2 && !Mprotect(kBad2Beg, kBad2End - kBad2Beg)) 74 return false; 75 if (map_shadow) { 76 void *shadow = MmapFixedNoReserve(kShadowBeg, kShadowEnd - kShadowBeg); 77 if (shadow != (void*)kShadowBeg) return false; 78 } 79 if (init_origins) { 80 void *origins = MmapFixedNoReserve(kOriginsBeg, kOriginsEnd - kOriginsBeg); 81 if (origins != (void*)kOriginsBeg) return false; 82 } 83 return true; 84} 85 86void MsanDie() { 87 if (death_callback) 88 death_callback(); 89 _exit(flags()->exit_code); 90} 91 92static void MsanAtExit(void) { 93 if (flags()->print_stats && (flags()->atexit || msan_report_count > 0)) 94 ReportStats(); 95 if (msan_report_count > 0) { 96 ReportAtExitStatistics(); 97 if (flags()->exit_code) _exit(flags()->exit_code); 98 } 99} 100 101void InstallAtExitHandler() { 102 atexit(MsanAtExit); 103} 104 105// ---------------------- TSD ---------------- {{{1 106 107static pthread_key_t tsd_key; 108static bool tsd_key_inited = false; 109void MsanTSDInit(void (*destructor)(void *tsd)) { 110 CHECK(!tsd_key_inited); 111 tsd_key_inited = true; 112 CHECK_EQ(0, pthread_key_create(&tsd_key, destructor)); 113} 114 115void *MsanTSDGet() { 116 CHECK(tsd_key_inited); 117 return pthread_getspecific(tsd_key); 118} 119 120void MsanTSDSet(void *tsd) { 121 CHECK(tsd_key_inited); 122 pthread_setspecific(tsd_key, tsd); 123} 124 125void MsanTSDDtor(void *tsd) { 126 MsanThread *t = (MsanThread*)tsd; 127 if (t->destructor_iterations_ > 1) { 128 t->destructor_iterations_--; 129 CHECK_EQ(0, pthread_setspecific(tsd_key, tsd)); 130 return; 131 } 132 MsanThread::TSDDtor(tsd); 133} 134 135} // namespace __msan 136 137#endif // __linux__ 138