X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/eb6b6ca394357805f2bdba989abae309f718b4d8..f427ee49d309d8fc33ebf3042c3a775f2f530ded:/tests/bounded_ptr_src/example.malloc.cpp diff --git a/tests/bounded_ptr_src/example.malloc.cpp b/tests/bounded_ptr_src/example.malloc.cpp new file mode 100644 index 000000000..c8a53afeb --- /dev/null +++ b/tests/bounded_ptr_src/example.malloc.cpp @@ -0,0 +1,75 @@ +// +// Example of providing a malloc() wrapper that returns a `bounded_ptr`. +// +// This test serves as some kind of integration test, ensuring that we're +// able to convert existing code using raw pointers to using `bounded_ptr`s +// without too much hassle. This code was lifted from existing code in XNU, +// and the variable names were changed to make it more generic. +// + +#include +#include +#include +#include +#include +#include "test_utils.h" + +test_bounded_ptr +bounded_malloc(std::size_t size) +{ + void* p = std::malloc(size); + void* end = static_cast(p) + size; + test_bounded_ptr with_bounds(p, p, end); + return with_bounds; +} + +void +bounded_free(test_bounded_ptr ptr) +{ + std::free(ptr.discard_bounds()); +} + +struct SomeType { + std::uint32_t idx; +}; + +// Pretend that those functions are already part of the code base being +// transitioned over to `bounded_ptr`s, and we can't change their signature. +// The purpose of having those functions is to make sure that we're able to +// integrate into existing code bases with decent ease. +void +use(SomeType*) +{ +} +void +require(bool condition) +{ + if (!condition) { + std::exit(EXIT_FAILURE); + } +} + +T_DECL(example_malloc, "bounded_ptr.example.malloc") { + test_bounded_ptr array = nullptr; + std::uint32_t count = 100; + std::uint32_t alloc_size = count * sizeof(SomeType); + + // (1) must use a bounded version of malloc + // (2) must use a reinterpret_pointer_cast to go from void* to SomeType* + array = libkern::reinterpret_pointer_cast(bounded_malloc(alloc_size)); + + require(array != nullptr); // use != nullptr instead of relying on implicit conversion to bool + use(array.discard_bounds()); // must manually discard bounds here + + for (std::uint32_t i = 0; i < count; i++) { + std::uint32_t& idx = array[i].idx; + idx = i; + use(&array[idx]); + } + + if (array) { + bounded_free(array); // must use a bounded version of free + } + + T_PASS("bounded_ptr.example.malloc test done"); +}