diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2007-12-18 20:36:40 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2007-12-18 20:36:40 +0000 |
commit | 543fe820616f31350366ab61052050303d17dd25 (patch) | |
tree | a2e4702be2cd9988ed341586c1c8c976b8ba3bb8 /cpukit/libcsupport/src/malloc_boundary.c | |
parent | 2007-12-18 Joel Sherrill <joel.sherrill@OARcorp.com> (diff) | |
download | rtems-543fe820616f31350366ab61052050303d17dd25.tar.bz2 |
2007-12-18 Joel Sherrill <joel.sherrill@oarcorp.com>
* libcsupport/Makefile.am, libcsupport/preinstall.am,
libcsupport/src/malloc.c, libcsupport/src/mallocinfo.c,
libmisc/Makefile.am, libmisc/shell/main_mallocinfo.c,
libmisc/shell/shellconfig.h: Split malloc.c into multiple files with
one function per file. Also split out statistics into a separate file
which can be plugged in dynamically. Right now, it is always in. I
suspect that splitting the file removed more code than leaving
statistics in. I tinkered with malloc information command in the
shell. I resurrected the malloc arena code as malloc boundary. This
code is now compiled all the time even though it does not appear to
work.
* libcsupport/include/rtems/malloc.h, libcsupport/src/_calloc_r.c,
libcsupport/src/_free_r.c, libcsupport/src/_malloc_r.c,
libcsupport/src/_realloc_r.c, libcsupport/src/calloc.c,
libcsupport/src/free.c, libcsupport/src/malloc_boundary.c,
libcsupport/src/malloc_get_statistics.c,
libcsupport/src/malloc_initialize.c, libcsupport/src/malloc_p.h,
libcsupport/src/malloc_report_statistics.c,
libcsupport/src/malloc_report_statistics_plugin.c,
libcsupport/src/malloc_statistics_helpers.c,
libcsupport/src/malloc_walk.c, libcsupport/src/realloc.c,
libmisc/shell/main_perioduse.c: New files.
Diffstat (limited to 'cpukit/libcsupport/src/malloc_boundary.c')
-rw-r--r-- | cpukit/libcsupport/src/malloc_boundary.c | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/cpukit/libcsupport/src/malloc_boundary.c b/cpukit/libcsupport/src/malloc_boundary.c new file mode 100644 index 0000000000..706e224294 --- /dev/null +++ b/cpukit/libcsupport/src/malloc_boundary.c @@ -0,0 +1,194 @@ +/* + * RTEMS Malloc Block Boundary Integrity Checker + * + * WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * + * This file is built but never called. It is a first + * step in reintegrating this functionality. + * This code was disabled for a LONG time in malloc.c. + * This is a restructured and slightly modified version + * that should be able to be configured as a plugin BUT + * it has not been tested recently. When it has been + * tested again, please remove this comment. + * + * JOEL: I have not analyzed this code in terms of + * the heap changes post 4.6. It is possible + * that that way the boundary area is carved + * off breaks the alignment. + * + * WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "malloc_p.h" + +#include <stdio.h> + +#ifdef RTEMS_NEWLIB + +#define SENTINELSIZE 12 +#define SENTINEL "\xD1\xAC\xB2\xF1" "BITE ME" +#define CALLCHAINSIZE 5 + +struct mallocNode { + struct mallocNode *back; + struct mallocNode *forw; + int callChain[CALLCHAINSIZE]; + size_t size; + void *memory; +}; + +struct mallocNode mallocNodeHead; + +void rtems_malloc_boundary_initialize(void) +{ + mallocNodeHead.back = &mallocNodeHead; + mallocNodeHead.forw = &mallocNodeHead; +} + +uint32_t rtems_malloc_boundary_overhead(void) +{ + return sizeof(struct mallocNode) + SENTINELSIZE; +} + +void rtems_malloc_boundary_at_malloc( + void *pointer, + size_t size +) +{ + void *return_this; + struct mallocNode *mp = (struct mallocNode *)pointer; + int *fp, *nfp, i; + + _RTEMS_Lock_allocator(); + mp->memory = mp + 1; + return_this = mp->memory; + mp->size = size - (sizeof(struct mallocNode) + SENTINELSIZE); + fp = (int *)&size - 2; + for (i = 0 ; i < CALLCHAINSIZE ; i++) { + mp->callChain[i] = fp[1]; + nfp = (int *)(fp[0]); + if((nfp <= fp) || (nfp > (int *)(1 << 24))) + break; + fp = nfp; + } + while (i < CALLCHAINSIZE) + mp->callChain[i++] = 0; + memcpy((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE); + mp->forw = mallocNodeHead.forw; + mp->back = &mallocNodeHead; + mallocNodeHead.forw->back = mp; + mallocNodeHead.forw = mp; + _RTEMS_Unlock_allocator(); +} + +void reportMallocError(const char *msg, struct mallocNode *mp); + +void rtems_malloc_boundary_at_free( + void *pointer +) +{ + struct mallocNode *mp = (struct mallocNode *)pointer - 1; + struct mallocNode *mp1; + + _RTEMS_Lock_allocator(); + if ((mp->memory != (mp + 1)) || + (memcmp((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE) != 0)) + reportMallocError("Freeing with inconsistent pointer/sentinel", mp); + mp1 = mallocNodeHead.forw; + while (mp1 != &mallocNodeHead) { + if (mp1 == mp) + break; + mp1 = mp1->forw; + } + if (mp1 != mp) + reportMallocError("Freeing, but not on allocated list", mp); + mp->forw->back = mp->back; + mp->back->forw = mp->forw; + mp->back = mp->forw = NULL; + pointer = mp; + _RTEMS_Unlock_allocator(); +} + +void rtems_malloc_boundary_at_realloc( + void *pointer, + size_t size +) +{ + /* this needs to be implemented */ +} + +/* + * Malloc boundary support plugin + */ +rtems_malloc_boundary_functions_t rtems_malloc_boundary_functions_table = { + rtems_malloc_boundary_initialize, + rtems_malloc_boundary_overhead, + rtems_malloc_boundary_at_malloc, + rtems_malloc_boundary_at_free, + rtems_malloc_boundary_at_realloc, +}; + +rtems_malloc_boundary_functions_t *rtems_malloc_boundary_helpers = NULL; +/* &rtems_malloc_boundary_functions_table; */ + +void reportMallocError(const char *msg, struct mallocNode *mp) +{ + unsigned char *sp = (unsigned char *)mp->memory + mp->size; + int i, ind = 0; + static char cbuf[500]; + ind += sprintf(cbuf+ind, "Malloc Error: %s\n", msg); + if ((mp->forw->back != mp) || (mp->back->forw != mp)) + ind += sprintf(cbuf+ind, + "mp:%p mp->forw:%p mp->forw->back:%p " + "mp->back:%p mp->back->forw:%p\n", + mp, mp->forw, mp->forw->back, mp->back, mp->back->forw); + if (mp->memory != (mp + 1)) + ind += sprintf(cbuf+ind, "mp+1:%p ", mp + 1); + ind += sprintf(cbuf+ind, "mp->memory:%p mp->size:%d\n", mp->memory, mp->size); + if (memcmp((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE) != 0) { + ind += sprintf(cbuf+ind, "mp->sentinel: "); + for (i = 0 ; i < SENTINELSIZE ; i++) + ind += sprintf(cbuf+ind, " 0x%x", sp[i]); + ind += sprintf(cbuf+ind, "\n"); + } + ind += sprintf(cbuf+ind, "Call chain:"); + for (i = 0 ; i < CALLCHAINSIZE ; i++) { + if (mp->callChain[i] == 0) + break; + ind += sprintf(cbuf+ind, " 0x%x", mp->callChain[i]); + } + printk("\n\n%s\n\n", cbuf); +} + +void checkMallocArena(void) +{ + struct mallocNode *mp; + + _RTEMS_Lock_allocator(); + for ( mp = mallocNodeHead.forw; mp != &mallocNodeHead ; mp = mp->forw ) { + if ((mp->forw->back != mp) || (mp->back->forw != mp)) + reportMallocError("Pointers mangled", mp); + if ((mp->memory != (mp + 1)) || + (memcmp((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE) != 0)) + reportMallocError("Inconsistent pointer/sentinel", mp); + } + _RTEMS_Unlock_allocator(); +} + +#endif + |