OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [newlib-1.17.0/] [newlib/] [libc/] [sys/] [linux/] [mcheck.c] - Blame information for rev 816

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 148 jeremybenn
/* Standard debugging hooks for `malloc'.
2
   Copyright (C) 1990-1997, 1999, 2000, 2001 Free Software Foundation, Inc.
3
   This file is part of the GNU C Library.
4
   Written May 1989 by Mike Haertel.
5
 
6
   The GNU C Library is free software; you can redistribute it and/or
7
   modify it under the terms of the GNU Lesser General Public
8
   License as published by the Free Software Foundation; either
9
   version 2.1 of the License, or (at your option) any later version.
10
 
11
   The GNU C Library is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
   Lesser General Public License for more details.
15
 
16
   You should have received a copy of the GNU Lesser General Public
17
   License along with the GNU C Library; if not, write to the Free
18
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19
   02111-1307 USA.  */
20
 
21
/* Modified for newlib, July 9, 2002 by Jeff Johnston */
22
 
23
#ifndef _MALLOC_INTERNAL
24
# define _MALLOC_INTERNAL
25
# include <features.h>
26
# define _LIBC 1
27
# include <malloc.h>
28
# include <mcheck.h>
29
# include <stdint.h>
30
# include <stdio.h>
31
# include <stdlib.h>
32
# include <libintl.h>
33
# include <sys/cdefs.h>
34
#endif
35
 
36
/* Old hook values.  */
37
static void (*old_free_hook) __P ((__ptr_t ptr, __const __ptr_t));
38
static __ptr_t (*old_malloc_hook) __P ((__malloc_size_t size, const __ptr_t));
39
static __ptr_t (*old_realloc_hook) __P ((__ptr_t ptr, __malloc_size_t size,
40
                                         __const __ptr_t));
41
 
42
/* Function to call when something awful happens.  */
43
static void (*abortfunc) __P ((enum mcheck_status));
44
 
45
/* Arbitrary magical numbers.  */
46
#define MAGICWORD       0xfedabeeb
47
#define MAGICFREE       0xd8675309
48
#define MAGICBYTE       ((char) 0xd7)
49
#define MALLOCFLOOD     ((char) 0x93)
50
#define FREEFLOOD       ((char) 0x95)
51
 
52
struct hdr
53
  {
54
    __malloc_size_t size;       /* Exact size requested by user.  */
55
    unsigned long int magic;    /* Magic number to check header integrity.  */
56
    struct hdr *prev;
57
    struct hdr *next;
58
  };
59
 
60
/* This is the beginning of the list of all memory blocks allocated.
61
   It is only constructed if the pedantic testing is requested.  */
62
static struct hdr *root;
63
 
64
static int mcheck_used;
65
 
66
/* Nonzero if pedentic checking of all blocks is requested.  */
67
static int pedantic;
68
 
69
#if defined _LIBC || defined STDC_HEADERS || defined USG
70
# include <string.h>
71
# define flood memset
72
#else
73
static void flood __P ((__ptr_t, int, __malloc_size_t));
74
static void
75
flood (ptr, val, size)
76
     __ptr_t ptr;
77
     int val;
78
     __malloc_size_t size;
79
{
80
  char *cp = ptr;
81
  while (size--)
82
    *cp++ = val;
83
}
84
#endif
85
 
86
static enum mcheck_status checkhdr __P ((const struct hdr *));
87
static enum mcheck_status
88
checkhdr (hdr)
89
     const struct hdr *hdr;
90
{
91
  enum mcheck_status status;
92
 
93
  if (!mcheck_used)
94
    /* Maybe the mcheck used is disabled?  This happens when we find
95
       an error and report it.  */
96
    return MCHECK_OK;
97
 
98
  switch (hdr->magic ^ ((uintptr_t) hdr->prev + (uintptr_t) hdr->next))
99
    {
100
    default:
101
      status = MCHECK_HEAD;
102
      break;
103
    case MAGICFREE:
104
      status = MCHECK_FREE;
105
      break;
106
    case MAGICWORD:
107
      if (((char *) &hdr[1])[hdr->size] != MAGICBYTE)
108
        status = MCHECK_TAIL;
109
      else
110
        status = MCHECK_OK;
111
      break;
112
    }
113
  if (status != MCHECK_OK)
114
    {
115
      mcheck_used = 0;
116
      (*abortfunc) (status);
117
      mcheck_used = 1;
118
    }
119
  return status;
120
}
121
 
