home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
dbmalloc-1.14-src.tgz
/
tar.out
/
contrib
/
dbmalloc
/
fill.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-28
|
8KB
|
449 lines
/*
* (c) Copyright 1990, 1991, 1992 Conor P. Cahill (cpcahil@virtech.vti.com)
*
* This software may be distributed freely as long as the following conditions
* are met:
* * the distribution, or any derivative thereof, may not be
* included as part of a commercial product
* * full source code is provided including this copyright
* * there is no charge for the software itself (there may be
* a minimal charge for the copying or distribution effort)
* * this copyright notice is not modified or removed from any
* source file
*/
#include <stdio.h>
#include "mallocin.h"
static long fillmalloc = -1;
static long fillfree = -1;
#define FILLINIT() if( fillmalloc == -1 ) FillInit()
/*
* Fill check types
*/
#define FILL_UNDER 1
#define FILL_OVER 2
#define FILL_FREED 3
/*
* FillInit() - fill initialization routine
*/
VOIDTYPE
FillInit()
{
char * ptr;
int i;
ptr = (char *) &fillmalloc;
for( i=0; i < sizeof(long); i++)
{
*ptr++ = M_FILL;
}
ptr = (char *) &fillfree;
for( i=0; i < sizeof(long); i++)
{
*ptr++ = M_FREE_FILL;
}
} /* FillInit(... */
/*
* FillCheck() check for overflow and/or underflow using the filled regions
* in the specified malloc segment.
*/
int
FillCheck(func,file,line,ptr,showerrors)
CONST char * func;
CONST char * file;
int line;
struct mlist * ptr;
int showerrors;
{
int rtn = -1;
FILLINIT();
/*
* if this block has no filling
*/
if( (ptr->flag & (M_FILLED|M_DFILLED)) == 0 )
{
rtn = 0;
}
/*
* else if this block is in use or it was not free-filled
*/
else if( ((ptr->flag & M_INUSE) != 0)
|| ((ptr->flag & M_FILLED) == 0) )
{
/*
* check for data underflow and data overflow
*/
rtn = FillCheckData(func,file,line,ptr,FILL_UNDER,showerrors)
+ FillCheckData(func,file,line,ptr,FILL_OVER, showerrors);
}
/*
* else the block must have been freed
*/
else
{
/*
* check for data underflow and free filling
*/
rtn = FillCheckData(func,file,line,ptr,FILL_UNDER,showerrors)
+ FillCheckData(func,file,line,ptr,FILL_FREED,showerrors);
}
return(rtn);
} /* FillCheck(... */
/*
* FillCheckData() - routine to check the data areas to ensure that they
* are filled with the appropriate fill characters.
*/
int
FillCheckData(func,file,line,ptr,checktype,showerrors)
CONST char * func;
CONST char * file;
int line;
struct mlist * ptr;
int checktype;
int showerrors;
{
register char * data = NULL;
int errcode = 0;
char filler = '\0';
long fillword = 0;
register SIZETYPE i = 0;
register long * ldata;
SIZETYPE limit = ptr->s.size;
int rtn = -1;
if( (ptr->flag & (M_DFILLED | M_FILLED)) == 0 )
{
return(0);
}
switch(checktype)
{
case FILL_UNDER:
if( ((ptr->flag & M_DFILLED) == 0 )
|| (ptr->s.filler[LONGFILL-1] == fillmalloc) )
{
rtn = 0;
}
else
{
/*
* if showing errors
*/
if( showerrors )
{
/*
* give the underrun error message
*/
malloc_errno = M_CODE_UNDERRUN;
malloc_warning(func,file,line,ptr);
/*
* fix the problem
*/
ptr->s.filler[LONGFILL-1] = fillmalloc;
}
rtn = 1;
}
break;
case FILL_OVER:
if( (ptr->flag & M_DFILLED) == 0)
{
rtn = 0;
}
else
{
i = ptr->r_size;
errcode = M_CODE_OVERRUN;
filler = M_FILL;
fillword = fillmalloc;
data = ptr->data;
}
break;
case FILL_FREED:
if( (ptr->flag & M_FILLED) == 0)
{
rtn = 0;
}
else
{
i = 0;
errcode = M_CODE_REUSE;
filler = M_FREE_FILL;
fillword = fillfree;
data = ptr->data;
}
break;
default:
i = 0;
limit = 0;
break;
}
/*
* if there is nothing to check, just return
*/
if( rtn != -1 )
{
return(rtn);
}
rtn = 0;
data += i;
i = limit - i;
while( ((long)data) & (sizeof(long)-1) )
{
if( *data != filler )
{
if( showerrors )
{
malloc_errno = errcode;
malloc_warning(func,file,line,ptr);
/*
* fix the underrun so we only get this
* message once
*/
while( i-- > 0 )
{
*(data++) = filler;
}
}
rtn++;
break;
}
data++;
i--;
}
/*
* if we haven't found an error yet
*/
if( rtn == 0 )
{
/*
* convert to use longword pointer
*/
ldata = (long *) data;
i >>= 2;
/*
* while more longwords to check
*/
while( i > 0 )
{
if( *ldata != fillword )
{
if( showerrors )
{
malloc_errno = errcode;
malloc_warning(func,file,line,ptr);
/*
* fix the underrun so we only get this
* message once
*/
while( i-- > 0 )
{
*(ldata++) = fillword;
}
}
rtn++;
break;
}
ldata++;
i--;
}
}
return(rtn);
} /* FillCheckData(... */
/*
* FillData() fill in the needed areas in the specified segment. This is used
* to place non-zero data in new malloc segments, setup boundary
* areas to catch under/overflow, and overwrite freed segments so
* that they can't be usefully re-used.
*/
void
FillData(ptr,alloctype,start,nextptr)
register struct mlist * ptr;
int alloctype;
SIZETYPE start;
struct mlist * nextptr;
{
int fills;
int filler = 0;
SIZETYPE limit = ptr->s.size;
FILLINIT();
if( (malloc_opts & (MOPT_MFILL|MOPT_DFILL|MOPT_FFILL)) == 0)
{
ptr->flag &= ~(M_FILLED|M_DFILLED);
return;
}
switch(alloctype)
{
case FILL_MALLOC:
fills = MOPT_MFILL | MOPT_DFILL;
filler = M_FILL;
break;
case FILL_FREE:
fills = MOPT_FFILL;
filler = M_FREE_FILL;
break;
case FILL_SPLIT:
fills = MOPT_FFILL;
filler = M_FREE_FILL;
break;
case FILL_JOIN:
if( (ptr->flag&M_INUSE) != 0 )
{
if( ptr->flag & M_FILLED )
{
fills = MOPT_MFILL;
filler = M_FILL;
}
else if( ptr->flag & M_DFILLED )
{
fills = MOPT_MFILL;
filler = M_FILL;
start = ptr->r_size;;
}
else
{
fills = 0;
}
}
else /* not in use */
{
/*
* if this segment has bee free-filled
*/
if( ptr->flag & M_FILLED )
{
fills = MOPT_MFILL;
filler = M_FREE_FILL;
/*
* if the next segment is already filled
*/
if( (nextptr->flag & M_FILLED) != 0 )
{
limit = start + M_SIZE;
}
}
/*
* else if this segment has overflow filling
* enabled, fill the next segment since it is
* now overflow of this segment.
*/
else if( (ptr->flag & M_DFILLED) != 0 )
{
fills = MOPT_DFILL;
filler = M_FILL;
start = ptr->r_size;;
}
else
{
fills = 0;
}
}
break;
case FILL_REALLOC:
if( ptr->flag & M_FILLED )
{
fills = MOPT_MFILL;
filler = M_FILL;
}
else if( ptr->flag & M_DFILLED )
{
fills = MOPT_MFILL;
filler = M_FILL;
start = ptr->r_size;;
}
else
{
fills = 0;
}
break;
case FILL_CALLOC:
fills = MOPT_DFILL;
break;
default:
fills = 0;
}
if( (fills & MOPT_DFILL) != 0 )
{
if( (malloc_opts & MOPT_DFILL) != 0 )
{
ptr->s.filler[LONGFILL-1] = fillmalloc;
ptr->flag |= M_DFILLED;
}
else if( alloctype != FILL_FREE )
{
ptr->flag &= ~M_DFILLED;
}
}
if( (malloc_opts & (MOPT_MFILL|MOPT_FFILL) & fills) != 0 )
{
/*
* fill in the data
*/
DataMS(ptr->data+start, filler, (MEMSIZE) (limit - start));
ptr->flag |= M_FILLED;
}
else
{
ptr->flag &= ~M_FILLED;
/*
* if we still have to fill the boundry area and this isn't
* a free-fill, go do it
*/
if( ((ptr->flag & M_DFILLED) != 0) && (filler == M_FILL) )
{
DataMS(ptr->data+ptr->r_size, M_FILL,
(MEMSIZE) (limit - ptr->r_size));
}
}
} /* FillData(... */