Fix alignment issues primarily with the malloc() alignment payload.
authorDavid Given <dg@cowlark.com>
Wed, 20 Jan 2016 22:32:12 +0000 (23:32 +0100)
committerDavid Given <dg@cowlark.com>
Wed, 20 Jan 2016 22:32:12 +0000 (23:32 +0100)
Library/libs/error.c
Library/libs/free.c
Library/libs/malloc-l.h
Library/libs/malloc.c

index 7cdc530..e3281f3 100644 (file)
@@ -11,6 +11,7 @@
 #include <paths.h>
 #include <errno.h>
 #include <fcntl.h>
+#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) {
index 1fd2448..021868a 100644 (file)
@@ -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;
        }
index 42ad35d..b8af513 100644 (file)
 \r
 #define __MINI_MALLOC__\r
 \r
+union maximally_aligned {\r
+       uint8_t b;\r
+       uint16_t s;\r
+       uint32_t i;\r
+       #if !defined(NO_64BIT)\r
+               uint64_t l;\r
+       #endif\r
+       float f;\r
+       double d;\r
+};\r
+\r
+struct malloc_alignment_tester\r
+{\r
+       char b;\r
+       union maximally_aligned u;\r
+};\r
+\r
+#define ALIGNMENT ((int)&(((struct malloc_alignment_tester*)NULL)->u))\r
+#define ALIGNUP(s) (((s) + ALIGNMENT - 1) & ~(ALIGNMENT - 1))\r
+\r
 #define MCHUNK         512     /* Allocation unit in 'mem' elements */\r
 #undef LAZY_FREE               /* If set frees can be infinitly defered */\r
 #undef MINALLOC        /* 32 */        /* Smallest chunk to alloc in 'mem's */\r
 #endif\r
 \r
 typedef struct mem_cell {\r
-       struct mem_cell *next;  /* A pointer to the next mem */\r
-       unsigned int size;      /* An int >= sizeof pointer */\r
-       char *depth;            /* For the alloca hack */\r
+       struct mem_cell *next;              /* A pointer to the next mem */\r
+       unsigned int size;                  /* An int >= sizeof pointer */\r
+       char *depth;                        /* For the alloca hack */\r
+       union maximally_aligned padding[0]; /* Ensures alignment of payload */\r
 } mem;\r
 \r
 #define m_size(p)  ((p)[0].size)               /* For malloc */\r
index 6b735a0..72b6a7d 100644 (file)
@@ -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)