source: rtems/cpukit/libcsupport/src/malloc_boundary.c @ 88db141

4.104.11
Last change on this file since 88db141 was 88db141, checked in by Ralf Corsepius <ralf.corsepius@…>, on Nov 19, 2009 at 1:51:40 PM

2009-11-19 Ralf Corsépius <ralf.corsepius@…>

  • Property mode set to 100644
File size: 5.8 KB
Line 
1/*
2 *  RTEMS Malloc Block Boundary Integrity Checker
3 *
4 *  WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!
5 *  WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!
6 *
7 *  This file is built but never called.  It is a first
8 *  step in reintegrating this functionality.
9 *  This code was disabled for a LONG time in malloc.c.
10 *  This is a restructured and slightly modified version
11 *  that should be able to be configured as a plugin BUT
12 *  it has not been tested recently.  When it has been
13 *  tested again, please remove this comment.
14 *
15 *  JOEL: I have not analyzed this code in terms of
16 *        the heap changes post 4.6.  It is possible
17 *        that that way the boundary area is carved
18 *        off breaks the alignment.
19 *
20 *  WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!
21 *  WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!
22 *
23 *  COPYRIGHT (c) 1989-2007.
24 *  On-Line Applications Research Corporation (OAR).
25 *
26 *  The license and distribution terms for this file may be
27 *  found in the file LICENSE in this distribution or at
28 *  http://www.rtems.com/license/LICENSE.
29 *
30 *  $Id$
31 */
32
33#if HAVE_CONFIG_H
34#include "config.h"
35#endif
36
37#include "malloc_p.h"
38
39#include <stdio.h>
40
41/* only supported on newlib targets */
42#ifdef RTEMS_NEWLIB
43/* not completely implemented so not included in coverage analysis */
44#ifndef RTEMS_COVERAGE
45
46#define SENTINELSIZE    12
47#define SENTINEL       "\xD1\xAC\xB2\xF1" "BITE ME"
48#define CALLCHAINSIZE 5
49
50struct mallocNode {
51  struct mallocNode *back;
52  struct mallocNode *forw;
53  int                callChain[CALLCHAINSIZE];
54  size_t             size;
55  void              *memory;
56};
57
58struct mallocNode mallocNodeHead;
59
60static void rtems_malloc_boundary_initialize(void)
61{
62  mallocNodeHead.back = &mallocNodeHead;
63  mallocNodeHead.forw = &mallocNodeHead;
64}
65
66static uint32_t rtems_malloc_boundary_overhead(void)
67{
68  return sizeof(struct mallocNode) + SENTINELSIZE;
69}
70
71static void rtems_malloc_boundary_at_malloc(
72  void     *pointer,
73  size_t    size
74)
75{
76  void *return_this;
77  struct mallocNode *mp = (struct mallocNode *)pointer;
78  int *fp, *nfp;
79  int i;
80
81  _RTEMS_Lock_allocator();
82    mp->memory = mp + 1;
83    return_this = mp->memory;
84    mp->size = size - (sizeof(struct mallocNode) + SENTINELSIZE);
85    fp = (int *)&size - 2;
86    for (i = 0 ; i < CALLCHAINSIZE ; i++) {
87      mp->callChain[i] = fp[1];
88      nfp = (int *)(fp[0]);
89      if((nfp <= fp) || (nfp > (int *)(INT32_C(0x1000000) /* 1 << 24 */)))
90       break;
91      fp = nfp;
92    }
93    while (i < CALLCHAINSIZE)
94      mp->callChain[i++] = 0;
95    memcpy((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE);
96    mp->forw = mallocNodeHead.forw;
97    mp->back = &mallocNodeHead;
98    mallocNodeHead.forw->back = mp;
99    mallocNodeHead.forw = mp;
100  _RTEMS_Unlock_allocator();
101}
102
103static void reportMallocError(const char *msg, struct mallocNode *mp);
104
105static void rtems_malloc_boundary_at_free(
106  void     *pointer
107)
108{
109  struct mallocNode *mp = (struct mallocNode *)pointer - 1;
110  struct mallocNode *mp1;
111
112  _RTEMS_Lock_allocator();
113    if ((mp->memory != (mp + 1)) ||
114        (memcmp((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE) != 0))
115      reportMallocError("Freeing with inconsistent pointer/sentinel", mp);
116    mp1 = mallocNodeHead.forw;
117    while (mp1 != &mallocNodeHead) {
118      if (mp1 == mp)
119        break;
120      mp1 = mp1->forw;
121    }
122    if (mp1 != mp)
123      reportMallocError("Freeing, but not on allocated list", mp);
124    mp->forw->back = mp->back;
125    mp->back->forw = mp->forw;
126    mp->back = mp->forw = NULL;
127    pointer = mp;
128  _RTEMS_Unlock_allocator();
129}
130
131static void rtems_malloc_boundary_at_realloc(
132  void     *pointer __attribute__((unused)),
133  size_t    size __attribute__((unused))
134)
135{
136  /* this needs to be implemented */
137}
138
139/*
140 *  Malloc boundary support plugin
141 */
142rtems_malloc_boundary_functions_t rtems_malloc_boundary_functions_table = {
143  rtems_malloc_boundary_initialize,
144  rtems_malloc_boundary_overhead,
145  rtems_malloc_boundary_at_malloc,
146  rtems_malloc_boundary_at_free,
147  rtems_malloc_boundary_at_realloc,
148};
149
150rtems_malloc_boundary_functions_t *rtems_malloc_boundary_helpers = NULL;
151/*   &rtems_malloc_boundary_functions_table; */
152
153static void reportMallocError(const char *msg, struct mallocNode *mp)
154{
155    unsigned char *sp = (unsigned char *)mp->memory + mp->size;
156    int i, ind = 0;
157    static char cbuf[500];
158    ind += sprintf(cbuf+ind, "Malloc Error: %s\n", msg);
159    if ((mp->forw->back != mp) || (mp->back->forw != mp))
160        ind += sprintf(cbuf+ind,
161            "mp:%p  mp->forw:%p  mp->forw->back:%p  "
162            "mp->back:%p  mp->back->forw:%p\n",
163            mp, mp->forw, mp->forw->back, mp->back, mp->back->forw);
164    if (mp->memory != (mp + 1))
165        ind += sprintf(cbuf+ind, "mp+1:%p  ", mp + 1);
166    ind += sprintf(cbuf+ind, "mp->memory:%p  mp->size:%zi\n", mp->memory, mp->size);
167    if (memcmp((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE) != 0) {
168        ind += sprintf(cbuf+ind, "mp->sentinel: ");
169        for (i = 0 ; i < SENTINELSIZE ; i++)
170            ind += sprintf(cbuf+ind, " 0x%x", sp[i]);
171        ind += sprintf(cbuf+ind, "\n");
172    }
173    ind += sprintf(cbuf+ind, "Call chain:");
174    for (i = 0 ; i < CALLCHAINSIZE ; i++) {
175        if (mp->callChain[i] == 0)
176            break;
177        ind += sprintf(cbuf+ind, " 0x%x", mp->callChain[i]);
178    }
179    printk("\n\n%s\n\n", cbuf);
180}
181
182#if UNUSED
183static void checkMallocArena(void)
184{
185  struct mallocNode *mp;
186
187  _RTEMS_Lock_allocator();
188    for ( mp = mallocNodeHead.forw; mp != &mallocNodeHead ; mp = mp->forw ) {
189      if ((mp->forw->back != mp) || (mp->back->forw != mp))
190        reportMallocError("Pointers mangled", mp);
191      if ((mp->memory != (mp + 1)) ||
192          (memcmp((char *)mp->memory + mp->size, SENTINEL, SENTINELSIZE) != 0))
193        reportMallocError("Inconsistent pointer/sentinel", mp);
194    }
195  _RTEMS_Unlock_allocator();
196}
197#endif
198
199#endif
200#endif
Note: See TracBrowser for help on using the repository browser.