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);
 }