diff options
Diffstat (limited to 'firmware/stub/vboot_api_stub_sf.c')
-rw-r--r-- | firmware/stub/vboot_api_stub_sf.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/firmware/stub/vboot_api_stub_sf.c b/firmware/stub/vboot_api_stub_sf.c index e2f1c1ae..3c5ec85a 100644 --- a/firmware/stub/vboot_api_stub_sf.c +++ b/firmware/stub/vboot_api_stub_sf.c @@ -5,6 +5,7 @@ * Stub implementations of firmware-provided API functions. */ +#include <execinfo.h> #include <stdint.h> #define _STUB_IMPLEMENTATION_ @@ -17,18 +18,81 @@ #include "vboot_api.h" +#define MAX_STACK_LEVELS 10 + + +/* Keep track of nodes that are currently allocated */ +struct alloc_node { + struct alloc_node *next; + void *ptr; + size_t size; + void *bt_buffer[MAX_STACK_LEVELS]; + int bt_levels; +}; + +static struct alloc_node *alloc_head; + +static void print_stacktrace(void) +{ + void *buffer[MAX_STACK_LEVELS]; + int levels = backtrace(buffer, MAX_STACK_LEVELS); + + // print to stderr (fd = 2), and remove this function from the trace + backtrace_symbols_fd(buffer + 1, levels - 1, 2); +} + void *VbExMalloc(size_t size) { + struct alloc_node *node; void *p = malloc(size); + if (!p) { /* Fatal Error. We must abort. */ abort(); } + + node = malloc(sizeof(*node)); + if (!node) + abort(); + node->next = alloc_head; + node->ptr = p; + node->size = size; + node->bt_levels = backtrace(node->bt_buffer, MAX_STACK_LEVELS); + alloc_head = node; + return p; } +static struct alloc_node **find_node(void *ptr) +{ + struct alloc_node **nodep; + + for (nodep = &alloc_head; *nodep; nodep = &(*nodep)->next) + if ((*nodep)->ptr == ptr) + return nodep; + + return NULL; +} + void VbExFree(void *ptr) { + struct alloc_node **nodep, *next; + + nodep = find_node(ptr); + if (nodep) { + next = (*nodep)->next; + free(*nodep); + *nodep = next; + } else { + fprintf(stderr, "\n>>>>>> Invalid VbExFree() %p\n", ptr); + fflush(stderr); + print_stacktrace(); + /* + * Fall through and do the free() so we get normal error + * handling. + */ + } + free(ptr); } @@ -37,3 +101,27 @@ VbError_t VbExHashFirmwareBody(VbCommonParams *cparams, { return VBERROR_SUCCESS; } + +int vboot_api_stub_check_memory(void) +{ + struct alloc_node *node, *next; + + if (!alloc_head) + return 0; + + /* + * Make sure we free all our memory so that valgrind doesn't complain + * about leaked memory. + */ + fprintf(stderr, "\nWarning, some allocations not freed:"); + for (node = alloc_head; node; node = next) { + next = node->next; + fprintf(stderr, "\nptr=%p, size=%zd\n", node->ptr, node->size); + fflush(stderr); + backtrace_symbols_fd(node->bt_buffer + 1, node->bt_levels - 1, + 2); + free(node); + } + + return -1; +} |