/* This file is in the public domain. */ #include #include #include #include #include #include "alloc.h" #undef malloc #undef realloc #undef free struct blk { BLK *ablink; BLK *aflink; BLK *lblink; BLK *lflink; int len; unsigned int flags; #define BF_FREE 0x00000001 SLOC *a; SLOC *r; SLOC *f; } ; static char dummy __attribute__((__aligned__)); #define ALIGNMENT (__alignof__(dummy)) #define GUARD ALIGNMENT static int didinit = 0; static unsigned int rstate[64]; static char *rsp; static BLK *allblk; static unsigned char guard1[GUARD]; static unsigned char guard2[GUARD]; static void init(void) { struct timeval tv; char *os; int i; if (didinit) return; os = initstate(tv.tv_sec^tv.tv_usec,(void *)&rstate[0],sizeof(rstate)); for (i=GUARD-1;i>=0;i--) { guard1[i] = (random() >> 20) & 0xff; guard2[i] = (random() >> 19) & 0xff; } rsp = setstate(os); didinit = 1; } static void blk_link(BLK *b) { b->aflink = allblk; b->ablink = 0; allblk = b; if (b->aflink) b->aflink->ablink = b; b->lflink = b->a->chain; b->lblink = 0; b->a->chain = b; if (b->lflink) b->lflink->lblink = b; } static void blk_unlink(BLK *b) { if (b->aflink) b->aflink->ablink = b->ablink; if (b->ablink) b->ablink->aflink = b->aflink; else allblk = b->aflink; if (b->lflink) b->lflink->lblink = b->lblink; if (b->lblink) b->lblink->lflink = b->lflink; else b->a->chain = b->lflink; } void *loc_malloc(SLOC *l, int nb) { char *v; BLK *b; void *d; init(); if (nb == 0) return(0); v = malloc(sizeof(BLK)+GUARD+nb+GUARD); b = (void *)v; d = b + 1; b->len = nb; b->flags = 0; b->a = l; b->r = 0; b->f = 0; blk_link(b); bcopy(&guard1[0],d,GUARD); bcopy(&guard2[0],((char *)d)+GUARD+nb,GUARD); return(((char *)d)+GUARD); } void *loc_realloc(SLOC *l, void *data, int nb) { char *v; BLK *b; char *r; init(); if (data == 0) return(loc_malloc(l,nb)); if (nb < 1) { loc_free(l,data); return(0); } v = ((char *)data) - GUARD; b = ((BLK *)v) - 1; if (bcmp(v,&guard1[0],GUARD)) abort(); if (bcmp(((char *)data)+b->len,&guard2[0],GUARD)) abort(); blk_unlink(b); b->flags = BF_FREE; r = realloc(b,sizeof(BLK)+GUARD+nb+GUARD); if (r == 0) { blk_link(b); return(0); } b = (void *)r; b->r = l; b->len = nb; b->flags &= ~BF_FREE; blk_link(b); bcopy(&guard1[0],b+1,GUARD); bcopy(&guard2[0],((char *)(b+1))+GUARD+nb,GUARD); return(((char *)(b+1))+GUARD); } void loc_free(SLOC *l, void *data) { char *v; BLK *b; init(); if (data == 0) return; v = ((char *)data) - GUARD; b = ((BLK *)v) - 1; if (bcmp(v,&guard1[0],GUARD)) abort(); if (bcmp(((char *)data)+b->len,&guard2[0],GUARD)) abort(); blk_unlink(b); b->f = l; b->flags = BF_FREE; free(b); } void loc_dump(void) { BLK *b; BLK *c; int fd; FILE *f; fd = open("loc.dbg",O_WRONLY|O_APPEND,0); if (fd < 0) return; f = fdopen(fd,"a"); fprintf(f,"dump, offset %d\n",(int)(sizeof(BLK)+GUARD)); for (b=allblk;b;b=b->aflink) { if (b == b->a->chain) { fprintf(f," %s %s %d:\n",b->a->file,b->a->func,b->a->ln); for (c=b;c;c=c->lflink) { fprintf(f,"\t%p\n",(void *)(((char *)c)+sizeof(BLK)+GUARD)); } } } fclose(f); }