/*
* ----------------------------------------------------------------
* Night Light Memory Allocation Library Functions (memcalls.c)
* ----------------------------------------------------------------
* Copyright (C) 1997-2007 Jonas Kvinge <jonas@night-light.net>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Last modified by:
* Jonas Kvinge (04.10.2006)
*
*/
#define MEMCALLS_C
#define LIBRARY
#define NEED_SYS_TYPES_H 1 /* Extra types */
#define NEED_SYS_PARAM_H 1 /* Some systems need this */
#define NEED_LIMITS_H 0 /* Kernel limits */
#define NEED_STDARG_H 1 /* va_list, etc */
#define NEED_ERRNO_H 1 /* errno */
#define NEED_CTYPE_H 1 /* isdigit(), etc */
#define NEED_NETINET_IN_H 0 /* in_addr, sockaddr_in, etc */
#define NEED_ARPA_INET_H 0 /* inet_ntoa(), inet_aton(), etc */
#define NEED_STDIO_H 1 /* Standard C UNIX functions */
#define NEED_STDLIB_H 1 /* malloc(), exit(), atoi(), etc */
#define NEED_TIME_H 1 /* time(), etc */
#define NEED_SYSCTL_H 0 /* sysctl(), etc */
#define NEED_SYS_STAT_H 0 /* chmod(), mkdir(), etc */
#define NEED_SYS_UIO_H 0 /* iovec, etc */
#define NEED_FCNTL_H 1 /* open(), creat(), fcntl(), etc */
#define NEED_SYS_IOCTL_H 0 /* ioctl(), etc */
#define NEED_SYS_FILIO_H 0 /* Solaris need this for ioctl(), etc */
#define NEED_UNISTD_H 1 /* Unix standard functions */
#define NEED_STRING_H 1 /* C string functions */
#define NEED_SIGNAL_H 0 /* Signal functions */
#define NEED_SYS_SOCKET_H 0 /* Socket functions */
#define NEED_NETDB_H 0 /* Network database functions */
#define NEED_ARPA_NAMESER_H 0 /* Nameserver definitions */
#define NEED_GETUSERPW_HEADERS 0 /* Functions to retrive system passwords */
#include "config.h"
#include "headers.h"
#include "defines.h"
#include "memcalls_int.h"
#ifdef MALLOC_REDEFINE
#error "Sanity check: malloc() can't be redefined in here!"
#endif
/* VARIABLES - JONAS (21.09.2001) */
struct MemTable_Struct *MemTable_Head = NULL;
struct MemTable_Struct *MemTable_Tail = NULL;
unsigned long int G_Allocations = 0;
struct MemTable_Struct *MemHashTable[MALLOC_HASH_SIZE] = { NULL };
size_t MemPrefixSize = (const size_t) sizeof(MALLOC_PREFIX);
size_t MemPostfixSize = (const size_t) sizeof(MALLOC_POSTFIX);
unsigned short int IgnoreWildPTR = FALSE;
/* MEMTABLE_ADD - JONAS (21.09.2001) */
void memtable_add(const void *const PTR, const char *const FilePT, const unsigned short int Line, const char *const FunctionPT, const size_t Size) {
struct MemTable_Struct *MemTableS = NULL;
struct MemTable_Struct *MemTableS_NEW = NULL;
unsigned long int Hash = 0;
assert(PTR != NULL);
assert(FilePT != NULL);
assert(FunctionPT != NULL);
MemTableS_NEW = malloc(sizeof(struct MemTable_Struct));
if (MemTableS_NEW == NULL) {
return;
}
memset(MemTableS_NEW, 0, sizeof(struct MemTable_Struct));
MemTableS_NEW->PTR = (const void *const) PTR;
MemTableS_NEW->File = (const char *const) FilePT;
MemTableS_NEW->Line = (const unsigned short int) Line;
MemTableS_NEW->Function = (const char *const) FunctionPT;
MemTableS_NEW->Size = Size;
MemTableS_NEW->Time = NOW;
if (MemTable_Head == NULL) {
MemTable_Head = MemTableS_NEW;
MemTable_Tail = MemTableS_NEW;
}
else {
MemTableS = MemTable_Tail;
MemTableS->Next = MemTableS_NEW;
MemTableS_NEW->Prev = MemTableS;
MemTable_Tail = MemTableS_NEW;
}
Hash = MallocHash(PTR);
if (MemHashTable[Hash] == NULL) { MemHashTable[Hash] = MemTableS_NEW; }
else {
for (MemTableS = MemHashTable[Hash] ; (MemTableS->NextH != NULL) ; MemTableS = MemTableS->NextH);
MemTableS->NextH = MemTableS_NEW;
MemTableS_NEW->PrevH = MemTableS;
}
G_Allocations++;
#ifdef DEBUGPRINT
DEBUGPRINT(BITMASK_DEBUG_MEMORY, "%s() - Pointer: %p - File: %s - Line: %d - Function: %s", __FUNCTION__, PTR, FilePT, Line, FunctionPT);
#endif
}
/* MEMTABLE_REM - JONAS (21.09.2001) */
void memtable_rem(struct MemTable_Struct *MemTableS) {
struct MemTable_Struct *MemTableH = NULL;
unsigned long int Hash = 0;
assert(MemTableS != NULL);
if (MemTableS->Prev == NULL) { MemTable_Head = MemTableS->Next; }
else { MemTableS->Prev->Next = MemTableS->Next; }
if (MemTableS->Next == NULL) { MemTable_Tail = MemTableS->Prev; }
else { MemTableS->Next->Prev = MemTableS->Prev; }
Hash = MallocHash(MemTableS->PTR);
for (MemTableH = MemHashTable[Hash] ; ((MemTableH != NULL) && (MemTableH != MemTableS)) ; MemTableH = MemTableH->NextH);
assert(MemTableH == MemTableS);
if (MemTableH->PrevH != NULL) { MemTableH->PrevH->NextH = MemTableH->NextH; }
if (MemTableH->NextH != NULL) { MemTableH->NextH->PrevH = MemTableH->PrevH; }
if (MemHashTable[Hash] == MemTableH) { MemHashTable[Hash] = MemTableH->NextH; }
G_Allocations--;
#ifdef DEBUGPRINT
DEBUGPRINT(BITMASK_DEBUG_MEMORY, "%s() - Pointer: %p - File: %s - Line: %d - Function: %s", __FUNCTION__, MemTableS->PTR, MemTableS->File, MemTableS->Line, MemTableS->Function);
#endif
free(MemTableS);
}
/* MEMTABLE_GET - JONAS (21.09.2001) */
struct MemTable_Struct *memtable_get(const void *const PTR) {
struct MemTable_Struct *MemTableH = MemHashTable[MallocHash(PTR)];
while ((MemTableH != NULL) && (PTR != MemTableH->PTR)) { MemTableH = MemTableH->NextH; }
return(MemTableH);
}
/* MEMALLOC - JONAS (21.09.2001) */
void *memalloc(const char *const FilePT, const unsigned short int Line, const char *const FunctionPT, const size_t MemSize) {
void *MemPTR = NULL;
void *PrefixPTR = NULL;
void *PostfixPTR = NULL;
size_t RealSize = MemSize + MemPrefixSize + MemPostfixSize;
#ifdef DEBUGPRINT
DEBUGPRINT(BITMASK_DEBUG_MEMORY, "%s() - File: %s - Line: %d - Function: %s - Size: %ld", __FUNCTION__, FilePT, Line, FunctionPT, (PRINT_SIZE_T) MemSize);
#endif
if (MemSize > MALLOC_LIMIT) {
fprintf(stderr, "ERROR: Memory request to large from function %s() (%s:%d) (%ld bytes).\n", FunctionPT, FilePT, Line, (PRINT_SIZE_T) MemSize);
return(NULL);
}
PrefixPTR = malloc(RealSize);
if (PrefixPTR == NULL) {
fprintf(stderr, "ERROR: Memory allocation failure in function %s() (%s:%d): %ld bytes: [%d] %s\n", FunctionPT, FilePT, Line, (PRINT_SIZE_T) MemSize, errno, strerror(errno));
return(NULL);
}
memset(PrefixPTR, 0, RealSize);
PostfixPTR = PrefixPTR + MemPrefixSize + MemSize;
MemPTR = PrefixPTR + MemPrefixSize;
strcpy(PrefixPTR, MALLOC_PREFIX);
strcpy(PostfixPTR, MALLOC_POSTFIX);
memtable_add(MemPTR, FilePT, Line, FunctionPT, MemSize);
return(MemPTR);
}
/* MEMREALLOC - JONAS (26.03.2002) */
void *memrealloc(const char *const FilePT, const unsigned short int Line, const char *const FunctionPT, void *const OldPTR, const size_t MemSize) {
struct MemTable_Struct *MemTableS = NULL;
void *NewPTR = NULL;
void *OldPrefixPTR = NULL;
void *OldPostfixPTR = NULL;
void *NewPrefixPTR = NULL;
void *NewPostfixPTR = NULL;
size_t RealSize = 0;
#ifdef DEBUGPRINT
DEBUGPRINT(BITMASK_DEBUG_MEMORY, "%s() - File: %s - Line: %d - Function: %s - Size: %ld", __FUNCTION__, FilePT, Line, FunctionPT, (PRINT_SIZE_T) MemSize);
#endif
if (OldPTR != NULL) {
MemTableS = memtable_get(OldPTR);
if (MemTableS == NULL) {
if (IgnoreWildPTR == FALSE) { fprintf(stderr, "ERROR: Wild pointer %p from function %s() (%s:%d) passed to function realloc().\n", OldPTR, FunctionPT, FilePT, Line); }
}
else {
if (MemTableS->Size == MemSize) { return(OldPTR); }
OldPrefixPTR = OldPTR - MemPrefixSize;
OldPostfixPTR = OldPTR + MemTableS->Size;
if (strncmp(OldPrefixPTR, MALLOC_PREFIX, MALLOC_PREFIX_LEN) != 0) {
fprintf(stderr, "ERROR: Magic memory prefix \"%s\" corrupt on pointer %p from function %s() (%s:%d) passed to function realloc().\n", MALLOC_PREFIX, OldPTR, FunctionPT, FilePT, Line);
abort();
}
if (strncmp(OldPostfixPTR, MALLOC_POSTFIX, MALLOC_POSTFIX_LEN) != 0) {
fprintf(stderr, "ERROR: Magic memory postfix \"%s\" corrupt on pointer %p from function %s() (%s:%d) passed to function realloc().\n", MALLOC_POSTFIX, OldPTR, FunctionPT, FilePT, Line);
abort();
}
memtable_rem(MemTableS);
}
}
if (MemSize > MALLOC_LIMIT) {
fprintf(stderr, "ERROR: Memory request to large from function %s (%s:%d) (%ld bytes).\n", FunctionPT, FilePT, Line, (PRINT_SIZE_T) MemSize);
return(NULL);
}
if (MemSize == 0) {
if (OldPrefixPTR != NULL) { free(OldPrefixPTR); }
return(NULL);
}
if (OldPostfixPTR != NULL) { memset(OldPostfixPTR, 0, MemPostfixSize); }
RealSize += MemPrefixSize;
RealSize += MemSize;
RealSize += MemPostfixSize;
NewPrefixPTR = realloc(OldPrefixPTR, RealSize);
if (NewPrefixPTR == NULL) {
if (RealSize > 0) { fprintf(stderr, "ERROR: Memory allocation failure in function %s (%s:%d): %ld bytes: [%d] %s\n", FunctionPT, FilePT, Line, (PRINT_SIZE_T) MemSize, errno, strerror(errno)); }
return(NULL);
}
NewPostfixPTR = NewPrefixPTR + MemPrefixSize + MemSize;
NewPTR = NewPrefixPTR + MemPrefixSize;
strcpy(NewPrefixPTR, MALLOC_PREFIX);
strcpy(NewPostfixPTR, MALLOC_POSTFIX);
memtable_add(NewPTR, FilePT, Line, FunctionPT, MemSize);
return(NewPTR);
}
/* MEMCALLOC - JONAS (21.09.2001) */
void *memcalloc(const char *const FilePT, const unsigned short int Line, const char *const FunctionPT, const size_t Elements, const size_t Size) {
size_t MemSize = (Size * Elements);
void *PTR = memalloc(FilePT, Line, FunctionPT, MemSize);
return(PTR);
}
/* MEMFREE - JONAS (21.09.2001) */
signed short int memfree(const char *const FilePT, const unsigned short int Line, const char *const FunctionPT, void *const MemPTR) {
struct MemTable_Struct *MemTableS = NULL;
void *PrefixPTR = NULL;
void *PostfixPTR = NULL;
size_t TotalSize = 0;
#ifdef DEBUGPRINT
DEBUGPRINT(BITMASK_DEBUG_MEMORY, "%s() - File: %s - Line: %d - Function: %s - Pointer: %p", __FUNCTION__, FilePT, Line, FunctionPT, MemPTR);
#endif
if (MemPTR == NULL) { return(SUCCESS); }
MemTableS = memtable_get(MemPTR);
if (MemTableS == NULL) {
if (IgnoreWildPTR == FALSE) { fprintf(stderr, "ERROR: Wild pointer %p from function %s (%s:%d) passed to function free().\n", MemPTR, FunctionPT, FilePT, Line); }
return(ERROR);
}
PrefixPTR = MemPTR - MemPrefixSize;
PostfixPTR = MemPTR + MemTableS->Size;
TotalSize = MemPrefixSize + MemTableS->Size + MemPostfixSize;
if (strncmp(PrefixPTR, MALLOC_PREFIX, MALLOC_PREFIX_LEN) != 0) {
fprintf(stderr, "ERROR: Magic memory prefix \"%s\" corrupt on pointer %p from function %s (%s:%d) passed to function free().\n", MALLOC_PREFIX, MemPTR, FunctionPT, FilePT, Line);
abort();
}
if (strncmp(PostfixPTR, MALLOC_POSTFIX, MALLOC_POSTFIX_LEN) != 0) {
fprintf(stderr, "ERROR: Magic memory postfix \"%s\" corrupt on pointer %p from function %s (%s:%d) passed to function free().\n", MALLOC_POSTFIX, MemPTR, FunctionPT, FilePT, Line);
abort();
}
memtable_rem(MemTableS);
memset(PrefixPTR, MALLOC_REDBYTE, TotalSize);
free(PrefixPTR);
return(SUCCESS);
}
syntax highlighted by Code2HTML, v. 0.9.1