//===-- msan_linux.cc -----------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file is a part of MemorySanitizer. // // Linux-specific code. //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" #if SANITIZER_LINUX #include "msan.h" #include #include #include #include #include #include #include #include #include #include #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_procmaps.h" namespace __msan { static const uptr kMemBeg = 0x600000000000; static const uptr kMemEnd = 0x7fffffffffff; static const uptr kShadowBeg = MEM_TO_SHADOW(kMemBeg); static const uptr kShadowEnd = MEM_TO_SHADOW(kMemEnd); static const uptr kBad1Beg = 0x100000000; // 4G static const uptr kBad1End = kShadowBeg - 1; static const uptr kBad2Beg = kShadowEnd + 1; static const uptr kBad2End = kMemBeg - 1; static const uptr kOriginsBeg = kBad2Beg; static const uptr kOriginsEnd = kBad2End; bool InitShadow(bool prot1, bool prot2, bool map_shadow, bool init_origins) { if ((uptr) & InitShadow < kMemBeg) { Printf("FATAL: Code below application range: %p < %p. Non-PIE build?\n", &InitShadow, (void *)kMemBeg); return false; } if (common_flags()->verbosity) { Printf("__msan_init %p\n", &__msan_init); Printf("Memory : %p %p\n", kMemBeg, kMemEnd); Printf("Bad2 : %p %p\n", kBad2Beg, kBad2End); Printf("Origins : %p %p\n", kOriginsBeg, kOriginsEnd); Printf("Shadow : %p %p\n", kShadowBeg, kShadowEnd); Printf("Bad1 : %p %p\n", kBad1Beg, kBad1End); } if (!MemoryRangeIsAvailable(kShadowBeg, init_origins ? kOriginsEnd : kShadowEnd)) { Printf("FATAL: Shadow memory range is not available.\n"); return false; } if (prot1 && !Mprotect(kBad1Beg, kBad1End - kBad1Beg)) return false; if (prot2 && !Mprotect(kBad2Beg, kBad2End - kBad2Beg)) return false; if (map_shadow) { void *shadow = MmapFixedNoReserve(kShadowBeg, kShadowEnd - kShadowBeg); if (shadow != (void*)kShadowBeg) return false; } if (init_origins) { void *origins = MmapFixedNoReserve(kOriginsBeg, kOriginsEnd - kOriginsBeg); if (origins != (void*)kOriginsBeg) return false; } return true; } void MsanDie() { _exit(flags()->exit_code); } static void MsanAtExit(void) { if (msan_report_count > 0) { ReportAtExitStatistics(); if (flags()->exit_code) _exit(flags()->exit_code); } } void InstallAtExitHandler() { atexit(MsanAtExit); } } // namespace __msan #endif // __linux__