NFC: Further disentangle chunkmap and pagemap
- Make GlobalPagemapTemplate and ExternalGlobalPagemap generic in the type of the pagemap they're encapsulating. We're going to want to use these for other kinds of pagemaps in the near future. - Rename snmalloc_pagemap_global_get to snmalloc_chunkmap_global_get. - Rename GlobalPagemap to GlobalChunkmap.
This commit is contained in:
committed by
Matthew Parkinson
parent
8da12f5af8
commit
6250428c3d
@@ -83,81 +83,14 @@ namespace snmalloc
|
||||
FlatPagemap<SUPERSLAB_BITS, uint8_t>,
|
||||
Pagemap<SUPERSLAB_BITS, uint8_t, 0>>;
|
||||
|
||||
/**
|
||||
* Mixin used by `ChunkMap` to directly access the pagemap via a global
|
||||
* variable. This should be used from within the library or program that
|
||||
* owns the pagemap.
|
||||
*
|
||||
* This class makes the global pagemap a static field so that its name
|
||||
* includes the type mangling. If two compilation units try to instantiate
|
||||
* two different types of pagemap then they will see two distinct pagemaps.
|
||||
* This will prevent allocating with one and freeing with the other (because
|
||||
* the memory will show up as not owned by any allocator in the other
|
||||
* compilation unit) but will prevent the same memory being interpreted as
|
||||
* having two different types.
|
||||
*/
|
||||
template<typename T>
|
||||
class GlobalPagemapTemplate
|
||||
{
|
||||
/**
|
||||
* The global pagemap variable. The name of this symbol will include the
|
||||
* type of `T`.
|
||||
*/
|
||||
inline static T global_pagemap;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Returns the pagemap.
|
||||
*/
|
||||
static ChunkmapPagemap& pagemap()
|
||||
{
|
||||
return global_pagemap;
|
||||
}
|
||||
};
|
||||
|
||||
using GlobalPagemap = GlobalPagemapTemplate<ChunkmapPagemap>;
|
||||
using GlobalChunkmap = GlobalPagemapTemplate<ChunkmapPagemap>;
|
||||
|
||||
/**
|
||||
* Optionally exported function that accesses the global pagemap provided by
|
||||
* a shared library.
|
||||
* Optionally exported function that accesses the global chunkmap pagemap
|
||||
* provided by a shared library.
|
||||
*/
|
||||
extern "C" void* snmalloc_pagemap_global_get(snmalloc::PagemapConfig const**);
|
||||
|
||||
/**
|
||||
* Mixin used by `ChunkMap` to access the global pagemap via a
|
||||
* type-checked C interface. This should be used when another library (e.g.
|
||||
* your C standard library) uses snmalloc and you wish to use a different
|
||||
* configuration in your program or library, but wish to share a pagemap so
|
||||
* that either version can deallocate memory.
|
||||
*/
|
||||
class ExternalGlobalPagemap
|
||||
{
|
||||
/**
|
||||
* A pointer to the pagemap.
|
||||
*/
|
||||
inline static ChunkmapPagemap* external_pagemap;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Returns the exported pagemap.
|
||||
* Accesses the pagemap via the C ABI accessor and casts it to
|
||||
* the expected type, failing in cases of ABI mismatch.
|
||||
*/
|
||||
static ChunkmapPagemap& pagemap()
|
||||
{
|
||||
if (external_pagemap == nullptr)
|
||||
{
|
||||
const snmalloc::PagemapConfig* c = nullptr;
|
||||
void* raw_pagemap = snmalloc_pagemap_global_get(&c);
|
||||
external_pagemap = ChunkmapPagemap::cast_to_pagemap(raw_pagemap, c);
|
||||
if (!external_pagemap)
|
||||
{
|
||||
Pal::error("Incorrect ABI of global pagemap.");
|
||||
}
|
||||
}
|
||||
return *external_pagemap;
|
||||
}
|
||||
};
|
||||
extern "C" void*
|
||||
snmalloc_chunkmap_global_get(snmalloc::PagemapConfig const**);
|
||||
|
||||
/**
|
||||
* Class that defines an interface to the pagemap. This is provided to
|
||||
@@ -165,7 +98,7 @@ namespace snmalloc
|
||||
* implementation (for example, to move pagemap updates to a different
|
||||
* protection domain).
|
||||
*/
|
||||
template<typename PagemapProvider = GlobalPagemap>
|
||||
template<typename PagemapProvider = GlobalChunkmap>
|
||||
struct DefaultChunkMap
|
||||
{
|
||||
/**
|
||||
|
||||
@@ -409,4 +409,74 @@ namespace snmalloc
|
||||
reinterpret_cast<uintptr_t>(&top[p >> SHIFT]) & ~(OS_PAGE_SIZE - 1));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mixin used by `ChunkMap` and other `PageMap` consumers to directly access
|
||||
* the pagemap via a global variable. This should be used from within the
|
||||
* library or program that owns the pagemap.
|
||||
*
|
||||
* This class makes the global pagemap a static field so that its name
|
||||
* includes the type mangling. If two compilation units try to instantiate
|
||||
* two different types of pagemap then they will see two distinct pagemaps.
|
||||
* This will prevent allocating with one and freeing with the other (because
|
||||
* the memory will show up as not owned by any allocator in the other
|
||||
* compilation unit) but will prevent the same memory being interpreted as
|
||||
* having two different types.
|
||||
*/
|
||||
template<typename T>
|
||||
class GlobalPagemapTemplate
|
||||
{
|
||||
/**
|
||||
* The global pagemap variable. The name of this symbol will include the
|
||||
* type of `T`.
|
||||
*/
|
||||
inline static T global_pagemap;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Returns the pagemap.
|
||||
*/
|
||||
static T& pagemap()
|
||||
{
|
||||
return global_pagemap;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mixin used by `ChunkMap` and other `PageMap` consumers to access the global
|
||||
* pagemap via a type-checked C interface. This should be used when another
|
||||
* library (e.g. your C standard library) uses snmalloc and you wish to use a
|
||||
* different configuration in your program or library, but wish to share a
|
||||
* pagemap so that either version can deallocate memory.
|
||||
*/
|
||||
template<typename T, void* (*raw_get)(const PagemapConfig**)>
|
||||
class ExternalGlobalPagemapTemplate
|
||||
{
|
||||
/**
|
||||
* A pointer to the pagemap.
|
||||
*/
|
||||
inline static T* external_pagemap;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Returns the exported pagemap.
|
||||
* Accesses the pagemap via the C ABI accessor and casts it to
|
||||
* the expected type, failing in cases of ABI mismatch.
|
||||
*/
|
||||
static T& pagemap()
|
||||
{
|
||||
if (external_pagemap == nullptr)
|
||||
{
|
||||
const snmalloc::PagemapConfig* c = nullptr;
|
||||
void* raw_pagemap = raw_get(&c);
|
||||
external_pagemap = T::cast_to_pagemap(raw_pagemap, c);
|
||||
if (!external_pagemap)
|
||||
{
|
||||
Pal::error("Incorrect ABI of global pagemap.");
|
||||
}
|
||||
}
|
||||
return *external_pagemap;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace snmalloc
|
||||
|
||||
@@ -221,10 +221,10 @@ extern "C"
|
||||
* this function to the correct type. This allows us to preserve some
|
||||
* semblance of ABI safety via a pure C API.
|
||||
*/
|
||||
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(snmalloc_pagemap_global_get)(
|
||||
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(snmalloc_chunkmap_global_get)(
|
||||
PagemapConfig const** config)
|
||||
{
|
||||
auto& pm = GlobalPagemap::pagemap();
|
||||
auto& pm = GlobalChunkmap::pagemap();
|
||||
if (config)
|
||||
{
|
||||
*config = &ChunkmapPagemap::config;
|
||||
|
||||
@@ -10,10 +10,13 @@ int main()
|
||||
# define SNMALLOC_EXPOSE_PAGEMAP 1
|
||||
# include <override/malloc.cc>
|
||||
|
||||
using ExternalChunkmap =
|
||||
ExternalGlobalPagemapTemplate<ChunkmapPagemap, snmalloc_chunkmap_global_get>;
|
||||
|
||||
int main()
|
||||
{
|
||||
auto& p = ExternalGlobalPagemap::pagemap();
|
||||
auto& global = GlobalPagemap::pagemap();
|
||||
auto& p = ExternalChunkmap::pagemap();
|
||||
auto& global = GlobalChunkmap::pagemap();
|
||||
SNMALLOC_CHECK(&p == &global);
|
||||
// Get a valid heap address
|
||||
uintptr_t addr = reinterpret_cast<uintptr_t>(malloc(42));
|
||||
|
||||
@@ -24,9 +24,9 @@ extern "C" void* enclave_malloc(size_t);
|
||||
extern "C" void enclave_free(void*);
|
||||
|
||||
extern "C" void*
|
||||
enclave_snmalloc_pagemap_global_get(snmalloc::PagemapConfig const**);
|
||||
enclave_snmalloc_chunkmap_global_get(snmalloc::PagemapConfig const**);
|
||||
extern "C" void*
|
||||
host_snmalloc_pagemap_global_get(snmalloc::PagemapConfig const**);
|
||||
host_snmalloc_chunkmap_global_get(snmalloc::PagemapConfig const**);
|
||||
|
||||
using namespace snmalloc;
|
||||
int main()
|
||||
@@ -47,8 +47,8 @@ int main()
|
||||
|
||||
// Call these functions to trigger asserts if the cast-to-self doesn't work.
|
||||
const PagemapConfig* c;
|
||||
enclave_snmalloc_pagemap_global_get(&c);
|
||||
host_snmalloc_pagemap_global_get(&c);
|
||||
enclave_snmalloc_chunkmap_global_get(&c);
|
||||
host_snmalloc_chunkmap_global_get(&c);
|
||||
|
||||
auto a = host_malloc(128);
|
||||
auto b = enclave_malloc(128);
|
||||
|
||||
Reference in New Issue
Block a user