Add additional segment handling
Fix bug in split_free_chunk when remainder is too small
diff --git a/preload.c b/preload.c
index 841ddbb..19bdd70 100644
--- a/preload.c
+++ b/preload.c
@@ -213,12 +213,11 @@
if (m.seg == NULL) {
m.seg = seg;
} else {
- for (sp = m.seg; sp->next == NULL; sp = sp->next)
+ for (sp = m.seg; sp->next != NULL; sp = sp->next)
;
sp->next = seg;
}
c = next_chunk(c);
- printf("NEXT CHUNK %p\n", c);
c->head = (size_t)(((char *)p + SEG_SIZE) - (char *)c) | PINUSE_BIT;
c->prev_foot = ssize;
DEBUG("next chunk at 0x%p, head=%x, prev=%x\n", c, chunk_size(c), c->prev_foot);
@@ -236,7 +235,6 @@
m.free.fd = &m.free;
m.free.bk = &m.free;
m.seg = NULL;
- alloc_segment();
}
static struct malloc_chunk *find_free(size_t size)
@@ -258,10 +256,13 @@
struct malloc_chunk *new_c, *n;
size_t csize = chunk_size(c);
- if (csize == size) {
+ if (csize - size < pad_request(1)) {
/* nothing to split, just give everything up */
unlink_free_chunk(c);
c->head |= CINUSE_BIT;
+ new_c = next_chunk(c);
+ if (new_c)
+ new_c->head |= PINUSE_BIT;
return;
}
@@ -289,9 +290,9 @@
size = pad_request(size);
c = find_free(size);
if (c == NULL) {
- printf("failed to find free\n");
- /* FIXME ADD MORE */
- return NULL;
+ alloc_segment();
+ c = find_free(size);
+ ASSERT(c != NULL);
}
DEBUG("found chunk 0x%p\n", c);
@@ -304,7 +305,7 @@
void *ret = NULL;
if (size < SEG_SIZE)
ret = dlmalloc(size);
- DEBUG("in crypto malloc from %s:%d =%p\n", file, line, ret);
+ DEBUG("in crypto malloc from %s:%d size=%x ret=%p\n", file, line, size, ret);
show_segment();
return ret;
}
@@ -313,7 +314,7 @@
{
struct malloc_chunk *c, *n;
- DEBUG("in crypto free from %s:%d\n", file, line);
+ DEBUG("in crypto free from %s:%d; ptr=%p\n", file, line, ptr);
if (ptr == NULL)
return;
@@ -323,7 +324,7 @@
n = next_chunk(c);
DEBUG("free c=%p, n=%p, next_in_use=%d, prev_in_use=%d\n",
- c,n,in_use(n),prev_in_use(c));
+ c,n,n && in_use(n),prev_in_use(c));
/* now check for consolidation with previous */
if (!prev_in_use(c)) {
diff --git a/preload_test.c b/preload_test.c
index 8d13215..8923dd4 100644
--- a/preload_test.c
+++ b/preload_test.c
@@ -15,7 +15,7 @@
int main(int argc, const char *argv[])
{
- void *mem[7];
+ void *mem[50];
int i;
printf("\nAlloc array\n\n");
@@ -62,6 +62,39 @@
OPENSSL_free(mem[i]);
+ printf("\nForce Allocation across the segment boundary\n\n");
+ mem[0] = OPENSSL_malloc(0x1ff000);
+
+ for (i = 1; i < ARRAY_SIZE(mem); i++)
+ mem[i] = myalloc();
+
+ printf("\nFree *2\n\n");
+ for (i = 0; i < ARRAY_SIZE(mem); i += 2)
+ OPENSSL_free(mem[i]);
+ printf("\nFree holes\n\n");
+ for (i = 1; i < ARRAY_SIZE(mem); i += 2)
+ OPENSSL_free(mem[i]);
+
+ printf("\nFail oversize allocation\n\n");
+ mem[0] = OPENSSL_malloc(2*1024*1024);
+ if (mem[0] != NULL)
+ printf("FAILED\n");
+
+ printf("\n100 Random allocations and frees\n\n");
+
+ memset(mem, 0, sizeof(mem));
+
+ for (i = 0; i < 300; i++) {
+ int j = random()%ARRAY_SIZE(mem);
+ if (mem[j]) {
+ OPENSSL_free(mem[j]);
+ mem[j] = NULL;
+ } else {
+ mem[j] = myalloc();
+ }
+ }
+ for (i = 0; i < ARRAY_SIZE(mem); i++)
+ OPENSSL_free(mem[i]);
exit(0);
}