From: David Given Date: Wed, 20 Jan 2016 22:32:12 +0000 (+0100) Subject: Fix alignment issues primarily with the malloc() alignment payload. X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=3ffaaab316ac9b0165f7df0ad36d80322d67b238;p=FUZIX.git Fix alignment issues primarily with the malloc() alignment payload. --- diff --git a/Library/libs/error.c b/Library/libs/error.c index 7cdc5303..e3281f3f 100644 --- a/Library/libs/error.c +++ b/Library/libs/error.c @@ -11,6 +11,7 @@ #include #include #include +#include "malloc-l.h" static uint8_t *__sys_errlist; static uint16_t *__sys_errptr; @@ -25,7 +26,7 @@ static void _load_errlist(void) return; if (fstat(fd, &st) < 0 || !S_ISREG(st.st_mode)) goto bad; - __sys_errlist = sbrk((st.st_size + 3)&~3); + __sys_errlist = sbrk(ALIGNUP(st.st_size)); if (__sys_errlist == (void *) -1) goto bad; if (read(fd,__sys_errlist, st.st_size) == st.st_size) { diff --git a/Library/libs/free.c b/Library/libs/free.c index 1fd24485..021868a5 100644 --- a/Library/libs/free.c +++ b/Library/libs/free.c @@ -135,8 +135,13 @@ void *__mini_malloc(size_t size) if (size == 0) return 0; + /* Ensure size is aligned, otherwise our memory nodes become unaligned + * and we get hard-to-debug errors on platforms which require + * aligned accesses. */ + size = ALIGNUP(size + sizeof(struct mem_cell)); + /* Minor oops here, sbrk has a signed argument */ - if (size > (((unsigned) -1) >> 1) - sizeof(struct mem_cell) * 3) { + if (size > (((unsigned) -1) >> 1) - sizeof(struct mem_cell) * 2) { nomem:errno = ENOMEM; return 0; } diff --git a/Library/libs/malloc-l.h b/Library/libs/malloc-l.h index 42ad35d0..b8af5131 100644 --- a/Library/libs/malloc-l.h +++ b/Library/libs/malloc-l.h @@ -14,6 +14,26 @@ #define __MINI_MALLOC__ +union maximally_aligned { + uint8_t b; + uint16_t s; + uint32_t i; + #if !defined(NO_64BIT) + uint64_t l; + #endif + float f; + double d; +}; + +struct malloc_alignment_tester +{ + char b; + union maximally_aligned u; +}; + +#define ALIGNMENT ((int)&(((struct malloc_alignment_tester*)NULL)->u)) +#define ALIGNUP(s) (((s) + ALIGNMENT - 1) & ~(ALIGNMENT - 1)) + #define MCHUNK 512 /* Allocation unit in 'mem' elements */ #undef LAZY_FREE /* If set frees can be infinitly defered */ #undef MINALLOC /* 32 */ /* Smallest chunk to alloc in 'mem's */ @@ -29,9 +49,10 @@ #endif typedef struct mem_cell { - struct mem_cell *next; /* A pointer to the next mem */ - unsigned int size; /* An int >= sizeof pointer */ - char *depth; /* For the alloca hack */ + struct mem_cell *next; /* A pointer to the next mem */ + unsigned int size; /* An int >= sizeof pointer */ + char *depth; /* For the alloca hack */ + union maximally_aligned padding[0]; /* Ensures alignment of payload */ } mem; #define m_size(p) ((p)[0].size) /* For malloc */ diff --git a/Library/libs/malloc.c b/Library/libs/malloc.c index 6b735a07..72b6a7d9 100644 --- a/Library/libs/malloc.c +++ b/Library/libs/malloc.c @@ -24,12 +24,10 @@ void *malloc(size_t size) if (size == 0) return 0; /* ANSI STD */ - /* Ensure size is aligned, otherwise our memory nodes become unaligned - * and we get hard-to-debug errors on platforms which require - * aligned accesses. */ - size = (size + sizeof(void*) - 1) & ~(sizeof(void*) - 1); - - sz = size + sizeof(struct mem_cell); + /* Ensure the size is aligned, otherwise our memory nodes become unaligned + * and we get hard-to-debug errors on platforms which require aligned + * accesses. */ + sz = ALIGNUP(size + sizeof(struct mem_cell)); #ifdef MINALLOC if (sz < MINALLOC)