debug/memory: add asan and valgrind annotation functions

This commit is contained in:
Danny Robson 2019-08-14 11:27:49 +10:00
parent 4e7e2c812d
commit 4608d24027
3 changed files with 171 additions and 0 deletions

View File

@ -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

129
debug/memory.cpp Normal file
View File

@ -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 <danny@nerdcruft.net>
*/
#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 <sanitizer/asan_interface.h>
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 <valgrind/memcheck.h>
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);
}

40
debug/memory.hpp Normal file
View File

@ -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 <danny@nerdcruft.net>
*/
#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 <typename ValueT>
void mark_undefined (cruft::view<ValueT const *> 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 <typename ValueT>
void mark_defined (cruft::view<ValueT const *> mem)
{
return mark_defined (mem.data (), mem.size () * sizeof (ValueT));
}
}