Aaron Durbin submitted this change.

View Change

Approvals: build bot (Jenkins): Verified Aaron Durbin: Looks good to me, approved
lib/malloc: Implement a simple free() only for last malloc()

Implement a free() that supports only the last malloc(). Rewind
the heap to the last allocation point if the ptr to be freed is
matching the end of heap before last malloc(). With current situation,
since free() is no-op, every call to malloc() is a memory leak.

BUG=b:140124451
TEST=Wrote a test function to do malloc and free operations.

Change-Id: I6d43cf54b79e6897cf6882335730b2310e4eae45
Signed-off-by: Bora Guvendik <bora.guvendik@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/37919
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
---
M src/include/stdlib.h
M src/lib/malloc.c
2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/src/include/stdlib.h b/src/include/stdlib.h
index a8297f8..f6369bf 100644
--- a/src/include/stdlib.h
+++ b/src/include/stdlib.h
@@ -5,7 +5,6 @@

void *memalign(size_t boundary, size_t size);
void *malloc(size_t size);
-/* We never free memory */
-static inline void free(void *ptr) {}
+void free(void *ptr);

#endif /* STDLIB_H */
diff --git a/src/lib/malloc.c b/src/lib/malloc.c
index aa266b4..ddc7ea5 100644
--- a/src/lib/malloc.c
+++ b/src/lib/malloc.c
@@ -11,6 +11,8 @@
extern unsigned char _heap, _eheap;
static void *free_mem_ptr = &_heap; /* Start of heap */
static void *free_mem_end_ptr = &_eheap; /* End of heap */
+static void *free_last_alloc_ptr = &_heap; /* End of heap before
+ last allocation */

/* We don't restrict the boundary. This is firmware,
* you are supposed to know what you are doing.
@@ -26,6 +28,12 @@

p = free_mem_ptr;
free_mem_ptr += size;
+ /*
+ * Store last allocation pointer after ALIGN, as malloc() will
+ * return it. This may cause n bytes of gap between allocations
+ * where n < boundary.
+ */
+ free_last_alloc_ptr = p;

if (free_mem_ptr >= free_mem_end_ptr) {
printk(BIOS_ERR, "memalign(boundary=%zu, size=%zu): failed: ",
@@ -46,3 +54,24 @@
{
return memalign(sizeof(u64), size);
}
+
+void free(void *ptr)
+{
+ if (ptr == NULL)
+ return;
+
+ if (ptr < (void *)&_heap || ptr >= free_mem_end_ptr) {
+ printk(BIOS_WARNING, "Warning - Pointer passed to %s is not "
+ "pointing to the heap\n", __func__);
+ return;
+ }
+
+ /*
+ * Rewind the heap pointer to the end of heap
+ * before the last successful malloc().
+ */
+ if (ptr == free_last_alloc_ptr) {
+ free_mem_ptr = free_last_alloc_ptr;
+ free_last_alloc_ptr = NULL;
+ }
+}

To view, visit change 37919. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I6d43cf54b79e6897cf6882335730b2310e4eae45
Gerrit-Change-Number: 37919
Gerrit-PatchSet: 11
Gerrit-Owner: Bora Guvendik <bora.guvendik@intel.com>
Gerrit-Reviewer: Aaron Durbin <adurbin@chromium.org>
Gerrit-Reviewer: Bora Guvendik <bora.guvendik@intel.com>
Gerrit-Reviewer: Selma Bensaid <selma.bensaid@intel.com>
Gerrit-Reviewer: Subrata Banik <subrata.banik@intel.com>
Gerrit-Reviewer: Thejaswani Putta <thejaswani.putta@intel.com>
Gerrit-Reviewer: build bot (Jenkins) <no-reply@coreboot.org>
Gerrit-CC: Patrick Rudolph <siro@das-labor.org>
Gerrit-CC: Paul Menzel <paulepanter@users.sourceforge.net>
Gerrit-MessageType: merged