}
END_TEST
+/*******************************************************************************
+ * mallac_align/free_align
+ */
+
+START_TEST(test_malloc_align)
+{
+ void *ptr[128][256];
+ int size, align;
+
+ for (size = 0; size < countof(ptr); size++)
+ {
+ for (align = 0; align < countof(ptr[0]); align++)
+ {
+ ptr[size][align] = malloc_align(size, align);
+ if (align)
+ {
+ ck_assert((uintptr_t)ptr[size][align] % align == 0);
+ }
+ if (size)
+ {
+ ck_assert(ptr[size][align]);
+ memset(ptr[size][align], 0xEF, size);
+ }
+ }
+ }
+ for (size = 0; size < countof(ptr); size++)
+ {
+ for (align = 0; align < countof(ptr[0]); align++)
+ {
+ free_align(ptr[size][align]);
+ }
+ }
+}
+END_TEST
+
/*******************************************************************************
* memxor
*/
tcase_add_loop_test(tc, test_strpfx, 0, countof(strpfx_data));
suite_add_tcase(s, tc);
+ tc = tcase_create("malloc_align");
+ tcase_add_test(tc, test_malloc_align);
+ suite_add_tcase(s, tc);
+
tc = tcase_create("memxor");
tcase_add_test(tc, test_memxor);
tcase_add_test(tc, test_memxor_aligned);
"NEED_MORE",
);
+/**
+ * Described in header.
+ */
+void* malloc_align(size_t size, u_int8_t align)
+{
+ u_int8_t pad;
+ void *ptr;
+
+ if (align == 0)
+ {
+ align = 1;
+ }
+ ptr = malloc(align + sizeof(pad) + size);
+ if (!ptr)
+ {
+ return NULL;
+ }
+ /* store padding length just before data, down to the allocation boundary
+ * to do some verification during free_align() */
+ pad = align - ((uintptr_t)ptr % align);
+ memset(ptr, pad, pad);
+ return ptr + pad;
+}
+
+/**
+ * Described in header.
+ */
+void free_align(void *ptr)
+{
+ u_int8_t pad, *pos;
+
+ pos = ptr - 1;
+ /* verify padding to check any corruption */
+ for (pad = *pos; (void*)pos >= ptr - pad; pos--)
+ {
+ if (*pos != pad)
+ {
+ DBG1(DBG_LIB, "!!!! invalid free_align() !!!!");
+ return;
+ }
+ }
+ free(ptr - pad);
+}
+
/**
* Described in header.
*/
*/
typedef struct sockaddr sockaddr_t;
+/**
+ * malloc(), but returns aligned memory.
+ *
+ * The returned pointer must be freed using free_align(), not free().
+ *
+ * @param size size of allocated data
+ * @param align alignment, up to 255 bytes, usually a power of 2
+ * @return allocated hunk, aligned to align bytes
+ */
+void* malloc_align(size_t size, u_int8_t align);
+
+/**
+ * Free a hunk allocated by malloc_align().
+ *
+ * @param ptr hunk to free
+ */
+void free_align(void *ptr);
+
/**
* Same as memcpy, but XORs src into dst instead of copy
*/