]> git.saurik.com Git - apple/xnu.git/blame - tests/bounded_ptr_src/example.malloc.cpp
xnu-7195.101.1.tar.gz
[apple/xnu.git] / tests / bounded_ptr_src / example.malloc.cpp
CommitLineData
f427ee49
A
1//
2// Example of providing a malloc() wrapper that returns a `bounded_ptr`.
3//
4// This test serves as some kind of integration test, ensuring that we're
5// able to convert existing code using raw pointers to using `bounded_ptr`s
6// without too much hassle. This code was lifted from existing code in XNU,
7// and the variable names were changed to make it more generic.
8//
9
10#include <libkern/c++/bounded_ptr.h>
11#include <cstddef>
12#include <cstdint>
13#include <cstdlib>
14#include <darwintest.h>
15#include "test_utils.h"
16
17test_bounded_ptr<void>
18bounded_malloc(std::size_t size)
19{
20 void* p = std::malloc(size);
21 void* end = static_cast<char*>(p) + size;
22 test_bounded_ptr<void> with_bounds(p, p, end);
23 return with_bounds;
24}
25
26void
27bounded_free(test_bounded_ptr<void> ptr)
28{
29 std::free(ptr.discard_bounds());
30}
31
32struct SomeType {
33 std::uint32_t idx;
34};
35
36// Pretend that those functions are already part of the code base being
37// transitioned over to `bounded_ptr`s, and we can't change their signature.
38// The purpose of having those functions is to make sure that we're able to
39// integrate into existing code bases with decent ease.
40void
41use(SomeType*)
42{
43}
44void
45require(bool condition)
46{
47 if (!condition) {
48 std::exit(EXIT_FAILURE);
49 }
50}
51
52T_DECL(example_malloc, "bounded_ptr.example.malloc") {
53 test_bounded_ptr<SomeType> array = nullptr;
54 std::uint32_t count = 100;
55 std::uint32_t alloc_size = count * sizeof(SomeType);
56
57 // (1) must use a bounded version of malloc
58 // (2) must use a reinterpret_pointer_cast to go from void* to SomeType*
59 array = libkern::reinterpret_pointer_cast<SomeType>(bounded_malloc(alloc_size));
60
61 require(array != nullptr); // use != nullptr instead of relying on implicit conversion to bool
62 use(array.discard_bounds()); // must manually discard bounds here
63
64 for (std::uint32_t i = 0; i < count; i++) {
65 std::uint32_t& idx = array[i].idx;
66 idx = i;
67 use(&array[idx]);
68 }
69
70 if (array) {
71 bounded_free(array); // must use a bounded version of free
72 }
73
74 T_PASS("bounded_ptr.example.malloc test done");
75}