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 36 namespace __msan { 37 38 static const uptr kMemBeg = 0x600000000000; 39 static const uptr kMemEnd = 0x7fffffffffff; 40 static const uptr kShadowBeg = MEM_TO_SHADOW(kMemBeg); 41 static const uptr kShadowEnd = MEM_TO_SHADOW(kMemEnd); 42 static const uptr kBad1Beg = 0; 43 static const uptr kBad1End = kShadowBeg - 1; 44 static const uptr kBad2Beg = kShadowEnd + 1; 45 static const uptr kBad2End = kMemBeg - 1; 46 static const uptr kOriginsBeg = kBad2Beg; 47 static const uptr kOriginsEnd = kBad2End; 48 49 bool 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 86 void MsanDie() { 87 if (death_callback) 88 death_callback(); 89 _exit(flags()->exit_code); 90 } 91 92 static 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 101 void InstallAtExitHandler() { 102 atexit(MsanAtExit); 103 } 104 105 // ---------------------- TSD ---------------- {{{1 106 107 static pthread_key_t tsd_key; 108 static bool tsd_key_inited = false; 109 void 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 115 void *MsanTSDGet() { 116 CHECK(tsd_key_inited); 117 return pthread_getspecific(tsd_key); 118 } 119 120 void MsanTSDSet(void *tsd) { 121 CHECK(tsd_key_inited); 122 pthread_setspecific(tsd_key, tsd); 123 } 124 125 void 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