From e3bd75570cc7a308616dad5ff8794602ee9c838b Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Tue, 19 Mar 2024 13:42:49 +0000 Subject: [PATCH] Add a check that the unused bits in MMIO imports are unused. This addresses the 'shouldn't silently fail' part of #182. A subsequent change may allow it to also work, depending on use cases. --- sdk/core/loader/boot.cc | 1 + sdk/core/loader/types.h | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/sdk/core/loader/boot.cc b/sdk/core/loader/boot.cc index 1de9986a..26bb5a8a 100644 --- a/sdk/core/loader/boot.cc +++ b/sdk/core/loader/boot.cc @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MIT #include + // memcpy is exposed as a libcall in the standard library headers but we want // to ensure that our version is called directly and not exposed to anything // else. diff --git a/sdk/core/loader/types.h b/sdk/core/loader/types.h index a74add2c..fea0a7e7 100644 --- a/sdk/core/loader/types.h +++ b/sdk/core/loader/types.h @@ -5,8 +5,8 @@ #include "../switcher/tstack.h" #include "assembly-helpers.h" +#include "debug.hh" #include "defines.h" -#include #include #include #include @@ -891,6 +891,33 @@ namespace loader */ static constexpr size_t PermitLoadMutable = (1UL << 28); + /** + * Mask for the used permissions. + */ + static constexpr size_t PermissionsMask = PermitLoad | PermitStore | + PermitLoadStoreCapabilities | + PermitLoadMutable; + + /** + * Mask for the space reserved for permissions. + */ + static constexpr size_t ReservedPermissionsMask = 0xff000000; + + /** + * Mask for the space not used yet for permissions. + */ + static constexpr size_t UnusedPermissionsMask = + ReservedPermissionsMask & ~PermissionsMask; + + static_assert( + (PermissionsMask & ReservedPermissionsMask) == PermissionsMask, + "Permissions must be in the space reserved for permissions"); + + /** + * Mask for the size. + */ + static constexpr size_t SizeMask = ~ReservedPermissionsMask; + /** * State on boot. */ @@ -926,7 +953,11 @@ namespace loader */ [[nodiscard]] size_t size() const { - return sizeAndPermissions & 0xffffff; + Debug::Invariant((sizeAndPermissions & UnusedPermissionsMask) == 0, + "Unused bits in sizeAndPermissions are not zero, " + "field contains {}", + sizeAndPermissions); + return sizeAndPermissions & SizeMask; } /**