1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, copy, 8 * modify, merge, publish, distribute, sublicense, and/or sell copies 9 * of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25 #include <endian.h> 26 #include <stdarg.h> 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 31 #include <map> 32 33 #include <base/debug/stack_trace.h> 34 35 #include <libavb/libavb.h> 36 37 int avb_memcmp(const void* src1, const void* src2, size_t n) { 38 return memcmp(src1, src2, n); 39 } 40 41 void* avb_memcpy(void* dest, const void* src, size_t n) { 42 return memcpy(dest, src, n); 43 } 44 45 void* avb_memset(void* dest, const int c, size_t n) { 46 return memset(dest, c, n); 47 } 48 49 int avb_strcmp(const char* s1, const char* s2) { 50 return strcmp(s1, s2); 51 } 52 53 size_t avb_strlen(const char* str) { 54 return strlen(str); 55 } 56 57 void avb_abort(void) { 58 abort(); 59 } 60 61 void avb_print(const char* message) { 62 fprintf(stderr, "%s", message); 63 } 64 65 void avb_printv(const char* message, ...) { 66 va_list ap; 67 const char* m; 68 69 va_start(ap, message); 70 for (m = message; m != NULL; m = va_arg(ap, const char*)) { 71 fprintf(stderr, "%s", m); 72 } 73 va_end(ap); 74 } 75 76 typedef struct { 77 size_t size; 78 base::debug::StackTrace stack_trace; 79 } AvbAllocatedBlock; 80 81 static std::map<void*, AvbAllocatedBlock> allocated_blocks; 82 83 void* avb_malloc_(size_t size) { 84 void* ptr = malloc(size); 85 avb_assert(ptr != nullptr); 86 AvbAllocatedBlock block; 87 block.size = size; 88 allocated_blocks[ptr] = block; 89 return ptr; 90 } 91 92 void avb_free(void* ptr) { 93 auto block_it = allocated_blocks.find(ptr); 94 if (block_it == allocated_blocks.end()) { 95 avb_fatal("Tried to free pointer to non-allocated block.\n"); 96 return; 97 } 98 allocated_blocks.erase(block_it); 99 free(ptr); 100 } 101 102 namespace avb { 103 104 void testing_memory_reset() { 105 allocated_blocks.clear(); 106 } 107 108 bool testing_memory_all_freed() { 109 if (allocated_blocks.size() == 0) { 110 return true; 111 } 112 113 size_t sum = 0; 114 for (const auto& block_it : allocated_blocks) { 115 sum += block_it.second.size; 116 } 117 fprintf(stderr, 118 "%zd bytes still allocated in %zd blocks:\n", 119 sum, 120 allocated_blocks.size()); 121 size_t n = 0; 122 for (const auto& block_it : allocated_blocks) { 123 fprintf(stderr, 124 "--\nAllocation %zd/%zd of %zd bytes:\n", 125 1 + n++, 126 allocated_blocks.size(), 127 block_it.second.size); 128 block_it.second.stack_trace.Print(); 129 } 130 return false; 131 } 132 133 // Also check leaks at process exit. 134 __attribute__((destructor)) static void ensure_all_memory_freed_at_exit() { 135 if (!testing_memory_all_freed()) { 136 avb_fatal("libavb memory leaks at process exit.\n"); 137 } 138 } 139 140 } // namespace avb 141