[OpenBIOS] [PATCH 1/6] Fix alignment of memory allocated by OFMEM's ofmem_malloc().

Mark Cave-Ayland mark.cave-ayland at siriusit.co.uk
Wed Dec 29 12:07:57 CET 2010


A casual glance at the source code suggests that pointers returned by ofmem_malloc() are aligned, but in fact they are not
because sizeof(alloc_desc_t) is added to the final pointer return value. Create some additional padding after the previous value
of ofmem->next_malloc so we can store the alloc_desc_t underneath the final return pointer in memory, thus ensuring that the
final pointer is aligned correctly.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at siriusit.co.uk>
---
 openbios-devel/libopenbios/ofmem_common.c |   21 +++++++++++++--------
 1 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/openbios-devel/libopenbios/ofmem_common.c b/openbios-devel/libopenbios/ofmem_common.c
index 20a4cba..bd0833f 100644
--- a/openbios-devel/libopenbios/ofmem_common.c
+++ b/openbios-devel/libopenbios/ofmem_common.c
@@ -28,9 +28,14 @@
 //#define OFMEM_FILL_RANGE
 
 
-static inline size_t ALIGN_SIZE(size_t x, size_t a)
+static inline size_t align_size(size_t x, size_t a)
 {
-    return (x + a - 1) & ~(a-1);
+    return (x + a - 1) & ~(a - 1);
+}
+
+static inline void * align_ptr(uintptr_t x, size_t a)
+{
+    return (void *)((x + a - 1) & ~(a - 1));
 }
 
 static ucell get_ram_size( void )
@@ -85,7 +90,7 @@ void* ofmem_malloc( size_t size )
 {
 	ofmem_t *ofmem = ofmem_arch_get_private();
 	alloc_desc_t *d, **pp;
-	char *ret;
+	void *ret;
 	ucell top;
 
 	if( !size )
@@ -94,7 +99,7 @@ void* ofmem_malloc( size_t size )
 	if( !ofmem->next_malloc )
 		ofmem->next_malloc = (char*)ofmem_arch_get_malloc_base();
 
-	size = ALIGN_SIZE(size + sizeof(alloc_desc_t), CONFIG_OFMEM_MALLOC_ALIGN);
+	size = align_size(size + sizeof(alloc_desc_t), CONFIG_OFMEM_MALLOC_ALIGN);
 
 	/* look in the freelist */
 	for( pp=&ofmem->mfree; *pp && (**pp).size < size; pp = &(**pp).next ) {
@@ -102,7 +107,7 @@ void* ofmem_malloc( size_t size )
 
 	/* waste at most 4K by taking an entry from the freelist */
 	if( *pp && (**pp).size < size + 0x1000 ) {
-		ret = (char*)*pp + sizeof(alloc_desc_t);
+		ret = (void *)((uintptr_t)*pp + sizeof(alloc_desc_t));
 		memset( ret, 0, (**pp).size - sizeof(alloc_desc_t) );
 		*pp = (**pp).next;
 		return ret;
@@ -110,18 +115,18 @@ void* ofmem_malloc( size_t size )
 
 	top = ofmem_arch_get_heap_top();
 
-	if( pointer2cell(ofmem->next_malloc) + size > top ) {
+	ret = align_ptr((uintptr_t)ofmem->next_malloc + sizeof(alloc_desc_t), CONFIG_OFMEM_MALLOC_ALIGN);
+	if( pointer2cell(ret) + size > top ) {
 		printk("out of malloc memory (%x)!\n", size );
 		return NULL;
 	}
 
-	d = (alloc_desc_t*) ofmem->next_malloc;
+	d = (alloc_desc_t*)((uintptr_t)ret - sizeof(alloc_desc_t));
 	ofmem->next_malloc += size;
 
 	d->next = NULL;
 	d->size = size;
 
-	ret = (char*)d + sizeof(alloc_desc_t);
 	memset( ret, 0, size - sizeof(alloc_desc_t) );
 
 	return ret;
-- 
1.7.2.3




More information about the OpenBIOS mailing list