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 uint32_t avb_div_by_10(uint64_t* dividend) { 103 uint32_t rem = (uint32_t)(*dividend % 10); 104 *dividend /= 10; 105 return rem; 106 } 107 108 namespace avb { 109 110 void testing_memory_reset() { 111 allocated_blocks.clear(); 112 } 113 114 bool testing_memory_all_freed() { 115 if (allocated_blocks.size() == 0) { 116 return true; 117 } 118 119 size_t sum = 0; 120 for (const auto& block_it : allocated_blocks) { 121 sum += block_it.second.size; 122 } 123 fprintf(stderr, 124 "%zd bytes still allocated in %zd blocks:\n", 125 sum, 126 allocated_blocks.size()); 127 size_t n = 0; 128 for (const auto& block_it : allocated_blocks) { 129 fprintf(stderr, 130 "--\nAllocation %zd/%zd of %zd bytes:\n", 131 1 + n++, 132 allocated_blocks.size(), 133 block_it.second.size); 134 block_it.second.stack_trace.Print(); 135 } 136 return false; 137 } 138 139 // Also check leaks at process exit. 140 __attribute__((destructor)) static void ensure_all_memory_freed_at_exit() { 141 if (!testing_memory_all_freed()) { 142 avb_fatal("libavb memory leaks at process exit.\n"); 143 } 144 } 145 146 } // namespace avb 147