10f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen/*
20f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * Copyright (C) 2017 The Android Open Source Project
30f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen *
40f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * Permission is hereby granted, free of charge, to any person
50f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * obtaining a copy of this software and associated documentation
60f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * files (the "Software"), to deal in the Software without
70f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * restriction, including without limitation the rights to use, copy,
80f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * modify, merge, publish, distribute, sublicense, and/or sell copies
90f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * of the Software, and to permit persons to whom the Software is
100f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * furnished to do so, subject to the following conditions:
110f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen *
120f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * The above copyright notice and this permission notice shall be
130f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * included in all copies or substantial portions of the Software.
140f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen *
150f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
160f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
170f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
180f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
190f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
200f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
210f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
220f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen * SOFTWARE.
230f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen */
240f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
250f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen#include <endian.h>
260f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen#include <stdarg.h>
270f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen#include <stdio.h>
280f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen#include <stdlib.h>
290f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen#include <string.h>
300f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
310f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen#include <map>
320f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
330f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen#include <base/debug/stack_trace.h>
340f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
350f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen#include <libavb/libavb.h>
360f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
370f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthenint avb_memcmp(const void* src1, const void* src2, size_t n) {
380f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  return memcmp(src1, src2, n);
390f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen}
400f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
410f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthenvoid* avb_memcpy(void* dest, const void* src, size_t n) {
420f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  return memcpy(dest, src, n);
430f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen}
440f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
450f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthenvoid* avb_memset(void* dest, const int c, size_t n) {
460f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  return memset(dest, c, n);
470f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen}
480f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
490f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthenint avb_strcmp(const char* s1, const char* s2) {
500f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  return strcmp(s1, s2);
510f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen}
520f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
530f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthensize_t avb_strlen(const char* str) {
540f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  return strlen(str);
550f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen}
560f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
570f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthenvoid avb_abort(void) {
580f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  abort();
590f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen}
600f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
610f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthenvoid avb_print(const char* message) {
620f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  fprintf(stderr, "%s", message);
630f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen}
640f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
650f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthenvoid avb_printv(const char* message, ...) {
660f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  va_list ap;
670f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  const char* m;
680f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
690f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  va_start(ap, message);
700f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  for (m = message; m != NULL; m = va_arg(ap, const char*)) {
710f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen    fprintf(stderr, "%s", m);
720f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  }
730f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  va_end(ap);
740f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen}
750f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
760f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthentypedef struct {
770f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  size_t size;
780f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  base::debug::StackTrace stack_trace;
790f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen} AvbAllocatedBlock;
800f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
810f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthenstatic std::map<void*, AvbAllocatedBlock> allocated_blocks;
820f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
830f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthenvoid* avb_malloc_(size_t size) {
840f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  void* ptr = malloc(size);
850f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  avb_assert(ptr != nullptr);
860f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  AvbAllocatedBlock block;
870f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  block.size = size;
880f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  allocated_blocks[ptr] = block;
890f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  return ptr;
900f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen}
910f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
920f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthenvoid avb_free(void* ptr) {
930f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  auto block_it = allocated_blocks.find(ptr);
940f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  if (block_it == allocated_blocks.end()) {
950f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen    avb_fatal("Tried to free pointer to non-allocated block.\n");
960f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen    return;
970f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  }
980f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  allocated_blocks.erase(block_it);
990f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  free(ptr);
1000f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen}
1010f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
1020f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthennamespace avb {
1030f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
1040f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthenvoid testing_memory_reset() {
1050f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  allocated_blocks.clear();
1060f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen}
1070f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
1080f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthenbool testing_memory_all_freed() {
1090f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  if (allocated_blocks.size() == 0) {
1100f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen    return true;
1110f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  }
1120f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
1130f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  size_t sum = 0;
1140f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  for (const auto& block_it : allocated_blocks) {
1150f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen    sum += block_it.second.size;
1160f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  }
1170f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  fprintf(stderr,
1180f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen          "%zd bytes still allocated in %zd blocks:\n",
1190f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen          sum,
1200f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen          allocated_blocks.size());
1210f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  size_t n = 0;
1220f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  for (const auto& block_it : allocated_blocks) {
1230f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen    fprintf(stderr,
1240f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen            "--\nAllocation %zd/%zd of %zd bytes:\n",
1250f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen            1 + n++,
1260f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen            allocated_blocks.size(),
1270f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen            block_it.second.size);
1280f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen    block_it.second.stack_trace.Print();
1290f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  }
1300f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  return false;
1310f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen}
1320f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
1330f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen// Also check leaks at process exit.
1340f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen__attribute__((destructor)) static void ensure_all_memory_freed_at_exit() {
1350f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  if (!testing_memory_all_freed()) {
1360f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen    avb_fatal("libavb memory leaks at process exit.\n");
1370f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen  }
1380f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen}
1390f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen
1400f7de9479afef18835cdbfe3da07811a7993504eDavid Zeuthen}  // namespace avb
141