#include #include extern const char *__progname; #include "mcc.h" #include "verbose.h" #include "alloc.h" #undef malloc #undef realloc #undef free typedef struct block BLOCK; struct block { BLOCK *flink; BLOCK *blink; void *blk; } ; static BLOCK *blocks = 0; static void write_2_dec(int n) { if (n >= 10) { write_2_dec(n/10); n %= 10; } write(2,"0123456789"+n,1); } static void newblk(void *blk) { BLOCK *b; if (! blk) return; b = malloc(sizeof(BLOCK)); b->blk = blk; b->flink = blocks; b->blink = 0; if (blocks) blocks->blink = b; blocks = b; } static void swapblk(void *old, void *new) { BLOCK *b; if (old == new) return; for (b=blocks;b;b=b->flink) { if (b->blk == old) { b->blk = new; return; } } panic(); } static void oldblk(void *blk) { BLOCK *b; for (b=blocks;b;b=b->flink) { if (b->blk == blk) { if (b->flink) b->flink->blink = b->blink; if (b->blink) b->blink->flink = b->flink; else blocks = b->flink; return; } } panic(); } void chkadopt(void *blk) { VERB(ALLOC,"elsewhere() -> %p\n",blk); newblk(blk); } void *chkmalloc(int nb) { void *rv; if (nb < 0) panic(); VERB(ALLOC,"malloc(%d)\n",nb); rv = malloc(nb); if (! rv) { write(2,"malloc(",7); write_2_dec(nb); write(2,") failed\n",9); exit(1); } VERB(ALLOC,"-> %p\n",rv); newblk(rv); return(rv); } void *chkrealloc(void *blk, int nb) { void *rv; if (nb < 0) panic(); VERB(ALLOC,"realloc(%p,%d)\n",blk,nb); rv = realloc(blk,nb); if (! rv) { write(2,"realloc(,",9); write_2_dec(nb); write(2,") failed\n",9); exit(1); } VERB(ALLOC,"-> %p\n",rv); if (blk) swapblk(blk,rv); else newblk(rv); return(rv); } void chkfree(void *blk) { VERB(ALLOC,"free(%p)\n",blk); if (blk) oldblk(blk); free(blk); } void chkearly(void) { BLOCK *b; for (b=blocks;b;b=b->flink) { VERB(ALLOC,"early() -> %p\n",b->blk); } }