home *** CD-ROM | disk | FTP | other *** search
- /*-------------------------[ jmalloc.c ]------------------------*/
- /* drop-in for malloc with diags */
- /*--------------------------------------------------------------*/
- /* Released to the public domain, 1992: Jeff Dunlop */
- /*--------------------------------------------------------------*/
-
- /*--------------------------------------------------------------*/
- /*-----------------------[ header files ]-----------------------*/
- /*--------------------------------------------------------------*/
-
- #include <alloc.h>
- #include <errno.h>
- #include <mem.h>
- #include <stdio.h>
- #include "dbug.h"
- #include "jmalloc.h"
-
- /*--------------------------------------------------------------*/
- /*---------------------[ global variables ]---------------------*/
- /*--------------------------------------------------------------*/
-
- MLINK *MalTop; /* top of allocation chain */
-
- /*--------------------------[ JMalloc ]-------------------------*/
- /* Memory allocator with diagnostics */
- /*--------------------------------------------------------------*/
- /* input: */
- /* Size = number of bytes to allocate */
- /* local: */
- /* CurMal = pointer current mem struct */
- /* PrevMal = pointer to previous mem struct */
- /* AllocAddr = pointer to allocated ram */
- /* return: */
- /* address of allocated ram, or NULL on error */
- /*--------------------------------------------------------------*/
-
- void *JMalloc(unsigned Size)
- {
- /* 1. Allocate the memory */
- /* 2. Add to allocation chain */
- /* 3. Fill with non-null */
-
- MLINK *CurMal = MalTop,
- *PrevMal;
-
- void *AllocAddr;
-
- DBUG_ENTER("JMalloc");
-
- /* Allocate the memory + 1 (for check byte) */
-
- if ( (AllocAddr = malloc(Size + 1)) == NULL )
- DBUG_PRINT("alloc", ("Allocation failed"));
-
- /* Add to the allocation chain */
-
- PrevMal = CurMal;
- while ( CurMal != NULL )
- {
- PrevMal = CurMal;
- CurMal = CurMal->NextLink;
- }
- if ( (CurMal = malloc(sizeof *CurMal)) == NULL )
- DBUG_PRINT("alloc", ("Allocation failed"));
-
- /* Deal with bootstrap */
- if ( PrevMal == NULL )
- MalTop = CurMal;
- else
- PrevMal->NextLink = CurMal;
-
- /* initialize */
- CurMal->NextLink = NULL;
- CurMal->MAddr = AllocAddr;
- CurMal->MSize = Size;
-
- /* fill with dirty char */
- memset(AllocAddr, 0x01, Size + 1);
- DBUG_RETURN(AllocAddr);
- }
-
- /*--------------------------[ JCalloc ]-------------------------*/
- /* Memory allocator with diagnostics */
- /*--------------------------------------------------------------*/
- /* method: */
- /* - Allocate the memory via JMalloc */
- /* - Fill with null */
- /* - Add check-byte */
- /* input: */
- /* Size = number of bytes to allocate */
- /* local: */
- /* CurCal = pointer current mem struct */
- /* PrevCal = pointer to previous mem struct */
- /* AllocAddr = pointer to allocated ram */
- /* return: */
- /* address of allocated ram, or NULL on error */
- /*--------------------------------------------------------------*/
-
- void *JCalloc(unsigned Size, unsigned SizEach)
- {
- char *AllocAddr;
-
- DBUG_ENTER("JCalloc");
- /* Allocate the memory + 1 (for check byte) */
-
- /* Do not piss over NULL return - JMalloc handled that */
- if ( (AllocAddr = JMalloc(Size * SizEach)) != NULL )
- {
- /* Prep allocated ram */
- memset(AllocAddr, 0, Size * SizEach);
- AllocAddr[Size * SizEach] = 0x01;
- }
-
- DBUG_RETURN(AllocAddr);
- }
-
- /*------------------------------[ j_free ]----------------------*/
- /* Memory deallocator with diagnostics */
- /*--------------------------------------------------------------*/
- /* input: */
- /* AllocAddr = pointer to ram to deallocate */
- /* local: */
- /* CurMal = pointer to current mem struct */
- /* PrevMal = pointer to prev mem struct */
- /* note: */
- /* This function is designed to be implemented with the */
- /* macro JFree */
- /*--------------------------------------------------------------*/
-
- void j_free(void *AllocAddr, char *file, int line)
- {
- /* 1. Find the block in the alloc list */
- /* 2. Check for check-byte overwrite */
- /* 3. Remove allocation record */
- /* 3. Free the ram */
-
- MLINK *CurMal = MalTop,
- *PrevMal;
-
- DBUG_ENTER("j_free");
-
- /* Find the block in the alloc list */
- while ( CurMal->MAddr != AllocAddr && CurMal != NULL )
- {
- PrevMal = CurMal;
- CurMal = CurMal->NextLink;
- }
- if ( CurMal == NULL )
- {
- DBUG_PRINT("alloc", ("Free attempt failed %s %d", file, line));
- }
- else
- {
- /* Check for check-byte overwrite */
- if ( CurMal->MAddr[CurMal->MSize] != 0x01 )
- DBUG_PRINT("alloc", ("Memory overrun detected"));
-
- /* dirty the deallocated ram - if it's still being used, it */
- /* should become fairly obvious */
- memset(AllocAddr, 0x02, CurMal->MSize + 1);
-
- /* Remove allocation record */
- PrevMal->NextLink = CurMal->NextLink;
- free(CurMal);
- }
-
- /* Free the ram regardless of validity */
- free(AllocAddr);
- DBUG_VOID_RETURN;
- }
-
- /*-------------------------[ JMemcheck ]------------------------*/
- /* Verify memory chain integrity */
- /*--------------------------------------------------------------*/
- /* local: */
- /* i = link number */
- /* CurMal = link pointer */
- /* status = current error condition */
- /* return: */
- /* -1 = error, */
- /* 0 = no error detected */
- /* warning: */
- /* I haven't had the pleasure of testing this */
- /*--------------------------------------------------------------*/
-
- int JMemcheck(void)
- {
- int i = 0,
- status = 0;
-
- MLINK *CurMal = MalTop;
-
- DBUG_ENTER("JMemcheck");
-
- /* Walk the alloc list */
- while ( CurMal != NULL )
- {
- i++;
- if ( CurMal->MAddr[CurMal->MSize] != 0x01 )
- {
- DBUG_PRINT("alloc", ("Memory overrun detected in link %d", i));
- status = -1;
- }
- CurMal = CurMal->NextLink;
- }
- DBUG_RETURN(status);
- }
-