//
//  malloc.c
//
//  Created by Julien-Pierre Averous on 16/10/06.
//  Copyright 2006 SourceMac.com. All rights reserved.
//
//


#include "malloc.h"
#include "hash.h"


/*
** To Install, on Bash :
**	$ DYLD_INSERT_LIBRARIES=%%LIBDIR%%/libgfs_hook.dylib
**	$ DYLD_FORCE_FLAT_NAMESPACE=
**	$ export DYLD_INSERT_LIBRARIES DYLD_FORCE_FLAT_NAMESPACE
*/



/*
** Original function pointer
*/

static void *(*_malloc)(size_t size) = NULL;

static void *(*_calloc)(size_t count, size_t size) = NULL;

static void *(*_valloc)(size_t size) = NULL;

static void *(*_realloc)(void *ptr, size_t size) = NULL;

static void *(*_reallocf)(void *ptr, size_t size) = NULL;

static void (*_free)(void *ptr) = NULL;



/*
** MALLOC
*/
void *malloc(size_t size)
{
	void	*ptr;
	s_frame	*frm;
	
	ptr = my_malloc(size);
	
	if (!ptr)
		return (ptr);
	
	frm = my_malloc(sizeof(s_frame));
	frm->sz = size;
	frm->ptr = ptr;
	frm->id = -1;
	
	hash_append_frame(frm);
	
	return ptr;
}


/*
** CALLOC
*/
void *calloc(size_t count, size_t size)
{
	void	*ptr;
	s_frame	*frm;
	
	if (_calloc == NULL)
		_calloc = (void *(*)(size_t, size_t))dlsym(RTLD_NEXT, "calloc");

	ptr = _calloc(count, size);
	
	if (!ptr)
		return (ptr);

	frm = my_malloc(sizeof(s_frame));
	frm->sz = count * size;
	frm->ptr = ptr;
	frm->id = -1;
	
	hash_append_frame(frm);

	return ptr;
}


/*
** VALLOC
*/
void *valloc(size_t size)
{
	void	*ptr;
	s_frame	*frm;
	
	if (_valloc == NULL)
		_valloc = (void *(*)(size_t))dlsym(RTLD_NEXT, "valloc");

	ptr = _valloc(size);
	
	if (!ptr)
		return (ptr);
	
	frm = my_malloc(sizeof(s_frame));
	frm->sz = size;
	frm->ptr = ptr;
	frm->id = -1;
	
	hash_append_frame(frm);
	
	return ptr;

}


/*
** REALLOC
*/
void *realloc(void *ptr, size_t size)
{
	void	*mptr;
	s_frame	*frm;
	int	id = -1;
	
	if (_realloc == NULL)
		_realloc = (void *(*)(void *, size_t))dlsym(RTLD_NEXT, "realloc");

	mptr = _realloc(ptr, size);
	
	if (!mptr)
		return (mptr);
	
	if (ptr)
		id = hash_remove_ptrframe(ptr);
	
	frm = my_malloc(sizeof(s_frame));
	frm->sz = size;
	frm->ptr = mptr;
	frm->id = id;
	
	hash_append_frame(frm);
	
	return mptr;

}


/*
** REALLOCF
*/
void *reallocf(void *ptr, size_t size)
{
	void	*mptr;
	s_frame	*frm;
	int	id = -1;
	
	if (_reallocf == NULL)
		_reallocf = (void *(*)(void *, size_t))dlsym(RTLD_NEXT, "reallocf");

	mptr = _reallocf(ptr, size);
	
	if (!mptr)
		return (mptr);
	
	if (ptr)
		id = hash_remove_ptrframe(ptr);
	
	frm = my_malloc(sizeof(s_frame));
	frm->sz = size;
	frm->ptr = mptr;
	frm->id = id;
	
	hash_append_frame(frm);
	
	return mptr;

}


/*
** FREE
*/
void free(void *ptr)
 {
 	sig_free(ptr);
 
 	hash_remove_ptrframe(ptr);

 	my_free(ptr);
}






/*
** Tools
*/


/*
** Not logged malloc
*/
void	*my_malloc(size_t	sz)
{
	if (_malloc == NULL)
		_malloc = (void *(*)(size_t))dlsym(RTLD_NEXT, "malloc");
	return (_malloc(sz));
}


/*
** Not logged free
*/
void	my_free(void *ptr)
{
	if (_free == NULL)
		_free = (void (*)(void *ptr))dlsym(RTLD_NEXT, "free");
	return (_free(ptr));
}
