diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2006-07-13 15:07:28 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2006-07-13 15:07:28 +0000 |
commit | aae22fa1c92df5ee70fa478f831c64287344879c (patch) | |
tree | 82d1b83aff375d2ab6b0d09427560550c1b7db1e /gst/nsf/memguard.c | |
parent | 9d2c04267dec2eda43a150b2541d5c5a0f9eaf18 (diff) | |
download | gst-plugins-bad-aae22fa1c92df5ee70fa478f831c64287344879c.tar.gz gst-plugins-bad-aae22fa1c92df5ee70fa478f831c64287344879c.tar.bz2 gst-plugins-bad-aae22fa1c92df5ee70fa478f831c64287344879c.zip |
Added NSF decoder plugin. Fixes 151192.
Original commit message from CVS:
Based on patches by: Johan Dahlin <johan at gnome dot org>
Ronald Bultje <rbultje at ronald dot bitfreak dot net>
* configure.ac:
* gst/nsf/Makefile.am:
* gst/nsf/dis6502.h:
* gst/nsf/fds_snd.c:
* gst/nsf/fds_snd.h:
* gst/nsf/fmopl.c:
* gst/nsf/fmopl.h:
* gst/nsf/gstnsf.c:
* gst/nsf/gstnsf.h:
* gst/nsf/log.c:
* gst/nsf/log.h:
* gst/nsf/memguard.c:
* gst/nsf/memguard.h:
* gst/nsf/mmc5_snd.c:
* gst/nsf/mmc5_snd.h:
* gst/nsf/nes6502.c:
* gst/nsf/nes6502.h:
* gst/nsf/nes_apu.c:
* gst/nsf/nes_apu.h:
* gst/nsf/nsf.c:
* gst/nsf/nsf.h:
* gst/nsf/osd.h:
* gst/nsf/types.h:
* gst/nsf/vrc7_snd.c:
* gst/nsf/vrc7_snd.h:
* gst/nsf/vrcvisnd.c:
* gst/nsf/vrcvisnd.h:
Added NSF decoder plugin. Fixes 151192.
Diffstat (limited to 'gst/nsf/memguard.c')
-rw-r--r-- | gst/nsf/memguard.c | 398 |
1 files changed, 398 insertions, 0 deletions
diff --git a/gst/nsf/memguard.c b/gst/nsf/memguard.c new file mode 100644 index 00000000..8ad9749d --- /dev/null +++ b/gst/nsf/memguard.c @@ -0,0 +1,398 @@ +/* +** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) +** +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of version 2 of the GNU Library General +** Public License as published by the Free Software Foundation. +** +** 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 +** Library General Public License for more details. To obtain a +** copy of the GNU Library General Public License, write to the Free +** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Any permitted reproduction of these routines, in whole or in part, +** must bear this legend. +** +** +** memguard.c +** +** memory allocation wrapper routines +** +** NOTE: based on code (c) 1998 the Retrocade group +** $Id$ +*/ + +#include "types.h" + +/* undefine macro definitions, so we get real calls */ +#undef malloc +#undef free + +#include <string.h> +#include <stdlib.h> +#include "memguard.h" +#include "log.h" + + +/* Maximum number of allocated blocks at any one time */ +#define MAX_BLOCKS 16384 + +/* Memory block structure */ +typedef struct memblock_s +{ + void *block_addr; + int block_size; + char *file_name; + int line_num; +} memblock_t; + +boolean mem_debug = TRUE; /* debugging flag */ + + +#ifdef NOFRENDO_DEBUG + +static int mem_blockcount = 0; /* allocated block count */ +static memblock_t *mem_record = NULL; + +#define GUARD_STRING "GgUuAaRrDdSsTtRrIiNnGgBbLlOoCcKk" +#define GUARD_LENGTH 64 /* before and after allocated block */ + + +/* +** Check the memory guard to make sure out of bounds writes have not +** occurred. +*/ +static boolean +mem_checkguardblock (void *data, int guard_size) +{ + uint8 *orig, *chk, *blk; + int i, alloc_size; + + /* get the original pointer */ + orig = (((uint8 *) data) - guard_size); + + /* get the size */ + alloc_size = *((uint32 *) orig); + + /* now skip past the size */ + blk = orig + sizeof (uint32); + + /* check leading guard string */ + chk = GUARD_STRING; + for (i = sizeof (uint32); i < guard_size; i++) { + if (0 == *chk) + chk = GUARD_STRING; + if (*blk != *chk) + return FALSE; + chk++; + blk++; + } + + /* check end of block */ + chk = GUARD_STRING; + blk = ((uint8 *) data) + alloc_size; + for (i = 0; i < guard_size; i++) { + if (0 == *chk) + chk = GUARD_STRING; + if (*blk != *chk) + return FALSE; + chk++; + blk++; + } + + /* we're okay! */ + return TRUE; +} + +/* free a guard block */ +static void +mem_freeguardblock (void *data, int guard_size) +{ + uint8 *orig = (((uint8 *) data) - guard_size); + + free (orig); +} + +/* fill in the memory guard, advance the pointer to the 'real' memory */ +static void * +mem_guardblock (int alloc_size, int guard_size) +{ + void *orig; + uint8 *blk, *chk; + int i; + + /* allocate memory */ + orig = calloc (alloc_size + (guard_size * 2), 1); + if (NULL == orig) + return NULL; + + blk = ((uint8 *) orig); + + /* store the size of the newly allocated block */ + *((uint32 *) blk) = alloc_size; + + /* skip past the size */ + blk += sizeof (uint32); + + /* put guard string at beginning of block */ + chk = GUARD_STRING; + for (i = sizeof (uint32); i < guard_size; i++) { + if (0 == *chk) + chk = GUARD_STRING; + *blk++ = *chk++; + } + + /* check end of block */ + chk = GUARD_STRING; + blk = guard_size + (uint8 *) orig + alloc_size; + for (i = 0; i < guard_size; i++) { + if (0 == *chk) + chk = GUARD_STRING; + *blk++ = *chk++; + } + + return (void *) (guard_size + (uint8 *) orig); +} + + +/* Allocate a bunch of memory to keep track of all memory blocks */ +static void +mem_init (void) +{ + if (mem_record) { + free (mem_record); + mem_record = NULL; + } + + mem_record = calloc (MAX_BLOCKS * sizeof (memblock_t), 1); + ASSERT (mem_record); +} + +/* add a block of memory to the master record */ +static void +mem_addblock (void *data, int block_size, char *file, int line) +{ + int i; + + for (i = 0; i < MAX_BLOCKS; i++) { + if (NULL == mem_record[i].block_addr) { + mem_record[i].block_addr = data; + mem_record[i].block_size = block_size; + mem_record[i].file_name = file; + mem_record[i].line_num = line; + return; + } + } + + ASSERT_MSG ("out of memory blocks."); +} + +/* find an entry in the block record and delete it */ +static void +mem_deleteblock (void *data, char *file, int line) +{ + int i; + char fail[256]; + + for (i = 0; i < MAX_BLOCKS; i++) { + if (data == mem_record[i].block_addr) { + if (FALSE == mem_checkguardblock (mem_record[i].block_addr, GUARD_LENGTH)) { + sprintf (fail, + "mem_deleteblock 0x%08X at line %d of %s -- block corrupt", + (uint32) data, line, file); + ASSERT_MSG (fail); + } + + memset (&mem_record[i], 0, sizeof (memblock_t)); + return; + } + } + + sprintf (fail, "mem_deleteblock 0x%08X at line %d of %s -- block not found", + (uint32) data, line, file); + ASSERT_MSG (fail); +} +#endif /* NOFRENDO_DEBUG */ + +/* allocates memory and clears it */ +#ifdef NOFRENDO_DEBUG +void * +_my_malloc (int size, char *file, int line) +#else +void * +_my_malloc (int size) +#endif +{ + void *temp; + char fail[256]; + +#ifdef NOFRENDO_DEBUG + if (NULL == mem_record && FALSE != mem_debug) + mem_init (); + + if (FALSE != mem_debug) + temp = mem_guardblock (size, GUARD_LENGTH); + else +#endif /* NOFRENDO_DEBUG */ + temp = calloc (sizeof (uint8), size); + + if (NULL == temp) { +#ifdef NOFRENDO_DEBUG + sprintf (fail, "malloc: out of memory at line %d of %s. block size: %d\n", + line, file, size); +#else + sprintf (fail, "malloc: out of memory. block size: %d\n", size); +#endif + ASSERT_MSG (fail); + } +#ifdef NOFRENDO_DEBUG + if (FALSE != mem_debug) + mem_addblock (temp, size, file, line); + + mem_blockcount++; +#endif + + return temp; +} + +/* free a pointer allocated with my_malloc */ +#ifdef NOFRENDO_DEBUG +void +_my_free (void **data, char *file, int line) +#else +void +_my_free (void **data) +#endif +{ + char fail[256]; + + if (NULL == data || NULL == *data + || 0xFFFFFFFF == (uint32) * data || 0xFFFFFFFF == (uint32) data) { +#ifdef NOFRENDO_DEBUG + sprintf (fail, "free: attempted to free NULL pointer at line %d of %s\n", + line, file); +#else + sprintf (fail, "free: attempted to free NULL pointer.\n"); +#endif + ASSERT_MSG (fail); + } +#ifdef NOFRENDO_DEBUG + /* if this is true, we are in REAL trouble */ + if (0 == mem_blockcount) { + ASSERT_MSG ("free: attempted to free memory when no blocks available"); + } + + if (FALSE != mem_debug) + mem_deleteblock (*data, file, line); + + mem_blockcount--; /* dec our block count */ + + if (FALSE != mem_debug) + mem_freeguardblock (*data, GUARD_LENGTH); + else +#endif /* NOFRENDO_DEBUG */ + free (*data); + + *data = NULL; /* NULL our source */ +} + +/* check for orphaned memory handles */ +void +mem_checkleaks (void) +{ +#ifdef NOFRENDO_DEBUG + int i; + + if (FALSE == mem_debug) + return; + + if (mem_blockcount) { + log_printf ("memory leak - %d unfreed block%s\n\n", mem_blockcount, + mem_blockcount == 1 ? "" : "s"); + + for (i = 0; i < MAX_BLOCKS; i++) { + if (mem_record[i].block_addr) { + log_printf ("addr: 0x%08X, size: %d, line %d of %s%s\n", + (uint32) mem_record[i].block_addr, + mem_record[i].block_size, + mem_record[i].line_num, + mem_record[i].file_name, + (FALSE == mem_checkguardblock (mem_record[i].block_addr, + GUARD_LENGTH)) + ? " -- block corrupt" : ""); + } + } + } else + log_printf ("no memory leaks\n"); +#endif +} + +void +mem_checkblocks (void) +{ +#ifdef NOFRENDO_DEBUG + int i; + + if (FALSE == mem_debug) + return; + + for (i = 0; i < MAX_BLOCKS; i++) { + if (mem_record[i].block_addr) { + if (FALSE == mem_checkguardblock (mem_record[i].block_addr, GUARD_LENGTH)) { + log_printf ("addr: 0x%08X, size: %d, line %d of %s -- block corrupt\n", + (uint32) mem_record[i].block_addr, + mem_record[i].block_size, + mem_record[i].line_num, mem_record[i].file_name); + } + } + } +#endif /* NOFRENDO_DEBUG */ +} + +/* +** $Log$ +** Revision 1.1 2006/07/13 15:07:28 wtay +** Based on patches by: Johan Dahlin <johan at gnome dot org> +** Ronald Bultje <rbultje at ronald dot bitfreak dot net> +** * configure.ac: +** * gst/nsf/Makefile.am: +** * gst/nsf/dis6502.h: +** * gst/nsf/fds_snd.c: +** * gst/nsf/fds_snd.h: +** * gst/nsf/fmopl.c: +** * gst/nsf/fmopl.h: +** * gst/nsf/gstnsf.c: +** * gst/nsf/gstnsf.h: +** * gst/nsf/log.c: +** * gst/nsf/log.h: +** * gst/nsf/memguard.c: +** * gst/nsf/memguard.h: +** * gst/nsf/mmc5_snd.c: +** * gst/nsf/mmc5_snd.h: +** * gst/nsf/nes6502.c: +** * gst/nsf/nes6502.h: +** * gst/nsf/nes_apu.c: +** * gst/nsf/nes_apu.h: +** * gst/nsf/nsf.c: +** * gst/nsf/nsf.h: +** * gst/nsf/osd.h: +** * gst/nsf/types.h: +** * gst/nsf/vrc7_snd.c: +** * gst/nsf/vrc7_snd.h: +** * gst/nsf/vrcvisnd.c: +** * gst/nsf/vrcvisnd.h: +** Added NSF decoder plugin. Fixes 151192. +** +** Revision 1.8 2000/06/26 04:54:48 matt +** simplified and made more robust +** +** Revision 1.7 2000/06/12 01:11:41 matt +** cleaned up some error output for win32 +** +** Revision 1.6 2000/06/09 15:12:25 matt +** initial revision +** +*/ |