CHERIoT-Platform/cheriot-rtos

Static sealing types parameterized by template parameters?

Opened this issue · 1 comments

It might be nice to replace https://github.com/microsoft/cheriot-rtos/blob/b4b6204e9b539a79c902245a9df26f1b3e309e8f/sdk/include/thread_pool.h#L70-L79
with something that didn't incur the dynamic costs. The static mechanism is tantalizingly close, and yet.

Using the existing macros is a non-starter, due to phasing: the preprocessor would need to have the (stringified) type being substituted for T, but it's operating before any of that nonsense has happened.

I've tried, to no success, slight tweaks on

template<typename T>
static constexpr loader::ExportEntry sealing_key_for_type_ee
  __attribute__((section("compartment_exports"))) = {
    .functionStart    = 0,
    .minimumStackSize = 0,
    .flags            = loader::ExportEntry::SealingTypeEntry};

template<typename T>
static constexpr loader::ImportEntry sealing_key_for_type_ie
  __attribute__((section("compartment_imports"))) = {
    .boot = {.address = &sealing_key_for_type_ee<T>, .size = 0}};

/**
 * Helper that generates a different sealing key per type using the
 * allocator's token mechanism.
 */
template<typename T>
inline SKey sealing_key_for_type()
{
	return static_cast<SKey>(sealing_key_for_type_ie<T>.pointer);
}

but, of course, that doesn't quite work either: I can't initialize the ptraddr_t .boot.address (having given a name to the anonymous struct in union ImportEntry) with a pointer type, and I can't reinterpret_cast<ptraddr_t>(&sealing_key_for_type_ee<T>) either, because that's not allowed as a constexpr.

Eventually, the scary macros will become compiler builtins (well, the macros will become very thing wrappers around compiler builtins). They're mostly macros because it removes some tight coupling between compiler version and the RTOS.

In that case, I think the static sealing things will just become an attribute on a struct and the struct can be used by name with an error if you do anything other than take the address of it. Once that's done, I think we can remove the dynamic allocation from things like this quite easily. The static SKey key = token_key_new(); will become something like static constexpr SKey key = __builtin_cheriot_token_new_anonymous();, where the anonymous bit means that we're not exporting this for other compartments to use and so it doesn't get a public symbol in the export table.

reinterpret_cast<ptraddr_t>(&sealing_key_for_type_ee)

I think this does work with c-style casts.