1 /*
2 * mpatrol
3 * A library for controlling and tracing dynamic memory allocations.
4 * Copyright (C) 1997-2002 Graeme S. Roy <graeme.roy@analog.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This 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 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 * MA 02111-1307, USA.
20 */
21
22
23 /*
24 * Release version of library interface. This module defines the visible
25 * interface for the mpatrol library in release mode. These functions
26 * should not normally be required if all of the source files that use
27 * mpatrol.h were recompiled with NDEBUG, but they are defined here just
28 * in case.
29 */
30
31
32 #include "inter.h"
33 #include "mpalloc.h"
34 #include "version.h"
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <stdarg.h>
39 #if TARGET == TARGET_UNIX
40 #include <unistd.h>
41 #if SYSTEM == SYSTEM_LINUX
42 #include <malloc.h>
43 #endif /* SYSTEM */
44 #elif TARGET == TARGET_WINDOWS
45 #include <windows.h>
46 #include <winbase.h>
47 #elif TARGET == TARGET_NETWARE
48 #include <nwthread.h>
49 #include <nks/memory.h>
50 #endif /* TARGET */
51
52
53 #if MP_IDENT_SUPPORT
54 #ident "$Id: mpalloc.c,v 1.44 2002/01/08 20:13:59 graeme Exp $"
55 #else /* MP_IDENT_SUPPORT */
56 static MP_CONST MP_VOLATILE char *mpalloc_id = "$Id: mpalloc.c,v 1.44 2002/01/08 20:13:59 graeme Exp $";
57 #endif /* MP_IDENT_SUPPORT */
58
59
60 /* An allocaheader belongs to a stack of memory allocations that were made
61 * by the alloca() and related functions. Some memory allocations at the
62 * top of the stack may be automatically freed when the next call to allocate
63 * memory is made and the stack has been unwound.
64 */
65
66 typedef union allocaheader
67 {
68 #if MP_LONGLONG_SUPPORT
69 long long integer; /* type with most restrictive alignment */
70 #else /* MP_LONGLONG_SUPPORT */
71 long integer; /* type with most restrictive alignment */
72 #endif /* MP_LONGLONG_SUPPORT */
73 long double real; /* type with most restrictive alignment */
74 struct
75 {
76 union allocaheader *next; /* pointer to next allocaheader */
77 void *frame; /* pointer to stack frame */
78 }
79 data;
80 }
81 allocaheader;
82
83
84 #ifdef __cplusplus
85 extern "C"
86 {
87 #endif /* __cplusplus */
88
89
90 /* The stack of allocaheaders that is used to keep track of the details of
91 * (and when to free) memory allocated with alloca() and related functions.
92 */
93
94 static allocaheader *allocastack;
95
96
97 /* Terminate the program after an mpatrol function has been called with an
98 * illegal function type.
99 */
100
101 static
102 void
illegalfunction(char * f,char * s,char * t,unsigned long u)103 illegalfunction(char *f, char *s, char *t, unsigned long u)
104 {
105 fputs("fatal error", stderr);
106 if (s != NULL)
107 fprintf(stderr, " in %s", s);
108 if ((t != NULL) && (u != 0))
109 fprintf(stderr, " in %s line %lu", t, u);
110 fputc('\n', stderr);
111 fprintf(stderr, "mpatrol function %s called with illegal function type\n",
112 f);
113 fflush(NULL);
114 exit(EXIT_FAILURE);
115 }
116
117
118 /* Round an unsigned integer up to the nearest power of two.
119 */
120
121 static
122 unsigned long
poweroftwo(unsigned long n)123 poweroftwo(unsigned long n)
124 {
125 unsigned char l;
126
127 if ((n == 0) || ((n & (n - 1)) == 0))
128 return n;
129 for (l = 0; n > 0; l++, n >>= 1);
130 return (unsigned long) (2 << (l - 1));
131 }
132
133
134 /* Return the system page size.
135 */
136
137 static
138 size_t
pagesize(void)139 pagesize(void)
140 {
141 static size_t s;
142 #if TARGET == TARGET_WINDOWS
143 SYSTEM_INFO i;
144 #endif /* TARGET */
145
146 if (s == 0)
147 {
148 #if TARGET == TARGET_UNIX
149 /* This call could also be getpagesize() but it is more POSIX-conforming
150 * to call sysconf(). Unfortunately, SunOS and the BSD systems only
151 * have getpagesize().
152 */
153 #if SYSTEM == SYSTEM_FREEBSD || SYSTEM == SYSTEM_NETBSD || \
154 SYSTEM == SYSTEM_OPENBSD || SYSTEM == SYSTEM_SUNOS
155 s = getpagesize();
156 #else /* SYSTEM */
157 s = sysconf(_SC_PAGESIZE);
158 #endif /* SYSTEM */
159 #elif TARGET == TARGET_AMIGA
160 /* The Amiga has no virtual memory system (at least not supplied with
161 * AmigaOS), so we return a fixed value here because it doesn't really
162 * matter what the page size is.
163 */
164 s = 4096;
165 #elif TARGET == TARGET_WINDOWS
166 GetSystemInfo(&i);
167 s = i.dwPageSize;
168 #elif TARGET == TARGET_NETWARE
169 s = NXGetPageSize();
170 #else /* TARGET */
171 /* We just assume that any other operating systems have no virtual
172 * memory support and so anything we return here is irrelevant.
173 */
174 return 1024;
175 #endif /* TARGET */
176 }
177 return s;
178 }
179
180
181 /* Determine the stack direction on this system.
182 */
183
184 static
185 int
stackdirection(void * p)186 stackdirection(void *p)
187 {
188 static int d;
189 unsigned long n;
190
191 if (d == 0)
192 {
193 n = (unsigned long) &p;
194 if (p == NULL)
195 return stackdirection(&n);
196 else if (&n < (unsigned long *) p)
197 d = -1;
198 else
199 d = 1;
200 }
201 return d;
202 }
203
204
205 /* Check the alloca allocation stack for any allocations that should be freed.
206 */
207
208 static
209 void
checkalloca(void * p)210 checkalloca(void *p)
211 {
212 allocaheader *m, *n;
213 int d;
214
215 d = stackdirection(NULL);
216 for (n = allocastack; n != NULL; n = m)
217 {
218 m = n->data.next;
219 if (((d > 0) && ((char *) n->data.frame > (char *) p + 32)) ||
220 ((d < 0) && ((char *) n->data.frame + 32 < (char *) p)))
221 {
222 free(n);
223 allocastack = m;
224 }
225 else
226 break;
227 }
228 }
229
230
231 /* The last error encountered by the mpatrol library.
232 */
233
234 MP_API errortype __mp_errno;
235
236
237 /* Initialise the mpatrol library.
238 */
239
240 MP_API
241 void
__mp_init(void)242 __mp_init(void)
243 {
244 }
245
246
247 /* Reinitialise the mpatrol library.
248 */
249
250 MP_API
251 void
__mp_reinit(void)252 __mp_reinit(void)
253 {
254 }
255
256
257 /* Finalise the mpatrol library.
258 */
259
260 MP_API
261 void
__mp_fini(void)262 __mp_fini(void)
263 {
264 }
265
266
267 /* Provide a function which can be used as a breakpoint target in a debugger.
268 */
269
270 MP_API
271 void
__mp_trap(void)272 __mp_trap(void)
273 {
274 }
275
276
277 /* Register a finalisation function to be called when __mp_fini() is called.
278 */
279
280 MP_API
281 int
__mp_atexit(void (* f)(void))282 __mp_atexit(void (*f)(void))
283 {
284 if (atexit(f) == -1)
285 return 0;
286 return 1;
287 }
288
289
290 /* Set an mpatrol option after the library has been initialised.
291 */
292
293 MP_API
294 unsigned long
__mp_setoption(long o,unsigned long v)295 __mp_setoption(long o, unsigned long v)
296 {
297 return ~0L;
298 }
299
300
301 /* Get an mpatrol option after the library has been initialised.
302 */
303
304 MP_API
305 int
__mp_getoption(long o,unsigned long * v)306 __mp_getoption(long o, unsigned long *v)
307 {
308 return 0;
309 }
310
311
312 /* Return the memory header structure.
313 */
314
315 MP_API
316 infohead *
__mp_memhead(void)317 __mp_memhead(void)
318 {
319 return NULL;
320 }
321
322
323 /* Allocate a new block of memory of a specified size and alignment.
324 */
325
326 MP_API
327 void *
__mp_alloc(size_t l,size_t a,alloctype f,char * s,char * t,unsigned long u,char * g,size_t h,size_t k)328 __mp_alloc(size_t l, size_t a, alloctype f, char *s, char *t, unsigned long u,
329 char *g, size_t h, size_t k)
330 {
331 void *p;
332 size_t n;
333
334 checkalloca(&l);
335 if (l == 0)
336 l = 1;
337 switch (f)
338 {
339 case AT_MALLOC:
340 p = malloc(l);
341 break;
342 case AT_CALLOC:
343 if (p = malloc(l))
344 memset(p, 0, l);
345 break;
346 case AT_MEMALIGN:
347 case AT_VALLOC:
348 case AT_PVALLOC:
349 /* We cannot rely on any system having implementations of memalign(),
350 * valloc() or pvalloc() and so we must either implement them with
351 * malloc() or with memalign() if it exists. For the former
352 * implementation, this is done by allocating extra space and then
353 * rounding up the start address of the new allocation to the specified
354 * alignment. This means that there is likely to be some space wasted
355 * for each allocation and the memory allocated by such functions
356 * cannot be freed with free(). The latter point is also likely to be
357 * true even if we allocated the memory with memalign().
358 */
359 n = pagesize();
360 if (f == AT_PVALLOC)
361 l = ((l - 1) & ~(n - 1)) + n;
362 if ((f == AT_VALLOC) || (f == AT_PVALLOC) || (a > n))
363 a = n;
364 else if (a < sizeof(long))
365 a = sizeof(long);
366 else
367 a = poweroftwo(a);
368 #if MP_MEMALIGN_SUPPORT
369 p = memalign(a, l);
370 #else /* MP_MEMALIGN_SUPPORT */
371 if (p = malloc(l + a - 1))
372 p = (void *) ((((unsigned long) p - 1) & ~(a - 1)) + a);
373 #endif /* MP_MEMALIGN_SUPPORT */
374 break;
375 case AT_ALLOCA:
376 p = __mp_xmalloc(l + sizeof(allocaheader), s, t, u, g, h);
377 ((allocaheader *) p)->data.next = allocastack;
378 ((allocaheader *) p)->data.frame = (void *) &l;
379 allocastack = (allocaheader *) p;
380 p = (char *) p + sizeof(allocaheader);
381 break;
382 case AT_XMALLOC:
383 p = __mp_xmalloc(l, s, t, u, g, h);
384 break;
385 case AT_XCALLOC:
386 p = __mp_xcalloc(l, s, t, u, g, h);
387 break;
388 case AT_NEW:
389 case AT_NEWVEC:
390 /* This implementation should really call the new handler if it
391 * has been installed, but for now just abort if no memory can be
392 * allocated.
393 */
394 p = __mp_xmalloc(l, s, t, u, g, h);
395 break;
396 default:
397 illegalfunction("__mp_alloc", s, t, u);
398 break;
399 }
400 return p;
401 }
402
403
404 /* Allocate a new block of memory to duplicate a string.
405 */
406
407 MP_API
408 char *
__mp_strdup(char * p,size_t l,alloctype f,char * s,char * t,unsigned long u,size_t k)409 __mp_strdup(char *p, size_t l, alloctype f, char *s, char *t, unsigned long u,
410 size_t k)
411 {
412 char *r;
413 size_t i;
414
415 checkalloca(&p);
416 if (f == AT_XSTRDUP)
417 return __mp_xstrdup(p, s, t, u);
418 i = strlen(p);
419 if ((f == AT_STRNDUP) || (f == AT_STRNSAVE) || (f == AT_STRNDUPA))
420 {
421 if (i > l)
422 i = l;
423 }
424 else if ((f != AT_STRDUP) && (f != AT_STRSAVE) && (f != AT_STRDUPA))
425 illegalfunction("__mp_strdup", s, t, u);
426 if ((f == AT_STRDUPA) || (f == AT_STRNDUPA))
427 {
428 r = (char *) __mp_xmalloc(i + sizeof(allocaheader) + 1, s, t, u, "char",
429 sizeof(char));
430 ((allocaheader *) r)->data.next = allocastack;
431 ((allocaheader *) r)->data.frame = (void *) &p;
432 allocastack = (allocaheader *) r;
433 r += sizeof(allocaheader);
434 }
435 else
436 r = (char *) malloc(i + 1);
437 if (r != NULL)
438 {
439 memcpy(r, p, i);
440 r[i] = '\0';
441 }
442 return r;
443 }
444
445
446 /* Resize an existing block of memory to a new size and alignment.
447 */
448
449 MP_API
450 void *
__mp_realloc(void * p,size_t l,size_t a,alloctype f,char * s,char * t,unsigned long u,char * g,size_t h,size_t k)451 __mp_realloc(void *p, size_t l, size_t a, alloctype f, char *s, char *t,
452 unsigned long u, char *g, size_t h, size_t k)
453 {
454 void *q;
455
456 checkalloca(&p);
457 if (f == AT_XREALLOC)
458 return __mp_xrealloc(p, l, s, t, u, g, h);
459 else if ((f != AT_REALLOC) && (f != AT_REALLOCF) && (f != AT_RECALLOC) &&
460 (f != AT_EXPAND))
461 illegalfunction("__mp_realloc", s, t, u);
462 /* There is a major limitation here in that we don't know the size of
463 * the existing memory allocation. This means that we can't implement
464 * recalloc() or expand() properly, and in the latter case means that
465 * we must always return NULL. If you have existing implementations
466 * of these functions on your system then you could make calls to them
467 * here.
468 */
469 if (p == NULL)
470 {
471 if (l == 0)
472 l = 1;
473 if ((p = malloc(l)) && (f == AT_RECALLOC))
474 memset(p, 0, l);
475 }
476 else if (l == 0)
477 {
478 free(p);
479 p = NULL;
480 }
481 else if (f == AT_REALLOCF)
482 {
483 if ((q = realloc(p, l)) == NULL)
484 free(p);
485 p = q;
486 }
487 else if (f != AT_EXPAND)
488 p = realloc(p, l);
489 else
490 p = NULL;
491 return p;
492 }
493
494
495 /* Free an existing block of memory.
496 */
497
498 MP_API
499 void
__mp_free(void * p,alloctype f,char * s,char * t,unsigned long u,size_t k)500 __mp_free(void *p, alloctype f, char *s, char *t, unsigned long u, size_t k)
501 {
502 checkalloca(&p);
503 if ((f != AT_FREE) && (f != AT_CFREE) && (f != AT_DEALLOCA) &&
504 (f != AT_XFREE) && (f != AT_DELETE) && (f != AT_DELETEVEC))
505 illegalfunction("__mp_free", s, t, u);
506 if (f != AT_DEALLOCA)
507 free(p);
508 }
509
510
511 /* Set a block of memory to contain a specific byte.
512 */
513
514 MP_API
515 void *
__mp_setmem(void * p,size_t l,unsigned char c,alloctype f,char * s,char * t,unsigned long u,size_t k)516 __mp_setmem(void *p, size_t l, unsigned char c, alloctype f, char *s, char *t,
517 unsigned long u, size_t k)
518 {
519 if ((f != AT_MEMSET) && (f != AT_BZERO))
520 illegalfunction("__mp_setmem", s, t, u);
521 return memset(p, (int) c, l);
522 }
523
524
525 /* Copy a block of memory from one address to another.
526 */
527
528 MP_API
529 void *
__mp_copymem(void * p,void * q,size_t l,unsigned char c,alloctype f,char * s,char * t,unsigned long u,size_t k)530 __mp_copymem(void *p, void *q, size_t l, unsigned char c, alloctype f, char *s,
531 char *t, unsigned long u, size_t k)
532 {
533 void *r;
534
535 switch (f)
536 {
537 case AT_MEMCCPY:
538 if (r = memchr(p, (int) c, l))
539 l = (size_t) ((char *) r - (char *) p) + 1;
540 memcpy(q, p, l);
541 if (r != NULL)
542 q = (char *) q + l;
543 else
544 q = NULL;
545 break;
546 case AT_MEMCPY:
547 memcpy(q, p, l);
548 break;
549 case AT_MEMMOVE:
550 case AT_BCOPY:
551 memmove(q, p, l);
552 break;
553 default:
554 illegalfunction("__mp_copymem", s, t, u);
555 break;
556 }
557 return q;
558 }
559
560
561 /* Attempt to locate the position of one block of memory in another block.
562 */
563
564 MP_API
565 void *
__mp_locatemem(void * p,size_t l,void * q,size_t m,alloctype f,char * s,char * t,unsigned long u,size_t k)566 __mp_locatemem(void *p, size_t l, void *q, size_t m, alloctype f, char *s,
567 char *t, unsigned long u, size_t k)
568 {
569 if (f == AT_MEMCHR)
570 return memchr(p, (int) (m & 0xFF), l);
571 else if (f == AT_MEMMEM)
572 {
573 if (m > 0)
574 while (l >= m)
575 {
576 if ((*((char *) p) == *((char *) q)) && ((m == 1) ||
577 !memcmp((char *) p + 1, (char *) q + 1, m - 1)))
578 return p;
579 p = (char *) p + 1;
580 l--;
581 }
582 return NULL;
583 }
584 illegalfunction("__mp_locatemem", s, t, u);
585 return NULL;
586 }
587
588
589 /* Compare two blocks of memory.
590 */
591
592 MP_API
593 int
__mp_comparemem(void * p,void * q,size_t l,alloctype f,char * s,char * t,unsigned long u,size_t k)594 __mp_comparemem(void *p, void *q, size_t l, alloctype f, char *s, char *t,
595 unsigned long u, size_t k)
596 {
597 if ((f != AT_MEMCMP) && (f != AT_BCMP))
598 illegalfunction("__mp_comparemem", s, t, u);
599 return memcmp(p, q, l);
600 }
601
602
603 /* Return the full version number of the mpatrol library.
604 */
605
606 MP_API
607 unsigned long
__mp_libversion(void)608 __mp_libversion(void)
609 {
610 return MP_VERNUM;
611 }
612
613
614 /* Return an error message corresponding to a given error type.
615 */
616
617 MP_API
618 char *
__mp_strerror(errortype e)619 __mp_strerror(errortype e)
620 {
621 return NULL;
622 }
623
624
625 /* Return the name of the function corresponding to a given allocation type.
626 */
627
628 MP_API
629 char *
__mp_function(alloctype f)630 __mp_function(alloctype f)
631 {
632 return NULL;
633 }
634
635
636 /* Set the user data for a given memory allocation.
637 */
638
639 MP_API
640 int
__mp_setuser(void * p,void * d)641 __mp_setuser(void *p, void *d)
642 {
643 return 0;
644 }
645
646
647 /* Set the marked flag for a given memory allocation.
648 */
649
650 MP_API
651 int
__mp_setmark(void * p)652 __mp_setmark(void *p)
653 {
654 return 0;
655 }
656
657
658 /* Obtain any details about the memory block that contains a given address.
659 */
660
661 MP_API
662 int
__mp_info(void * p,allocinfo * d)663 __mp_info(void *p, allocinfo *d)
664 {
665 return 0;
666 }
667
668
669 /* Obtain any details about the function symbol that contains a given address.
670 */
671
672 MP_API
673 int
__mp_syminfo(void * p,symbolinfo * d)674 __mp_syminfo(void *p, symbolinfo *d)
675 {
676 return 0;
677 }
678
679
680 /* Obtain the name of the function symbol that contains a given address.
681 */
682
683 MP_API
684 char *
__mp_symbol(void * p)685 __mp_symbol(void *p)
686 {
687 return NULL;
688 }
689
690
691 /* Display any details about the memory block that contains a given address.
692 * This is for calling within a symbolic debugger and will result in output to
693 * the standard error file stream instead of the log file.
694 */
695
696 MP_API
697 int
__mp_printinfo(void * p)698 __mp_printinfo(void *p)
699 {
700 return 0;
701 }
702
703
704 /* Return the current allocation event count for later use when examining
705 * the difference in the list of allocations between now and a future point.
706 */
707
708 MP_API
709 unsigned long
__mp_snapshot(void)710 __mp_snapshot(void)
711 {
712 return 0;
713 }
714
715
716 /* Iterate over all of the allocated and freed memory blocks, calling a
717 * user-supplied function for each one encountered.
718 */
719
720 MP_API
721 size_t
__mp_iterate(int (* f)(void *,void *),void * d,unsigned long s)722 __mp_iterate(int (*f)(void *, void *), void *d, unsigned long s)
723 {
724 return 0;
725 }
726
727
728 /* Iterate over all of the allocated, freed and free memory blocks, calling
729 * a user-supplied function for each one encountered.
730 */
731
732 MP_API
733 size_t
__mp_iterateall(int (* f)(void *,void *),void * d)734 __mp_iterateall(int (*f)(void *, void *), void *d)
735 {
736 return 0;
737 }
738
739
740 /* Add a memory allocation to the leak table.
741 */
742
743 MP_API
744 int
__mp_addallocentry(char * f,unsigned long l,size_t c)745 __mp_addallocentry(char *f, unsigned long l, size_t c)
746 {
747 return 0;
748 }
749
750
751 /* Remove a memory allocation from the leak table.
752 */
753
754 MP_API
755 int
__mp_addfreeentry(char * f,unsigned long l,size_t c)756 __mp_addfreeentry(char *f, unsigned long l, size_t c)
757 {
758 return 0;
759 }
760
761
762 /* Clear the leak table.
763 */
764
765 MP_API
766 void
__mp_clearleaktable(void)767 __mp_clearleaktable(void)
768 {
769 }
770
771
772 /* Start recording memory allocation events in the leak table.
773 */
774
775 MP_API
776 int
__mp_startleaktable(void)777 __mp_startleaktable(void)
778 {
779 return 0;
780 }
781
782
783 /* Stop recording memory allocation events in the leak table.
784 */
785
786 MP_API
787 int
__mp_stopleaktable(void)788 __mp_stopleaktable(void)
789 {
790 return 0;
791 }
792
793
794 /* Display the leak table.
795 */
796
797 MP_API
798 void
__mp_leaktable(size_t l,int o,unsigned char f)799 __mp_leaktable(size_t l, int o, unsigned char f)
800 {
801 }
802
803
804 /* Display a complete memory map of the heap and (optionally) a summary of
805 * all mpatrol library settings and statistics.
806 */
807
808 MP_API
809 void
__mp_memorymap(int s)810 __mp_memorymap(int s)
811 {
812 }
813
814
815 /* Display a summary of all mpatrol library settings and statistics.
816 */
817
818 MP_API
819 void
__mp_summary(void)820 __mp_summary(void)
821 {
822 }
823
824
825 /* Return statistics about the current state of the heap.
826 */
827
828 MP_API
829 int
__mp_stats(heapinfo * d)830 __mp_stats(heapinfo *d)
831 {
832 return 0;
833 }
834
835
836 /* Check the validity of all memory blocks that have been filled with
837 * a predefined pattern.
838 */
839
840 MP_API
841 void
__mp_checkheap(char * s,char * t,unsigned long u)842 __mp_checkheap(char *s, char *t, unsigned long u)
843 {
844 }
845
846
847 /* Check the validity of all memory blocks that have been filled with
848 * a predefined pattern.
849 */
850
851 MP_API
852 void
__mp_check(void)853 __mp_check(void)
854 {
855 }
856
857
858 /* Set the prologue function and return the previous setting.
859 */
860
861 MP_API
862 prologuehandler
__mp_prologue(prologuehandler h)863 __mp_prologue(prologuehandler h)
864 {
865 return NULL;
866 }
867
868
869 /* Set the epilogue function and return the previous setting.
870 */
871
872 MP_API
873 epiloguehandler
__mp_epilogue(epiloguehandler h)874 __mp_epilogue(epiloguehandler h)
875 {
876 return NULL;
877 }
878
879
880 /* Set the low-memory handler and return the previous setting.
881 */
882
883 MP_API
884 nomemoryhandler
__mp_nomemory(nomemoryhandler h)885 __mp_nomemory(nomemoryhandler h)
886 {
887 return NULL;
888 }
889
890
891 /* Push source level information onto the top of the delete stack.
892 */
893
894 MP_API
895 void
__mp_pushdelstack(char * s,char * t,unsigned long u)896 __mp_pushdelstack(char *s, char *t, unsigned long u)
897 {
898 }
899
900
901 /* Pop source level information off the top of the delete stack.
902 */
903
904 MP_API
905 void
__mp_popdelstack(char ** s,char ** t,unsigned long * u)906 __mp_popdelstack(char **s, char **t, unsigned long *u)
907 {
908 *s = *t = NULL;
909 *u = 0;
910 }
911
912
913 /* Write user data to the mpatrol log file.
914 */
915
916 MP_API
917 int
__mp_printf(char * s,...)918 __mp_printf(char *s, ...)
919 {
920 return 0;
921 }
922
923
924 /* Write user data to the mpatrol log file.
925 */
926
927 MP_API
928 int
__mp_vprintf(char * s,va_list v)929 __mp_vprintf(char *s, va_list v)
930 {
931 return 0;
932 }
933
934
935 /* Write user data to the mpatrol log file along with location information.
936 */
937
938 MP_API
939 void
__mp_printfwithloc(char * s,char * t,unsigned long u,char * m,...)940 __mp_printfwithloc(char *s, char *t, unsigned long u, char *m, ...)
941 {
942 }
943
944
945 /* Write user data to the mpatrol log file along with location information.
946 */
947
948 MP_API
949 void
__mp_vprintfwithloc(char * s,char * t,unsigned long u,char * m,va_list v)950 __mp_vprintfwithloc(char *s, char *t, unsigned long u, char *m, va_list v)
951 {
952 }
953
954
955 /* Write a hex dump for a specified memory location to the mpatrol log file.
956 */
957
958 MP_API
959 void
__mp_logmemory(void * p,size_t l)960 __mp_logmemory(void *p, size_t l)
961 {
962 }
963
964
965 /* Write the current call stack to the mpatrol log file.
966 */
967
968 MP_API
969 int
__mp_logstack(size_t k)970 __mp_logstack(size_t k)
971 {
972 return 0;
973 }
974
975
976 /* Write the details about the memory block that contains a given address to
977 * the mpatrol log file.
978 */
979
980 MP_API
981 int
__mp_logaddr(void * p)982 __mp_logaddr(void *p)
983 {
984 return 0;
985 }
986
987
988 /* Invoke a text editor on a given source file at a specific line.
989 */
990
991 MP_API
992 int
__mp_edit(char * f,unsigned long l)993 __mp_edit(char *f, unsigned long l)
994 {
995 return 0;
996 }
997
998
999 /* List a given source file at a specific line.
1000 */
1001
1002 MP_API
1003 int
__mp_list(char * f,unsigned long l)1004 __mp_list(char *f, unsigned long l)
1005 {
1006 return 0;
1007 }
1008
1009
1010 /* Edit or list a given source file at a specific line, but only if the EDIT
1011 * or LIST options are in effect.
1012 */
1013
1014 MP_API
1015 int
__mp_view(char * f,unsigned long l)1016 __mp_view(char *f, unsigned long l)
1017 {
1018 return 0;
1019 }
1020
1021
1022 /* Read in an allocation contents file.
1023 */
1024
1025 MP_API
1026 int
__mp_readcontents(char * s,void * p)1027 __mp_readcontents(char *s, void *p)
1028 {
1029 return 0;
1030 }
1031
1032
1033 /* Write out an allocation contents file.
1034 */
1035
1036 MP_API
1037 int
__mp_writecontents(char * s,void * p)1038 __mp_writecontents(char *s, void *p)
1039 {
1040 return 0;
1041 }
1042
1043
1044 /* Compare an allocation contents file with the contents currently in memory.
1045 */
1046
1047 MP_API
1048 long
__mp_cmpcontents(char * s,void * p)1049 __mp_cmpcontents(char *s, void *p)
1050 {
1051 return -1;
1052 }
1053
1054
1055 /* Remove an allocation contents file.
1056 */
1057
1058 MP_API
1059 int
__mp_remcontents(char * s,void * p)1060 __mp_remcontents(char *s, void *p)
1061 {
1062 return 0;
1063 }
1064
1065
1066 /* The function that is called at every function prologue.
1067 */
1068
1069 MP_API
1070 void
__cyg_profile_func_enter(void * a,void * p)1071 __cyg_profile_func_enter(void *a, void *p)
1072 {
1073 }
1074
1075
1076 /* The function that is called at every function epilogue.
1077 */
1078
1079 MP_API
1080 void
__cyg_profile_func_exit(void * a,void * p)1081 __cyg_profile_func_exit(void *a, void *p)
1082 {
1083 }
1084
1085
1086 /* Set the access rights for a block of memory using the checker interface.
1087 */
1088
1089 MP_API
1090 void
chkr_set_right(void * p,size_t l,unsigned char a)1091 chkr_set_right(void *p, size_t l, unsigned char a)
1092 {
1093 }
1094
1095
1096 /* Copy the access rights for a block of memory to another block using the
1097 * checker interface.
1098 */
1099
1100 MP_API
1101 void
chkr_copy_bitmap(void * p,void * q,size_t l)1102 chkr_copy_bitmap(void *p, void *q, size_t l)
1103 {
1104 }
1105
1106
1107 /* Check a block of memory using the checker interface.
1108 */
1109
1110 MP_API
1111 void
chkr_check_addr(void * p,size_t l,unsigned char a)1112 chkr_check_addr(void *p, size_t l, unsigned char a)
1113 {
1114 }
1115
1116
1117 /* Check a string using the checker interface.
1118 */
1119
1120 MP_API
1121 void
chkr_check_str(char * p,unsigned char a)1122 chkr_check_str(char *p, unsigned char a)
1123 {
1124 }
1125
1126
1127 /* Check a function pointer using the checker interface.
1128 */
1129
1130 MP_API
1131 void
chkr_check_exec(void * p)1132 chkr_check_exec(void *p)
1133 {
1134 }
1135
1136
1137 #ifdef __cplusplus
1138 }
1139 #endif /* __cplusplus */
1140