/* This file is in the public domain. */ #ifdef ECL_MALLOC_DEBUG #include #define ECL_MALLOC_IMPLEMENTATION #include "ecl-malloc.h" #define GUARDBYTES 8 static const unsigned char guardpattern1[GUARDBYTES] = { 0xf8, 0x13, 0x79, 0xc3, 0xef, 0xe3, 0xdd, 0x06 }; static const unsigned char guardpattern2[GUARDBYTES] = { 0x91, 0x2d, 0x13, 0x16, 0xf6, 0xa7, 0x3c, 0xfb }; #define ALIGN 8 typedef struct hdr HDR; struct hdr { HDR *flink; HDR *blink; size_t size; void *data; const char *file1; int line1; const char *file; int line; } ; #define N_BEFORE (((sizeof(HDR)+GUARDBYTES+ALIGN-1)/ALIGN)*ALIGN) extern char *malloc_options; static char malloc_options_contents[] = "AJVX"; char *malloc_options = &malloc_options_contents[0]; static HDR *root = 0; void *ecl_malloc(size_t nb, const char *file, int line) { char *blk; HDR *h; ecl_consistency(); if (nb > (1<<20)) abort(); if (nb == 0) return(0); blk = malloc(N_BEFORE+nb+GUARDBYTES); if (blk == 0) abort(); h = (void *) blk; h->flink = root; h->blink = 0; if (root) root->blink = h; root = h; h->size = nb; h->data = blk + N_BEFORE; h->file = file; h->line = line; h->file1 = file; h->line1 = line; bcopy(&guardpattern1[0],blk+N_BEFORE-GUARDBYTES,GUARDBYTES); bcopy(&guardpattern2[0],blk+N_BEFORE+nb,GUARDBYTES); ecl_consistency(); return(h->data); } void *ecl_realloc(void *oldv, size_t newnb, const char *file, int line) { char *old; HDR *oldh; char *new; HDR *newh; if (newnb == 0) { ecl_free(oldv,file,line); return(0); } if (oldv == 0) return(ecl_malloc(newnb,file,line)); ecl_consistency(); old = oldv; if (bcmp(old-GUARDBYTES,&guardpattern1[0],GUARDBYTES)) abort(); oldh = (void *)(old - N_BEFORE); if (oldh->data != old) abort(); if (bcmp(old+oldh->size,&guardpattern2[0],GUARDBYTES)) abort(); new = malloc(N_BEFORE+newnb+GUARDBYTES); newh = (void *)new; if ((newh->flink = oldh->flink)) newh->flink->blink = newh; if ((newh->blink = oldh->blink)) newh->blink->flink = newh; else root = newh; newh->data = new + N_BEFORE; bcopy(&guardpattern1[0],new+N_BEFORE-GUARDBYTES,GUARDBYTES); bcopy(&guardpattern2[0],new+N_BEFORE+newnb,GUARDBYTES); newh->file1 = oldh->file1; newh->line1 = oldh->line1; newh->file = file; newh->line = line; newh->size = newnb; if (newnb < oldh->size) { bcopy(old,new+N_BEFORE,newnb); } else { bcopy(old,new+N_BEFORE,oldh->size); if (newnb > oldh->size) { memset(new+N_BEFORE+oldh->size,0xd1,newnb-oldh->size); } } free(oldh); ecl_consistency(); return(newh->data); } void ecl_free(void *blkv, const char *file, int line) { char *blk; HDR *h; if (blkv == 0) return; ecl_consistency(); blk = blkv; if (bcmp(blk-GUARDBYTES,&guardpattern1[0],GUARDBYTES)) abort(); h = (void *)(blk - N_BEFORE); if (h->data != blk) abort(); if (bcmp(blk+h->size,&guardpattern2[0],GUARDBYTES)) abort(); if (h->flink) h->flink->blink = h->blink; if (h->blink) h->blink->flink = h->flink; else root = h->flink; free(h); file = file; line = line; ecl_consistency(); } char *ecl_strdup(const char *s, const char *file, int line) { int n; char *r; if (! s) return(0); n = strlen(s); r = ecl_malloc(n+1,file,line); strcpy(r,s); return(r); } void ecl_consistency(void) { HDR *h; for (h=root;h;h=h->flink) { if (h->data != ((char *)h)+N_BEFORE) abort(); if (bcmp(&guardpattern1[0],((char *)h->data)-GUARDBYTES,GUARDBYTES)) abort(); if (bcmp(&guardpattern2[0],((char *)h->data)+h->size,GUARDBYTES)) abort(); } } #endif