diff --git a/sdk/core/loader/types.h b/sdk/core/loader/types.h index fea0a7e7..285a2a58 100644 --- a/sdk/core/loader/types.h +++ b/sdk/core/loader/types.h @@ -300,7 +300,8 @@ namespace loader /** * Helper for encapsulating an address range. */ - struct __packed AddressRange + template + struct __packed ShiftedAddressRange { /** * Start address. @@ -325,10 +326,12 @@ namespace loader */ [[nodiscard]] size_t size() const { - return smallSize; + return size_t(smallSize) << Shift; } }; + using AddressRange = ShiftedAddressRange<0>; + static_assert(RawAddressRange, "AddressRange should be a raw address range"); @@ -441,7 +444,7 @@ namespace loader /** * The compartment's globals. */ - AddressRange data; + ShiftedAddressRange<2> data; /** * The distance from the start of the code region to the end of the @@ -612,7 +615,7 @@ namespace loader // This is a random 32-bit number and should be changed whenever // the compartment header layout changes to provide some sanity // checking. - return magic == 0x6cef3879; + return magic == 0x46391da0; } /** @@ -707,7 +710,7 @@ namespace loader /** * The (mutable) data section for this compartment. */ - AddressRange data; + ShiftedAddressRange<2> data; /** * The size in bytes of the data section that is initialised diff --git a/sdk/firmware.ldscript.in b/sdk/firmware.ldscript.in index 82d57b33..9b7a9899 100644 --- a/sdk/firmware.ldscript.in +++ b/sdk/firmware.ldscript.in @@ -181,7 +181,7 @@ SECTIONS # Scheduler globals start address LONG(.scheduler_globals); # Scheduler globals end size - SHORT(SIZEOF(.scheduler_globals)); + SHORT(SIZEOF(.scheduler_globals) / 4); # Size of the scheduler import table SHORT(.scheduler_import_end - .scheduler_start); # Address of scheduler export table @@ -200,7 +200,7 @@ SECTIONS # Allocator globals start address LONG(.allocator_globals); # Allocator globals end - SHORT(SIZEOF(.allocator_globals)); + SHORT(SIZEOF(.allocator_globals) / 4); # Size of the allocator import table SHORT(.allocator_import_end - .allocator_start); # Address of allocator export table @@ -236,7 +236,7 @@ SECTIONS # loader versions. # New versions of this can be generated with: # head /dev/random | shasum | cut -c 0-8 - LONG(0x6cef3879); + LONG(0x46391da0); # Number of library headers. SHORT(@library_count@); # Number of compartment headers. diff --git a/sdk/xmake.lua b/sdk/xmake.lua index 96b03cdd..f089778e 100644 --- a/sdk/xmake.lua +++ b/sdk/xmake.lua @@ -528,7 +528,8 @@ rule("firmware") "\n\t\tLONG(.${compartment}_export_table);" .. "\n\t\tSHORT(.${compartment}_export_table_end - .${compartment}_export_table);" .. "\n\t\tLONG(.${compartment}_globals);" .. - "\n\t\tSHORT(SIZEOF(.${compartment}_globals));" .. + "\n\t\tSHORT(SIZEOF(.${compartment}_globals)/4);" .. + "\n\t\tASSERT(SIZEOF(.${compartment}_globals) < 0x40000, \"${compartment}'s globals are too large\");" .. "\n\t\tSHORT(.${compartment}_bss_start - .${compartment}_globals);" .. "\n\t\tLONG(.${compartment}_cap_relocs_start);" .. "\n\t\tSHORT(.${compartment}_cap_relocs_end - .${compartment}_cap_relocs_start);" .. @@ -652,7 +653,7 @@ rule("firmware") "\n\t\tLONG(.software_revoker_start);" .. "\n\t\tSHORT(.software_revoker_end - .software_revoker_start);" .. "\n\t\tLONG(.software_revoker_globals);" .. - "\n\t\tSHORT(SIZEOF(.software_revoker_globals));" .. + "\n\t\tSHORT(SIZEOF(.software_revoker_globals) / 4);" .. -- The import table offset is computed from the start by code -- that assumes that the first two words are space for sealing -- keys, so we set it to 16 here to provide a computed size of diff --git a/tests/bigdata-test.cc b/tests/bigdata-test.cc new file mode 100644 index 00000000..79817ece --- /dev/null +++ b/tests/bigdata-test.cc @@ -0,0 +1,29 @@ +#include "cheri.hh" +#define TEST_NAME "Big Data" +#include "tests.hh" + +extern "C" enum ErrorRecoveryBehaviour +compartment_error_handler(struct ErrorState *frame, size_t mcause, size_t mtval) +{ + debug_log("Detected error in instruction {}", frame->pcc); + debug_log("Error cause: {}, mtval: {}", mcause, mtval); + auto [reg, cause] = CHERI::extract_cheri_mtval(mtval); + debug_log("Error {} in register {}", reg, cause); + return ErrorRecoveryBehaviour::ForceUnwind; +} + +void test_big_data() +{ + register char *cgpRegister asm("cgp"); + asm("" : "=C"(cgpRegister)); + static uint32_t data[16384]; + debug_log("Data: {}", data); + debug_log("CGP: {}", cgpRegister); + debug_log("Fill with for oop"); + for (int i = 0; i < 16000; ++i) + { + data[i] = 0x01020304; + } + debug_log("Fill with memset"); + memset(data, 0x5a, sizeof(data)); +} diff --git a/tests/misc-test.cc b/tests/misc-test.cc index 13e1adfc..ba90cd50 100644 --- a/tests/misc-test.cc +++ b/tests/misc-test.cc @@ -6,6 +6,12 @@ #include #include +namespace +{ + char largeBuffer[4096]; + const char LargeConstBuffer[4096] = "This is a large const buffer buffer."; +} // namespace + /** * Test timeouts. * @@ -87,6 +93,23 @@ void check_memchr() void test_misc() { + CHERI::Capability largeRW{largeBuffer}; + CHERI::Capability largeRO{LargeConstBuffer}; + debug_log("RW: {}", largeRW); + debug_log("RO: {}", largeRO); + TEST(largeRW.length() == sizeof(largeBuffer), + "Large buffer has the wrong size: {}", + largeRW.length()); + TEST(largeRO.length() == sizeof(LargeConstBuffer), + "Large const buffer has the wrong size: {}", + largeRO.length()); + TEST(largeRW.is_valid(), "Large buffer is untagged"); + TEST(largeRO.is_valid(), "Large const buffer is untagged"); + TEST(largeRW.permissions().contains(CHERI::Permission::Store), + "Large buffer is not writable: {}", + largeRW); + TEST(!largeRO.permissions().contains(CHERI::Permission::Store), + "Large const buffer is writable"); check_timeouts(); check_memchr(); } diff --git a/tests/test-runner.cc b/tests/test-runner.cc index 8d99fdd2..3857b1c3 100644 --- a/tests/test-runner.cc +++ b/tests/test-runner.cc @@ -107,6 +107,9 @@ void __cheri_compartment("test_runner") run_tests() debug_log("Trying to print string: {}", std::string_view{testString, 13}); run_timed("All tests", []() { + // This test is disabled because it uses too much memory for the heap + // tests to work. + // run_timed("big data in globals", test_big_data); run_timed("Debug helpers (C++)", test_debug_cxx); run_timed("Debug helpers (C)", test_debug_c); run_timed("MMIO", test_mmio); diff --git a/tests/tests.hh b/tests/tests.hh index bd63a3ce..bf279289 100644 --- a/tests/tests.hh +++ b/tests/tests.hh @@ -22,6 +22,7 @@ __cheri_compartment("static_sealing_test") void test_static_sealing(); __cheri_compartment("stdio_test") void test_stdio(); __cheri_compartment("debug_test") void test_debug_cxx(); __cheri_compartment("debug_test") void test_debug_c(); +__cheri_compartment("bigdata_test") void test_big_data(); // Simple tests don't need a separate compartment. void test_global_constructors(); diff --git a/tests/xmake.lua b/tests/xmake.lua index 2f9e5ed5..df52e86b 100644 --- a/tests/xmake.lua +++ b/tests/xmake.lua @@ -57,6 +57,7 @@ test("stdio") -- Test the debug helpers. test("debug") add_files("debug-test.c") +-- test("bigdata") -- Test the static sealing types test("static_sealing") compartment("static_sealing_inner")