/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at golgotha_source@usa.net (Subject should have "GOLG" in it) ***********************************************************************/ #include#include #include #include "arch.hh" #include "memory/malloc.hh" #include "error/error.hh" #include "threads/threads.hh" #include "time/profile.hh" #include "init/init.hh" #include "file/file.hh" #include "file/static_file.hh" #include "string/string.hh" // define this to override the native memcpy to check for overwriting memory leaks //#define i4_MEMCPY_CHECK #define i4_FREE_CHECK #ifdef i4_NEW_CHECK #undef new #endif #undef i4_malloc #undef i4_realloc static i4_critical_section_class mem_lock; #ifndef __MAC__ static i4_profile_class pf_malloc("i4_malloc"); static i4_profile_class pf_free("i4_free"); // declare the new()s before we include malloc.hh so that the new // macro doesn't mess up their definition int i4_m_instance=0; int i4_mem_break=-1; #if (__linux && i4_NEW_CHECK) void *operator new( size_t size, char *file, w32 line) { return i4_malloc(size, file, line); } void *operator new [](size_t size, char *file, w32 line) { return i4_malloc(size, file, line); } #endif #include #undef new void *operator new( size_t size) { return i4_malloc(size,"unknown",0); } void operator delete(void *ptr) { i4_free(ptr); } #endif #ifdef i4_MEM_CHECK #define i4_MEM_CLEAR #endif #include "memory/bmanage.hh" extern void free_up_memory(); #ifdef i4_MEM_CHECK // can be set in debugger, break mem fun will be called when this address is allocated long break_mem_point=0; void break_mem_fun() { printf("memory breakpoint\n"); } #ifdef i4_MEMCPY_CHECK // can set this memory range to check for mem copies over memory w32 i4_check_min=0, i4_check_max=0; extern "C" void *memcpy(void* dest, const void *src,size_t n) { if (((w32)dest) i4_check_min) break_mem_fun(); bcopy(src,dest,n); } #endif #endif i4_block_manager_class bmanage[5]; int bmanage_total=0; void inspect_memory() { mem_lock.lock(); for (int i=0;i alloc_list&(1< next; } } } } void i4_malloc_uninit() { #ifdef i4_MEM_CHECK i4_mem_report("end.mem"); #endif mem_lock.lock(); for (int i=0;i =i4_malloc_min_size;) { mem=malloc(size); if (!mem) size-=0x100; } if (mem) { bmanage[bmanage_total].init(mem,size); bmanage_total++; size-=0x1000; } else i4_error(not_enough_total_memory_message); } } class i4_memory_init_class : public i4_init_class { public: int init_type() { return I4_INIT_TYPE_MEMORY_MANAGER; } void init() { i4_malloc_init(); } void uninit() { i4_malloc_uninit(); } } i4_memory_init_instance; long i4_available() { mem_lock.lock(); long size=0; for (int i=0;i l) l=t; } mem_lock.unlock(); return l; } long i4_allocated() { mem_lock.lock(); long size=0; for (int i=0;i =(void *)bmanage[i].sfirst) // is the pointer in this block? { if (ptr<=(void *)bmanage[i].slast) // is it in static space? { bmanage[i].free(ptr); mem_lock.unlock(); pf_free.stop(); return ; } } mem_lock.unlock(); i4_error("i4_free : bad pointer\n"); pf_free.stop(); } void *i4_realloc(void *ptr, w32 size, char *file, int line) { if (!ptr) { // malloc is already lock protected return i4_malloc(size, file, line); } if (!bmanage_total) { // thread protect the c library realloc mem_lock.lock(); void *ret=realloc(ptr,size); mem_lock.unlock(); return ret; } if (size==0) { // free is already lock protected i4_free(ptr); return NULL; } sw32 old_size=0; for (int i=0;i =(void *)bmanage[i].sfirst && ptr<=(void *)(((char *)bmanage[i].sfirst)+bmanage[i].block_size)) { old_size=bmanage[i].pointer_size(ptr); if (ptr<=(void *)bmanage[i].slast) { void *nptr=i4_malloc(size, file, line); if ((sw32)size>old_size) memcpy(nptr,ptr,old_size); else memcpy(nptr,ptr,size); bmanage[i].free(ptr); return nptr; } } i4_error("jrealloc : bad pointer\n"); return NULL; } void dmem_report() { i4_mem_report("debug.mem"); } static i4_static_file_class mem_report; void i4_mem_report(char *filename) { i4_file_class *fp=mem_report.open(filename); if (fp) { for (int i=0;i printf("Total available=%d, allocated=%d\n", i4_available(), i4_allocated()); } } long small_ptr_size(void *ptr) { return ((small_block *)(((long *)ptr)[-1]))->size; } int valid_ptr(void *ptr) { if (!bmanage_total) { return 0; } for (int i=0;i =(void *)bmanage[i].sfirst) // is the pointer in this block? { if (ptr<=(void *)bmanage[i].slast) { int ret=bmanage[i].valid_ptr(ptr); return ret; } } return 0; } int valid_memory(void *ptr) { for (int i=0; i =(void *)bmanage[i].sfirst) // is the pointer in this block? if (ptr<=(void *)bmanage[i].slast) return 1; return 0; }