Skip to content

Commit

Permalink
OpenEnclave PAL: Store enclave heap base/end in inline variables. (#201)
Browse files Browse the repository at this point in the history
PALOpenEnclave object is lazily constructed. I couldn't
figure out a straight-forward way to pass the heap bounds to
the constructor of PALOpenEnclave object.
As an alternative, store the bounds in inline static variables of
the PALOpenEnclave class and set them via static setup_initial_range
function.

- two_alloc_types/alloc1.cc
  Define oe_allocator_init to forward base, end values to
  PALOpenEnclave::setup_inital_range
- two_alloc_types/main.cc
  Use oe_allocator_init function to set up heap range.

- fixed_region/fixed_region.cc
  Initialize heap range via call to PALOpenEnclave::setup_inital_range.

Signed-off-by: Anand Krishnamoorthi <[email protected]>
  • Loading branch information
anakrish authored May 28, 2020
1 parent 4c22c5b commit c7736a2
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 40 deletions.
24 changes: 12 additions & 12 deletions src/pal/pal_open_enclave.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,26 @@
#include "ds/address.h"
#include "pal_plain.h"
#ifdef OPEN_ENCLAVE
extern "C" const void* __oe_get_heap_base();
extern "C" const void* __oe_get_heap_end();
extern "C" void* oe_memset_s(void* p, size_t p_size, int c, size_t size);
extern "C" [[noreturn]] void oe_abort();

namespace snmalloc
{
class PALOpenEnclave
{
std::atomic<void*> oe_base = nullptr;
static inline std::atomic<void*> oe_base;
static inline void* oe_end = nullptr;

public:
/**
* This will be called by oe_allocator_init to set up enclave heap bounds.
*/
static void setup_initial_range(void* base, void* end)
{
oe_base = base;
oe_end = end;
}

/**
* Bitmap of PalFeatures flags indicating the optional features that this
* PAL supports.
Expand All @@ -32,17 +40,9 @@ namespace snmalloc
template<bool committed>
void* reserve(size_t size) noexcept
{
if (oe_base == 0)
{
void* dummy = NULL;
// If this CAS fails then another thread has initialised this.
oe_base.compare_exchange_strong(
dummy, const_cast<void*>(__oe_get_heap_base()));
}

void* old_base = oe_base;
void* next_base;
auto end = __oe_get_heap_end();
auto end = oe_end;
do
{
auto new_base = old_base;
Expand Down
17 changes: 3 additions & 14 deletions src/test/func/fixed_region/fixed_region.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,6 @@
#endif
#define assert please_use_SNMALLOC_ASSERT

void* oe_base;
void* oe_end;
extern "C" const void* __oe_get_heap_base()
{
return oe_base;
}

extern "C" const void* __oe_get_heap_end()
{
return oe_end;
}

extern "C" void* oe_memset_s(void* p, size_t p_size, int c, size_t size)
{
UNUSED(p_size);
Expand All @@ -43,8 +31,9 @@ int main()
// For 1MiB superslabs, SUPERSLAB_BITS + 4 is not big enough for the example.
size_t large_class = 28 - SUPERSLAB_BITS;
size_t size = 1ULL << (SUPERSLAB_BITS + large_class);
oe_base = mp.reserve<true>(large_class);
oe_end = (uint8_t*)oe_base + size;
void* oe_base = mp.reserve<true>(large_class);
void* oe_end = (uint8_t*)oe_base + size;
PALOpenEnclave::setup_initial_range(oe_base, oe_end);
std::cout << "Allocated region " << oe_base << " - " << oe_end << std::endl;

auto a = ThreadAlloc::get();
Expand Down
5 changes: 5 additions & 0 deletions src/test/func/two_alloc_types/alloc1.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,8 @@
// Redefine the namespace, so we can have two versions.
#define snmalloc snmalloc_enclave
#include "../../../override/malloc.cc"

extern "C" void oe_allocator_init(void* base, void* end)
{
snmalloc_enclave::PALOpenEnclave::setup_initial_range(base, end);
}
18 changes: 4 additions & 14 deletions src/test/func/two_alloc_types/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,6 @@
#include <string.h>
#include <test/setup.h>

void* oe_base;
void* oe_end;
extern "C" const void* __oe_get_heap_base()
{
return oe_base;
}

extern "C" const void* __oe_get_heap_end()
{
return oe_end;
}

extern "C" void* oe_memset_s(void* p, size_t p_size, int c, size_t size)
{
UNUSED(p_size);
Expand All @@ -28,6 +16,7 @@ extern "C" void oe_abort()
abort();
}

extern "C" void oe_allocator_init(void* base, void* end);
extern "C" void* host_malloc(size_t);
extern "C" void host_free(void*);

Expand All @@ -51,8 +40,9 @@ int main()
// For 1MiB superslabs, SUPERSLAB_BITS + 2 is not big enough for the example.
size_t large_class = 26 - SUPERSLAB_BITS;
size_t size = 1ULL << (SUPERSLAB_BITS + large_class);
oe_base = mp.reserve<true>(large_class);
oe_end = (uint8_t*)oe_base + size;
void* oe_base = mp.reserve<true>(large_class);
void* oe_end = (uint8_t*)oe_base + size;
oe_allocator_init(oe_base, oe_end);
std::cout << "Allocated region " << oe_base << " - " << oe_end << std::endl;

// Call these functions to trigger asserts if the cast-to-self doesn't work.
Expand Down

0 comments on commit c7736a2

Please sign in to comment.