diff --git a/src/server/ram-smalloc.c b/src/server/ram-smalloc.c index 938604cfab2dbab47e252bfc05b3d2d247b7c249..b30cd171d1f2e342f3f434ab0feb5cff8a28e51b 100644 --- a/src/server/ram-smalloc.c +++ b/src/server/ram-smalloc.c @@ -1,5 +1,5 @@ /* - * $Id: ram-smalloc.c,v 0.34 2002/03/29 22:38:04 ceder Exp $ + * $Id: ram-smalloc.c,v 0.35 2002/08/02 21:26:32 ceder Exp $ * Copyright (C) 1991-1996, 1998-1999, 2001-2002 Lysator Academic Computer Association. * * This file is part of the LysKOM server. @@ -114,6 +114,42 @@ static int no_of_allocated_blocks = 0; +/* When using our own malloc guard areas, the memory layout looks like + this, where U is sizeof(unsigned int), and S is the size of the + requested block. + + offset what + ====== ==== + 0: magic cookie (an unsigned int) (see below) + U: the size S (an unsigned int) + 2*U: S bytes of data returned to the user. + S+2*U: guard byte: 0x89 + 1+S+2*U: guard byte: 0xA7 + 2+S+2*U: one past the end of the block allocated with malloc(). + + The total overhead is thus 2*U + 2. The macro OVERHEAD adds the + specified overead to S and returns the size we request from the + system malloc. + + The magic cookie reflects the status of the block and is used for + defensive checks. The constants are defined in smalloc.h: + + SMALLOC_MAGIC_ALLOC: an allocated block. + SMALLOC_MAGIC_FREE: a block that was previously allocated. + +*/ + +#ifdef USE_MALLOC_GUARDS +# define OVERHEAD(s) ((s) + (2*sizeof(unsigned int) + 2)) +#else + +/* When malloc() or realloc() is asked to allocate a 0-sized area, + they may return NULL to indicate success. We are not prepared for + that behaviour, so we always allocate at leaste 1 byte. */ +# define OVERHEAD(s) (((s) == 0) ? 1 : s) + +#endif + #ifdef TRACED_ALLOCATIONS static FILE *malloc_fp = NULL; @@ -141,6 +177,7 @@ trace_smalloc(size_t size, fprintf(malloc_fp, "==== end ====\n"); fflush(malloc_fp); } + #endif /* @@ -150,24 +187,27 @@ trace_smalloc(size_t size, EXPORT void * smalloc(size_t size) { - unsigned int *p; - - p = (unsigned int *) malloc(size + 2*sizeof(unsigned int) + 2); - if (p == NULL) - restart_kom("Can't allocate %lu bytes.\n", (unsigned long)size); + unsigned int *p; + + p = (unsigned int *) malloc(OVERHEAD(size)); - ++no_of_allocated_blocks; + if (p == NULL) + restart_kom("Can't allocate %lu bytes.\n", (unsigned long)size); - *p++ = SMALLOC_MAGIC_ALLOC; - *p++ = size; - ((unsigned char *) p)[size] = 0x89; - ((unsigned char *) p)[size+1] = 0xA7; + ++no_of_allocated_blocks; + +#ifdef USE_MALLOC_GUARDS + *p++ = SMALLOC_MAGIC_ALLOC; + *p++ = size; + ((unsigned char *) p)[size] = 0x89; + ((unsigned char *) p)[size+1] = 0xA7; +#endif #ifdef TRACED_ALLOCATIONS - trace_smalloc(size, p); + trace_smalloc(size, p); #endif - return (void *) p; + return (void *) p; } #ifdef TRACED_ALLOCATIONS @@ -184,13 +224,20 @@ trace_free(void *block) EXPORT void sfree(void * ptr) /* it is legal to sfree a NULL pointer */ { +#ifdef USE_MALLOC_GUARDS unsigned int *ip; +#endif if ( ptr != NULL ) { #ifdef TRACED_ALLOCATIONS trace_free(ptr); #endif + +#ifndef USE_MALLOC_GUARDS + free(ptr); + --no_of_allocated_blocks; +#else ip = (unsigned int *) ptr; ip -= 2; switch (*ip) @@ -210,6 +257,7 @@ sfree(void * ptr) /* it is legal to sfree a NULL pointer */ default: restart_kom("SFREE: Illegal magic number\n"); } +#endif } } @@ -236,6 +284,7 @@ srealloc(void * ptr, size_t size) /* Never fails. It is legal to */ return smalloc(size); ip = (unsigned int *) ptr; +#ifdef USE_MALLOC_GUARDS ip -= 2; switch (*ip) { @@ -255,18 +304,19 @@ srealloc(void * ptr, size_t size) /* Never fails. It is legal to */ ip[1], (unsigned long)size); *ip = SMALLOC_MAGIC_FREE; - if ( (new_ptr = (unsigned int *) realloc((void *) ip, - size+2*sizeof(unsigned int)+2) ) == NULL ) +#endif + if ((new_ptr = (unsigned int *)realloc((void*)ip, OVERHEAD(size))) == NULL) { restart_kom("Out of memory - can't realloc. ptr = %lu size = %lu.\n", (unsigned long)ptr, (unsigned long)size); } - +#ifdef USE_MALLOC_GUARDS *new_ptr++ = SMALLOC_MAGIC_ALLOC; *new_ptr++ = size; ((unsigned char *) new_ptr)[size] = 0x89; ((unsigned char *) new_ptr)[size+1] = 0xA7; +#endif #ifdef TRACED_ALLOCATIONS trace_srealloc(size, ptr, new_ptr);