From 6b4ff3e7abdde5bb422d00014765bb1f09669648 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 30 Jul 2019 20:58:38 +0100 Subject: [PATCH] Basic OpenBSD backend support. Cannot enforce alignment so we just check its correctness. --- src/override/malloc.cc | 4 +- src/pal/pal.h | 3 ++ src/pal/pal_openbsd.h | 95 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 src/pal/pal_openbsd.h diff --git a/src/override/malloc.cc b/src/override/malloc.cc index ea1838b..1a864d8 100644 --- a/src/override/malloc.cc +++ b/src/override/malloc.cc @@ -89,7 +89,7 @@ extern "C" return p; } -#ifndef __FreeBSD__ +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(reallocarray)(void* ptr, size_t nmemb, size_t size) { @@ -165,7 +165,7 @@ extern "C" return 0; } -#ifndef __FreeBSD__ +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(valloc)(size_t size) { return SNMALLOC_NAME_MANGLE(memalign)(OS_PAGE_SIZE, size); diff --git a/src/pal/pal.h b/src/pal/pal.h index 799f859..6cec451 100644 --- a/src/pal/pal.h +++ b/src/pal/pal.h @@ -13,6 +13,7 @@ namespace snmalloc # include "pal_free_bsd_kernel.h" # include "pal_freebsd.h" # include "pal_linux.h" +# include "pal_openbsd.h" # include "pal_windows.h" #endif #include "pal_open_enclave.h" @@ -32,6 +33,8 @@ namespace snmalloc PALFreeBSDKernel; # elif defined(__FreeBSD__) PALFBSD; +# elif defined(__OpenBSD__) + PALOBSD; # else # error Unsupported platform # endif diff --git a/src/pal/pal_openbsd.h b/src/pal/pal_openbsd.h new file mode 100644 index 0000000..61fb19d --- /dev/null +++ b/src/pal/pal_openbsd.h @@ -0,0 +1,95 @@ +#pragma once + +#if defined(__OpenBSD__) && !defined(_KERNEL) +# include "../ds/bits.h" +# include "../mem/allocconfig.h" + +# include +# include +# include + +namespace snmalloc +{ + class PALOBSD + { + public: + /** + * Bitmap of PalFeatures flags indicating the optional features that this + * PAL supports. + */ + static constexpr uint64_t pal_features = AlignedAllocation | LazyCommit; + static void error(const char* const str) + { + puts(str); + abort(); + } + + /// Notify platform that we will not be using these pages + void notify_not_using(void* p, size_t size) noexcept + { + assert(bits::is_aligned_block(p, size)); + madvise(p, size, MADV_FREE); + } + + /// Notify platform that we will be using these pages + template + void notify_using(void* p, size_t size) noexcept + { + assert( + bits::is_aligned_block(p, size) || (zero_mem == NoZero)); + if constexpr (zero_mem == YesZero) + { + zero(p, size); + } + else + { + UNUSED(size); + UNUSED(p); + } + } + + /// OS specific function for zeroing memory + template + void zero(void* p, size_t size) noexcept + { + if (page_aligned || bits::is_aligned_block(p, size)) + { + assert(bits::is_aligned_block(p, size)); + void* r = mmap( + p, + size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + -1, + 0); + + if (r != MAP_FAILED) + return; + } + + ::memset(p, 0, size); + } + + template + void* reserve(const size_t* size, size_t align) noexcept + { + size_t request = *size; + // Alignment must be a power of 2. + assert(align == bits::next_pow2(align)); + + void* p = mmap( + nullptr, + request, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, + 0); + + if (p == MAP_FAILED) + error("Out of memory"); + + return p; + } + }; +} // namespace snmalloc +#endif