122
void
123
mcheck_check_all ()
124
{
125
  /* Walk through all the active blocks and test whether they were tempered
126
     with.  */
127
  struct hdr *runp = root;
128
 
129
  /* Temporarily turn off the checks.  */
130
  pedantic = 0;
131
 
132
  while (runp != NULL)
133
    {
134
      (void) checkhdr (runp);
135
 
136
      runp = runp->next;
137
    }
138
 
139
  /* Turn checks on again.  */
140
  pedantic = 1;
141
}
142
 
143
static void unlink_blk __P ((struct hdr *ptr));
144
static void
145
unlink_blk (ptr)
146
     struct hdr *ptr;
147
{
148
  if (ptr->next != NULL)
149
    {
150
      ptr->next->prev = ptr->prev;
151
      ptr->next->magic = MAGICWORD ^ ((uintptr_t) ptr->next->prev
152
                                      + (uintptr_t) ptr->next->next);
153
    }
154
  if (ptr->prev != NULL)
155
    {
156
      ptr->prev->next = ptr->next;
157
      ptr->prev->magic = MAGICWORD ^ ((uintptr_t) ptr->prev->prev
158
                                      + (uintptr_t) ptr->prev->next);
159
    }
160
  else
161
    root = ptr->next;
162
}
163
 
164
static void link_blk  __P ((struct hdr *ptr));
165
static void
166
link_blk (hdr)
167
     struct hdr *hdr;
168
{
169
  hdr->prev = NULL;
170
  hdr->next = root;
171
  root = hdr;
172
  hdr->magic = MAGICWORD ^ (uintptr_t) hdr->next;
173
 
174
  /* And the next block.  */
175
  if (hdr->next != NULL)
176
    {
177
      hdr->next->prev = hdr;
178
      hdr->next->magic = MAGICWORD ^ ((uintptr_t) hdr
179
                                      + (uintptr_t) hdr->next->next);
180
    }
181
}
182
 
183
static void freehook __P ((__ptr_t, const __ptr_t));
184
static void
185
freehook (ptr, caller)
186
     __ptr_t ptr;
187
     const __ptr_t caller;
188
{
189
  if (pedantic)
190
    mcheck_check_all ();
191
  if (ptr)
192
    {
193
      struct hdr *hdr = ((struct hdr *) ptr) - 1;
194
      checkhdr (hdr);
195
      hdr->magic = MAGICFREE;
196
      unlink_blk (hdr);
197
      hdr->prev = hdr->next = NULL;
198
      flood (ptr, FREEFLOOD, hdr->size);
199
      ptr = (__ptr_t) hdr;
200
    }
201
  __free_hook = old_free_hook;
202
  if (old_free_hook != NULL)
203
    (*old_free_hook) (ptr, caller);
204
  else
205
    free (ptr);
206
  __free_hook = freehook;
207
}
208
 
209
static __ptr_t mallochook __P ((__malloc_size_t, const __ptr_t));
210
static __ptr_t
211
mallochook (size, caller)
212
     __malloc_size_t size;
213
     const __ptr_t caller;
214
{
215
  struct hdr *hdr;
216
 
217
  if (pedantic)
218
    mcheck_check_all ();
219
 
220
  __malloc_hook = old_malloc_hook;
221
  if (old_malloc_hook != NULL)
222
    hdr = (struct hdr *) (*old_malloc_hook) (sizeof (struct hdr) + size + 1,
223
                                             caller);
224
  else
225
    hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1);
226
  __malloc_hook = mallochook;
227
  if (hdr == NULL)
228
    return NULL;
229
 
230
  hdr->size = size;
231
  link_blk (hdr);
232
  ((char *) &hdr[1])[size] = MAGICBYTE;
233
  flood ((__ptr_t) (hdr + 1), MALLOCFLOOD, size);
234
  return (__ptr_t) (hdr + 1);
235
}
236
 
