Skip to content

Commit 91973ed

Browse files
author
Nicolas Pitre
committed
tests/lib/heap_align: improve test some more
- Make sure the align-and-rewind feature is explicitly tested. - Clobber memory at allocation edges to catch off-by-one type errors. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
1 parent b7970cc commit 91973ed

File tree

1 file changed

+55
-4
lines changed
  • tests/lib/heap_align/src

1 file changed

+55
-4
lines changed

tests/lib/heap_align/src/main.c

+55-4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,44 @@ uint8_t __aligned(8) heapmem[HEAP_SZ];
1414
/* Heap metadata sizes */
1515
uint8_t *heap_start, *heap_end;
1616

17+
static void fill(void *mem, size_t size)
18+
{
19+
uint32_t *word32 = mem;
20+
21+
/*
22+
* No need to fill the entire memory block. Only touching the edges
23+
* is sufficient to trip heap validation with off-by-one errors.
24+
* Strictly speaking we may overflow the boundary if given size
25+
* is not a multiple of 4 but the actual allocation is always
26+
* rounded up to at least the next 4-byte boundary anyway.
27+
*/
28+
if (size != 0) {
29+
word32[0] = 0;
30+
word32[(size - 1)/4] = 0;
31+
}
32+
}
33+
34+
/*
35+
* The align argument may contain a "rewind" bit.
36+
* See comment in sys_heap_aligned_alloc().
37+
*/
38+
static bool alignment_ok(void *ptr, size_t align)
39+
{
40+
uintptr_t addr = (uintptr_t)ptr;
41+
size_t rew;
42+
43+
/* split rewind bit from alignment */
44+
rew = (align & -align);
45+
rew = (rew == align) ? 0 : rew;
46+
align -= rew;
47+
48+
/* undo the pointer rewind */
49+
addr += rew;
50+
51+
/* validate pointer alignment */
52+
return (addr & (align - 1)) == 0;
53+
}
54+
1755
/* Note that this test is making whitebox assumptions about the
1856
* behavior of the heap in order to exercise coverage of the
1957
* underlying code: that chunk headers are 8 bytes, that heap chunks
@@ -24,25 +62,34 @@ static void check_heap_align(struct sys_heap *h,
2462
size_t prefix, size_t align, size_t size)
2563
{
2664
void *p, *q, *r, *s;
65+
size_t suffix;
2766

2867
p = sys_heap_alloc(h, prefix);
2968
zassert_true(prefix == 0 || p != NULL, "prefix allocation failed");
3069

3170
q = sys_heap_aligned_alloc(h, align, size);
3271
zassert_true(q != NULL, "first aligned allocation failed");
33-
zassert_true((((uintptr_t)q) & (align - 1)) == 0, "block not aligned");
72+
zassert_true(alignment_ok(q, align), "block not aligned");
3473

3574
r = sys_heap_aligned_alloc(h, align, size);
3675
zassert_true(r != NULL, "second aligned allocation failed");
37-
zassert_true((((uintptr_t)r) & (align - 1)) == 0, "block not aligned");
76+
zassert_true(alignment_ok(r, align), "block not aligned");
3877

3978
/* Make sure ALL the split memory goes back into the heap and
4079
* we can allocate the full remaining suffix
4180
*/
42-
s = sys_heap_alloc(h, (heap_end - (uint8_t *)r) - size - 8);
81+
suffix = (heap_end - (uint8_t *)r) - size - 8;
82+
s = sys_heap_alloc(h, suffix);
4383
zassert_true(s != NULL, "suffix allocation failed (%zd/%zd/%zd)",
4484
prefix, align, size);
4585

86+
/* Touch some of the allocated memory */
87+
fill(p, prefix);
88+
fill(q, size);
89+
fill(r, size);
90+
fill(s, suffix);
91+
zassert_true(sys_heap_validate(h), "heap invalid");
92+
4693
sys_heap_free(h, p);
4794
sys_heap_free(h, q);
4895
sys_heap_free(h, r);
@@ -76,8 +123,12 @@ ZTEST(lib_heap_align, test_aligned_alloc)
76123

77124
for (size_t align = 8; align < HEAP_SZ / 4; align *= 2) {
78125
for (size_t prefix = 0; prefix <= align; prefix += 8) {
79-
for (size_t size = 8; size <= align; size += 8) {
126+
for (size_t size = 4; size <= align; size += 12) {
80127
check_heap_align(&heap, prefix, align, size);
128+
for (size_t rew = 4; rew < MIN(align, 32); rew *= 2) {
129+
check_heap_align(&heap, prefix,
130+
align | rew, size);
131+
}
81132
}
82133
}
83134
}

0 commit comments

Comments
 (0)