Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | // // pgm_testing.h // libmalloc // // Shared testing code for ProbGuard. // #ifndef _PGM_TESTING_H_ #define _PGM_TESTING_H_ #pragma mark - #pragma mark Mocks #define PGM_MOCK_RANDOM static uint32_t expected_upper_bound; static uint32_t rand_ret_value; static uint32_t rand_ret_values[10]; static uint32_t rand_call_count; static bool rand_use_ret_values; static uint32_t rand_uniform(uint32_t upper_bound) { T_QUIET; T_EXPECT_EQ(upper_bound, expected_upper_bound, "rand_uniform(upper_bound)"); if (rand_use_ret_values) { T_QUIET; T_ASSERT_LT(rand_call_count, 10, NULL); rand_ret_value = rand_ret_values[rand_call_count]; } rand_call_count++; return rand_ret_value; } #define PGM_MOCK_TRACE_COLLECT static uint8_t *expected_trace_buffers[3]; static size_t expected_trace_sizes[3]; static uint32_t capture_trace_call_count; static size_t collect_trace_ret_value; MALLOC_ALWAYS_INLINE static inline size_t my_trace_collect(uint8_t *buffer, size_t size) { T_QUIET; T_ASSERT_LT(capture_trace_call_count, 3, NULL); T_QUIET; T_EXPECT_EQ(buffer, expected_trace_buffers[capture_trace_call_count], "my_trace_collect(buffer)"); T_QUIET; T_EXPECT_EQ(size, expected_trace_sizes[capture_trace_call_count], "my_trace_collect(size)"); capture_trace_call_count++; return collect_trace_ret_value; } #define PGM_MOCK_PAGE_ACCESS static vm_address_t expected_inaccessible_page; static vm_address_t expected_read_write_page; static void mark_inaccessible(vm_address_t page) { T_QUIET; T_EXPECT_EQ(page, expected_inaccessible_page, "mark_inaccessible(page)"); } static void mark_read_write(vm_address_t page) { T_QUIET; T_EXPECT_EQ(page, expected_read_write_page, "mark_read_write(page)"); } static vm_address_t expected_cause; static const char *expected_msg; static void report_fatal_error(vm_address_t addr, const char *msg) { T_QUIET; T_EXPECT_EQ(addr, expected_cause, "MALLOC_REPORT_FATAL_ERROR(): cause"); T_QUIET; T_EXPECT_EQ(msg, expected_msg, "MALLOC_REPORT_FATAL_ERROR(): message"); } #undef MALLOC_REPORT_FATAL_ERROR #define MALLOC_REPORT_FATAL_ERROR(cause, message) \ report_fatal_error(cause, message); \ T_END #undef memcpy static vm_address_t expected_dest; static vm_address_t expected_src; static size_t expected_size; static void memcpy(void *dest, void *src, size_t size) { T_QUIET; T_EXPECT_EQ(dest, (void *)expected_dest, "memcpy(): dest"); T_QUIET; T_EXPECT_EQ(src, (void *)expected_src, "memcpy(): src"); T_QUIET; T_EXPECT_EQ(size, expected_size, "memcpy(): size"); } #pragma mark - #pragma mark Wrapped Zone Mocks static malloc_zone_t wrapped_zone; static vm_address_t expected_size_ptr; static size_t size_ret_value; static size_t wrapped_size(malloc_zone_t *zone, const void *ptr) { T_QUIET; T_EXPECT_EQ(zone, &wrapped_zone, "wrapped_size(): zone"); T_QUIET; T_EXPECT_EQ(ptr, (void *)expected_size_ptr, "wrapped_size(): ptr"); return size_ret_value; } static size_t expected_malloc_size; static vm_address_t malloc_ret_value; static void * wrapped_malloc(malloc_zone_t *zone, size_t size) { T_QUIET; T_EXPECT_EQ(zone, &wrapped_zone, "wrapped_malloc(): zone"); T_QUIET; T_EXPECT_EQ(size, expected_malloc_size, "wrapped_malloc(): size"); return (void *)malloc_ret_value; } static vm_address_t expected_free_ptr; static void wrapped_free(malloc_zone_t *zone, void *ptr) { T_QUIET; T_EXPECT_EQ(zone, &wrapped_zone, "wrapped_free(): zone"); T_QUIET; T_EXPECT_EQ(ptr, (void *)expected_free_ptr, "wrapped_free(): ptr"); } static malloc_zone_t wrapped_zone = { .size = wrapped_size, .malloc = wrapped_malloc, .free = wrapped_free }; #pragma mark - #pragma mark Test Harness #include "../src/pgm_malloc.c" // Dependencies #include "../src/has_section.c" #include "../src/malloc_common.c" #include "../src/stack_trace.c" #include "../src/wrapper_zones.c" static slot_t slots[10]; static metadata_t metadata[10]; static pgm_zone_t zone = { .wrapped_zone = &wrapped_zone, .slots = slots, .metadata = metadata }; // Stub out cross-file dependencies. void malloc_report(uint32_t flags, const char *fmt, ...) { __builtin_trap(); } void malloc_report_simple(const char *fmt, ...) { __builtin_trap(); } #endif // _PGM_TESTING_H_ |