237
static __ptr_t reallochook __P ((__ptr_t, __malloc_size_t, const __ptr_t));
238
static __ptr_t
239
reallochook (ptr, size, caller)
240
     __ptr_t ptr;
241
     __malloc_size_t size;
242
     const __ptr_t caller;
243
{
244
  struct hdr *hdr;
245
  __malloc_size_t osize;
246
 
247
  if (pedantic)
248
    mcheck_check_all ();
249
 
250
  if (ptr)
251
    {
252
      hdr = ((struct hdr *) ptr) - 1;
253
      osize = hdr->size;
254
 
255
      checkhdr (hdr);
256
      unlink_blk (hdr);
257
      if (size < osize)
258
        flood ((char *) ptr + size, FREEFLOOD, osize - size);
259
    }
260
  else
261
    {
262
      osize = 0;
263
      hdr = NULL;
264
    }
265
  __free_hook = old_free_hook;
266
  __malloc_hook = old_malloc_hook;
267
  __realloc_hook = old_realloc_hook;
268
  if (old_realloc_hook != NULL)
269
    hdr = (struct hdr *) (*old_realloc_hook) ((__ptr_t) hdr,
270
                                              sizeof (struct hdr) + size + 1,
271
                                              caller);
272
  else
273
    hdr = (struct hdr *) realloc ((__ptr_t) hdr,
274
                                  sizeof (struct hdr) + size + 1);
275
  __free_hook = freehook;
276
  __malloc_hook = mallochook;
277
  __realloc_hook = reallochook;
278
  if (hdr == NULL)
279
    return NULL;
280
 
281
  hdr->size = size;
282
  link_blk (hdr);
283
  ((char *) &hdr[1])[size] = MAGICBYTE;
284
  if (size > osize)
285
    flood ((char *) (hdr + 1) + osize, MALLOCFLOOD, size - osize);
286
  return (__ptr_t) (hdr + 1);
287
}
288
 
289
static void mabort __P ((enum mcheck_status status))
290
     __attribute__ ((noreturn));
291
static void
292
mabort (status)
293
     enum mcheck_status status;
294
{
295
  const char *msg;
296
  switch (status)
297
    {
298
    case MCHECK_OK:
299
      msg = _("memory is consistent, library is buggy\n");
300
      break;
301
    case MCHECK_HEAD:
302
      msg = _("memory clobbered before allocated block\n");
303
      break;
304
    case MCHECK_TAIL:
305
      msg = _("memory clobbered past end of allocated block\n");
306
      break;
307
    case MCHECK_FREE:
308
      msg = _("block freed twice\n");
309
      break;
310
    default:
311
      msg = _("bogus mcheck_status, library is buggy\n");
312
      break;
313
    }
314
  fprintf (stderr, "mcheck: %s", msg);
315
  fflush (stderr);
316
  abort ();
317
}
318
 
319
int
320
mcheck (func)
321
     void (*func) __P ((enum mcheck_status));
322
{
323
  abortfunc = (func != NULL) ? func : &mabort;
324
 
325
  /* These hooks may not be safely inserted if malloc is already in use.  */
326
  if (__malloc_initialized <= 0 && !mcheck_used)
327
    {
328
      /* We call malloc() once here to ensure it is initialized.  */
329
      void *p = malloc (0);
330
      free (p);
331
 
332
      old_free_hook = __free_hook;
333
      __free_hook = freehook;
334
      old_malloc_hook = __malloc_hook;
335
      __malloc_hook = mallochook;
336
      old_realloc_hook = __realloc_hook;
337
      __realloc_hook = reallochook;
338
      mcheck_used = 1;
339
    }
340
 
341
  return mcheck_used ? 0 : -1;
342
}
343
 
344
int
345
mcheck_pedantic (func)
346
      void (*func) __P ((enum mcheck_status));
347
{
348
  int res = mcheck (func);
349
  if (res == 0)
350
    pedantic = 1;
351
  return res;
352
}
353
 
354
enum mcheck_status
355
mprobe (__ptr_t ptr)
356
{
357
  return mcheck_used ? checkhdr (((struct hdr *) ptr) - 1) : MCHECK_DISABLED;
358
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.