#include <u.h>
#define NOPLAN9DEFINES
#include <libc.h>

/*
 * The Unix libc routines cannot be trusted to do their own locking.
 * Sad but apparently true.
 */
static Lock malloclock;
static int mallocpid;

/*
 * The Unix mallocs don't do nearly enough error checking
 * for my tastes.  We'll waste another 24 bytes per guy so that
 * we can.  This is severely antisocial, since now free and p9free
 * are not interchangeable.
 */
int debugmalloc;

#define Overhead (debugmalloc ? (6*sizeof(ulong)) : 0)
#define MallocMagic 0xA110C09
#define ReallocMagic 0xB110C09
#define CallocMagic 0xC110C09
#define FreeMagic 0xF533F533
#define CheckMagic 0
#define END "\x7F\x2E\x55\x23"

static void
whoops(void *v)
{
	fprint(2, "bad malloc block %p\n", v);
	abort();
}

static void*
mark(void *v, ulong pc, ulong n, ulong magic)
{
	ulong *u;
	char *p;

	if(!debugmalloc)
		return v;

	if(v == nil)
		return nil;

	if(magic == FreeMagic || magic == CheckMagic){
		u = (ulong*)((char*)v-4*sizeof(ulong));
		if(u[0] != MallocMagic && u[0] != ReallocMagic && u[0] != CallocMagic)
			whoops(v);
		n = u[1];
		p = (char*)v+n;
		if(memcmp(p, END, 4) != 0)
			whoops(v);
		if(magic != CheckMagic){
			u[0] = FreeMagic;
			u[1] = u[2] = u[3] = pc;
			if(n > 16){
				u[4] = u[5] = u[6] = u[7] = pc;
				memset((char*)v+16, 0xFB, n-16);
			}
		}
		return u;
	}else{
		u = v;
		u[0] = magic;
		u[1] = n;
		u[2] = 0;
		u[3] = 0;
		if(magic == ReallocMagic)
			u[3] = pc;
		else
			u[2] = pc;
		p = (char*)(u+4)+n;
		memmove(p, END, 4);
		return u+4;
	}	
}

void
setmalloctag(void *v, ulong t)
{
	ulong *u;

	if(!debugmalloc)
		return;

	if(v == nil)
		return;
	u = mark(v, 0, 0, 0);
	u[2] = t;
}

void
setrealloctag(void *v, ulong t)
{
	ulong *u;

	if(!debugmalloc)
		return;

	if(v == nil)
		return;
	u = mark(v, 0, 0, 0);
	u[3] = t;
}
	
void*
p9malloc(ulong n)
{
	void *v;
	if(n == 0)
		n++;
/*fprint(2, "%s %d malloc\n", argv0, getpid()); */
	lock(&malloclock);
	mallocpid = getpid();
	v = malloc(n+Overhead);
	v = mark(v, getcallerpc(&n), n, MallocMagic);
	unlock(&malloclock);
/*fprint(2, "%s %d donemalloc\n", argv0, getpid()); */
	return v;
}

void
p9free(void *v)
{
	if(v == nil)
		return;

/*fprint(2, "%s %d free\n", argv0, getpid()); */
	lock(&malloclock);
	mallocpid = getpid();
	v = mark(v, getcallerpc(&v), 0, FreeMagic);
	free(v);
	unlock(&malloclock);
/*fprint(2, "%s %d donefree\n", argv0, getpid()); */
}

void*
p9calloc(ulong a, ulong b)
{
	void *v;

/*fprint(2, "%s %d calloc\n", argv0, getpid()); */
	lock(&malloclock);
	mallocpid = getpid();
	v = calloc(a*b+Overhead, 1);
	v = mark(v, getcallerpc(&a), a*b, CallocMagic);
	unlock(&malloclock);
/*fprint(2, "%s %d donecalloc\n", argv0, getpid()); */
	return v;
}

void*
p9realloc(void *v, ulong n)
{
/*fprint(2, "%s %d realloc\n", argv0, getpid()); */
	lock(&malloclock);
	mallocpid = getpid();
	v = mark(v, getcallerpc(&v), 0, CheckMagic);
	v = realloc(v, n+Overhead);
	v = mark(v, getcallerpc(&v), n, ReallocMagic);
	unlock(&malloclock);
/*fprint(2, "%s %d donerealloc\n", argv0, getpid()); */
	return v;
}
