SP: introduce AAL, PAL methods as per design doc
These capture the primitive architectural operations we are going to use. At the moment, since all AALs and PALs are not StrictProvenance, the only implementations are stubs that just subvert the type system (but give us something to compile against, going forward).
This commit is contained in:
committed by
Nathaniel Wesley Filardo
parent
c5aff8ed74
commit
268ef2c059
@@ -1,11 +1,13 @@
|
||||
#pragma once
|
||||
#include "../ds/concept.h"
|
||||
#include "../ds/defines.h"
|
||||
#include "../ds/ptrwrap.h"
|
||||
#include "aal_concept.h"
|
||||
#include "aal_consts.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
#if defined(__i386__) || defined(_M_IX86) || defined(_X86_) || \
|
||||
defined(__amd64__) || defined(__x86_64__) || defined(_M_X64) || \
|
||||
@@ -113,6 +115,48 @@ namespace snmalloc
|
||||
}
|
||||
};
|
||||
|
||||
template<class Arch>
|
||||
class AAL_NoStrictProvenance : public Arch
|
||||
{
|
||||
static_assert(
|
||||
(Arch::aal_features & StrictProvenance) == 0,
|
||||
"AAL_NoStrictProvenance requires what it says on the tin");
|
||||
|
||||
public:
|
||||
/**
|
||||
* For architectures which do not enforce StrictProvenance, we can just
|
||||
* perform an underhanded bit of type-casting.
|
||||
*/
|
||||
template<
|
||||
typename T,
|
||||
enum capptr_bounds nbounds,
|
||||
enum capptr_bounds obounds,
|
||||
typename U = T>
|
||||
static SNMALLOC_FAST_PATH CapPtr<T, nbounds>
|
||||
capptr_bound(CapPtr<U, obounds> a, size_t size) noexcept
|
||||
{
|
||||
// Impose constraints on bounds annotations.
|
||||
static_assert(
|
||||
obounds == CBArena || obounds == CBChunkD || obounds == CBChunk ||
|
||||
obounds == CBChunkE);
|
||||
static_assert(capptr_is_bounds_refinement<obounds, nbounds>());
|
||||
|
||||
UNUSED(size);
|
||||
return CapPtr<T, nbounds>(a.template as_static<T>().unsafe_capptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* For architectures which do not enforce StrictProvenance, there's nothing
|
||||
* to be done, so just return the pointer unmodified with new annotation.
|
||||
*/
|
||||
template<typename T, capptr_bounds BOut, capptr_bounds BIn>
|
||||
static SNMALLOC_FAST_PATH CapPtr<T, BOut>
|
||||
capptr_rebound(CapPtr<void, BOut> a, CapPtr<T, BIn> r) noexcept
|
||||
{
|
||||
UNUSED(a);
|
||||
return CapPtr<T, BOut>(r.unsafe_capptr);
|
||||
}
|
||||
};
|
||||
} // namespace snmalloc
|
||||
|
||||
#if defined(PLATFORM_IS_X86)
|
||||
@@ -129,7 +173,7 @@ namespace snmalloc
|
||||
|
||||
namespace snmalloc
|
||||
{
|
||||
using Aal = AAL_Generic<AAL_Arch>;
|
||||
using Aal = AAL_Generic<AAL_NoStrictProvenance<AAL_Arch>>;
|
||||
|
||||
template<AalFeatures F, SNMALLOC_CONCEPT(ConceptAAL) AAL = Aal>
|
||||
constexpr static bool aal_supports = (AAL::aal_features & F) == F;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#ifdef __cpp_concepts
|
||||
# include "../ds/concept.h"
|
||||
# include "../ds/ptrwrap.h"
|
||||
# include "aal_consts.h"
|
||||
|
||||
# include <cstdint>
|
||||
@@ -38,11 +39,31 @@ namespace snmalloc
|
||||
{ AAL::tick() } noexcept -> ConceptSame<uint64_t>;
|
||||
};
|
||||
|
||||
template<typename AAL>
|
||||
concept ConceptAAL_capptr_methods =
|
||||
requires(CapPtr<void, CBArena> auth, CapPtr<void, CBAlloc> ret, size_t sz)
|
||||
{
|
||||
/**
|
||||
* Produce a pointer with reduced authority from a more privilged pointer.
|
||||
* The resulting pointer will have base at auth's address and length of
|
||||
* exactly sz. auth+sz must not exceed auth's limit.
|
||||
*/
|
||||
{ AAL::template capptr_bound<void, CBChunk>(auth, sz) } noexcept
|
||||
-> ConceptSame<CapPtr<void, CBChunk>>;
|
||||
|
||||
/**
|
||||
* Construct a copy of auth with its target set to that of ret.
|
||||
*/
|
||||
{ AAL::capptr_rebound(auth, ret) } noexcept
|
||||
-> ConceptSame<CapPtr<void, CBArena>>;
|
||||
};
|
||||
|
||||
template<typename AAL>
|
||||
concept ConceptAAL =
|
||||
ConceptAAL_static_members<AAL> &&
|
||||
ConceptAAL_prefetch<AAL> &&
|
||||
ConceptAAL_tick<AAL>;
|
||||
ConceptAAL_tick<AAL> &&
|
||||
ConceptAAL_capptr_methods<AAL>;
|
||||
|
||||
} // namespace snmalloc
|
||||
#endif
|
||||
|
||||
@@ -69,6 +69,30 @@ namespace snmalloc
|
||||
// Used to keep Superslab metadata committed.
|
||||
static constexpr size_t OS_PAGE_SIZE = Pal::page_size;
|
||||
|
||||
/**
|
||||
* Perform platform-specific adjustment of return pointers.
|
||||
*
|
||||
* This is here, rather than in every PAL proper, merely to minimize
|
||||
* disruption to PALs for platforms that do not support StrictProvenance AALs.
|
||||
*/
|
||||
template<typename PAL = Pal, typename AAL = Aal, typename T, capptr_bounds B>
|
||||
static SNMALLOC_FAST_PATH typename std::enable_if_t<
|
||||
!aal_supports<StrictProvenance, AAL>,
|
||||
CapPtr<T, capptr_export_type<B>()>>
|
||||
capptr_export(CapPtr<T, B> p)
|
||||
{
|
||||
return CapPtr<T, capptr_export_type<B>()>(p.unsafe_capptr);
|
||||
}
|
||||
|
||||
template<typename PAL = Pal, typename AAL = Aal, typename T, capptr_bounds B>
|
||||
static SNMALLOC_FAST_PATH typename std::enable_if_t<
|
||||
aal_supports<StrictProvenance, AAL>,
|
||||
CapPtr<T, capptr_export_type<B>()>>
|
||||
capptr_export(CapPtr<T, B> p)
|
||||
{
|
||||
return PAL::capptr_export(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience wrapper that avoids the need to litter unsafe accesses with
|
||||
* every call to PAL::zero.
|
||||
|
||||
Reference in New Issue
Block a user