/* * smalloc.c * * Contains memory allocator routines * * TEST VERSION by ceder */ #include #include #include #include #include #include "smalloc.h" #include "lyskomd.h" #include "log.h" #include "exp.h" static u_long no_of_allocated_blocks = 0; /* * "safe" malloc. Handles the case when malloc returns NULL. * smalloc cannot fail. */ 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", (u_long)size); ++no_of_allocated_blocks; *p++ = SMALLOC_MAGIC_ALLOC; *p++ = size; ((unsigned char *) p)[size] = 0x89; ((unsigned char *) p)[size+1] = 0xA7; return (void *) p; } EXPORT void sfree(void * ptr) /* it is legal to sfree a NULL pointer */ { unsigned int *ip; #if 0 if ( ptr == NULL) log("SFREE: Freeing a NULL pointer - should be bad! /pen\n"); #endif if ( ptr != NULL ) { ip = (unsigned int *) ptr; ip -= 2; switch (*ip) { case SMALLOC_MAGIC_ALLOC: if (((unsigned char *) (ip+2))[ip[1]] != 0x89 || ((unsigned char *) (ip+2))[ip[1]+1] != 0xA7) restart_kom("SFREE: Buffer overflow, bsize = %ul\n", ip[1]); --no_of_allocated_blocks; *ip = SMALLOC_MAGIC_FREE; free( ip ); break; case SMALLOC_MAGIC_FREE: restart_kom("SFREE: Trying to free already freed block\n"); default: restart_kom("SFREE: Illegal magic number\n"); } } } EXPORT void * srealloc(void * ptr, size_t size) /* Never fails. It is legal to */ { /* realloc the NULL ptr. */ unsigned int * ip; unsigned int * new_ptr; if ( ptr == NULL ) return smalloc(size); ip = (unsigned int *) ptr; ip -= 2; switch (*ip) { case SMALLOC_MAGIC_ALLOC: break; case SMALLOC_MAGIC_FREE: restart_kom("SREALLOC: Trying to realloc freed block\n"); default: restart_kom("SREALLOC: Illegal magic number\n"); } if (((unsigned char *) (ip+2))[ip[1]] != 0x89 || ((unsigned char *) (ip+2))[ip[1]+1] != 0xA7) restart_kom("SREALLOC: Buffer overflow, osize = %ul, nsize = %ul\n", ip[1], size); *ip = SMALLOC_MAGIC_FREE; if ( (new_ptr = (unsigned int *) realloc((void *) ip, size+2*sizeof(unsigned int)+2) ) == NULL ) { restart_kom("Out of memory - can't realloc. ptr = %d size = %d. ", (int)ptr, size); } *new_ptr++ = SMALLOC_MAGIC_ALLOC; *new_ptr++ = size; ((unsigned char *) new_ptr)[size] = 0x89; ((unsigned char *) new_ptr)[size+1] = 0xA7; return (void *) new_ptr; } /* * Allocate temporary memory, which is automatically freed after this * atomic call. */ static void **tmp_alloc_table = NULL; static int tmp_alloc_table_size = 0; /* Size */ static int tmp_alloc_table_use = 0; /* Used size */ EXPORT void * tmp_alloc(u_long size) { if ( tmp_alloc_table_size <= tmp_alloc_table_use ) { /* Need to increas table. */ tmp_alloc_table = srealloc (tmp_alloc_table, ((++tmp_alloc_table_size) * sizeof (void *))); log("tmp_alloc: internal table size now %d elements.\n", tmp_alloc_table_size); } return (tmp_alloc_table[ tmp_alloc_table_use++ ] = smalloc (size)); } /* * Free all core which is allocated with tmp_alloc(). This is called from * end_of_atomic(). */ EXPORT void free_tmp(void) { int i; for ( i = 0; i < tmp_alloc_table_use; i++ ) { sfree ( tmp_alloc_table[ i ] ); tmp_alloc_table[ i ] = NULL; } tmp_alloc_table_use = 0; } EXPORT void free_all_tmp(void) { free_tmp(); sfree( tmp_alloc_table ); tmp_alloc_table = NULL; tmp_alloc_table_size = 0; } EXPORT void dump_smalloc_counts(FILE *stat_file) { fprintf(stat_file, "Allocated blocks (grand total): %lu\n", no_of_allocated_blocks); }