From 4608d2402725cb2d967fd5b3b4c56cf50f7ec7eb Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Wed, 14 Aug 2019 11:27:49 +1000 Subject: [PATCH] debug/memory: add asan and valgrind annotation functions --- CMakeLists.txt | 2 + debug/memory.cpp | 129 +++++++++++++++++++++++++++++++++++++++++++++++ debug/memory.hpp | 40 +++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 debug/memory.cpp create mode 100644 debug/memory.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c01969d..dbd3fd5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -305,6 +305,8 @@ list ( debug/compiler.hpp debug/debugger.cpp debug/debugger.hpp + debug/memory.cpp + debug/memory.hpp debug/panic.cpp debug/panic.hpp debug/system.cpp diff --git a/debug/memory.cpp b/debug/memory.cpp new file mode 100644 index 00000000..e9e615a6 --- /dev/null +++ b/debug/memory.cpp @@ -0,0 +1,129 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2019 Danny Robson + */ + +#include "memory.hpp" + +#include "std.hpp" +#include "maths.hpp" +#include "debug/panic.hpp" + + +/////////////////////////////////////////////////////////////////////////////// +#ifndef __has_feature +#define __has_feature(X) 0 +#endif + + +//----------------------------------------------------------------------------- +#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) +#include +static std::align_val_t asan_alignment (void) +{ + return std::align_val_t {8u}; +} + + +static void asan_undefined (void const volatile *addr, std::size_t size) +{ + return ASAN_POISON_MEMORY_REGION ((addr), (size)); +} + + +static void asan_defined (void const volatile *addr, std::size_t size) +{ + return ASAN_UNPOISON_MEMORY_REGION ((addr), (size)); +} +#else +static std::align_val_t asan_alignment (void) +{ + return std::align_val_t {1u}; +} + + +static void asan_undefined (void const volatile *addr, std::size_t size) +{ + (void)addr; + (void)size; +} + + +static void asan_defined (void const volatile *addr, std::size_t size) +{ + (void)addr; + (void)size; +} +#endif + + +/////////////////////////////////////////////////////////////////////////////// +static std::align_val_t vg_alignment (void) +{ + return std::align_val_t {1u}; +} + + +//----------------------------------------------------------------------------- +#if __has_include("valgrind/memcheck.h") +#include +static void vg_undefined (void const volatile *addr, std::size_t len) +{ + VALGRIND_MAKE_MEM_UNDEFINED (addr, len); +} + + +//----------------------------------------------------------------------------- +static void vg_defined (void const volatile *addr, std::size_t len) +{ + VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE (addr, len); +} +#else +//----------------------------------------------------------------------------- +static void vg_undefined (void const volatile *addr, std::size_t len) +{ + (void)addr; + (void)len; +} + + +//----------------------------------------------------------------------------- +static void vg_defined (void const volatile *addr, std::size_t len) +{ + (void)addr; + (void)len; +} +#endif + + +/////////////////////////////////////////////////////////////////////////////// +std::align_val_t +cruft::debug::memory::instrumentation_alignment (void) +{ + return cruft::max ( + asan_alignment (), + vg_alignment (), + std::align_val_t {1u} + ); +} + + +//----------------------------------------------------------------------------- +void +cruft::debug::memory::mark_undefined (void const volatile *ptr, std::size_t len) +{ + asan_undefined (ptr, len); + vg_undefined (ptr, len); +} + + +//----------------------------------------------------------------------------- +void +cruft::debug::memory::mark_defined (void const volatile *ptr, std::size_t len) +{ + asan_defined (ptr, len); + vg_defined (ptr, len); +} diff --git a/debug/memory.hpp b/debug/memory.hpp new file mode 100644 index 00000000..887ec58d --- /dev/null +++ b/debug/memory.hpp @@ -0,0 +1,40 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2019 Danny Robson + */ + +#pragma once + +#include "../view.hpp" + +namespace cruft::debug::memory { + /// Returns the required alignment for instrumented memory accesses. + std::align_val_t instrumentation_alignment (void); + + + /// Label the contents of this memory region as undefined. + void mark_undefined (void const volatile*, std::size_t); + + + //------------------------------------------------------------------------- + template + void mark_undefined (cruft::view mem) + { + return mark_undefined (mem.data (), mem.size () * sizeof (ValueT)); + } + + + /// Label the contents of this memory region as defined + void mark_defined (void const volatile*, std::size_t); + + + //------------------------------------------------------------------------- + template + void mark_defined (cruft::view mem) + { + return mark_defined (mem.data (), mem.size () * sizeof (ValueT)); + } +}