This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa mudflap] more mudflap work
- From: graydon at redhat dot com
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 16 Aug 2002 20:55:46 -0400
- Subject: [tree-ssa mudflap] more mudflap work
- Reply-to: graydon at redhat dot com
Just committed:
[ libmudflap/ChangeLog ]
2002-08-16 Graydon Hoare <graydon@redhat.com>
* mf-runtime.c (__mf_insert_new_object): Factor out of
__mf_register.
(__mf_remove_old_object): Factor out of __mf_unregister.
(__mf_register): Handle guessed regions, splitting
guesses when new registrations arrive.
(__mf_unregister): Do not unregister guesses.
* mf-runtime.h: Move convenience macros around,
declare new option fields. Add __MF_TYPE_GUESS.
* mf-hooks.c (__wrap_*alloc): Use crumple zones.
(__wrap_free): Call __real_free for deferred frees.
* Makefile.am: Add more tests, fix dependency.
* Makefile.in: Regenerate.
* test/pass[13..17]-frag.c: New testcases.
* test/fail[13..17]-frag.c: New testcases.
2002-08-15 Graydon Hoare <graydon@redhat.com>
* mf-heuristics.c: New file.
* mf-runtime.c (options): Add -trace-calls option.
(__mf_init): Call __mf_init_heuristics.
Index: libmudflap/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/ChangeLog,v
retrieving revision 1.1.2.7
diff -u -r1.1.2.7 ChangeLog
--- libmudflap/ChangeLog 14 Aug 2002 17:35:58 -0000 1.1.2.7
+++ libmudflap/ChangeLog 17 Aug 2002 00:51:35 -0000
@@ -1,3 +1,26 @@
+2002-08-16 Graydon Hoare <graydon@redhat.com>
+
+ * mf-runtime.c (__mf_insert_new_object): Factor out of
+ __mf_register.
+ (__mf_remove_old_object): Factor out of __mf_unregister.
+ (__mf_register): Handle guessed regions, splitting
+ guesses when new registrations arrive.
+ (__mf_unregister): Do not unregister guesses.
+ * mf-runtime.h: Move convenience macros around,
+ declare new option fields. Add __MF_TYPE_GUESS.
+ * mf-hooks.c (__wrap_*alloc): Use crumple zones.
+ (__wrap_free): Call __real_free for deferred frees.
+ * Makefile.am: Add more tests, fix dependency.
+ * Makefile.in: Regenerate.
+ * test/pass[13..17]-frag.c: New testcases.
+ * test/fail[13..17]-frag.c: New testcases.
+
+2002-08-15 Graydon Hoare <graydon@redhat.com>
+
+ * mf-heuristics.c: New file.
+ * mf-runtime.c (options): Add -trace-calls option.
+ (__mf_init): Call __mf_init_heuristics.
+
2002-08-14 Graydon Hoare <graydon@redhat.com>
* Makefile.am (TESTS): Add testsuite support.
Index: libmudflap/Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/Makefile.am,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 Makefile.am
--- libmudflap/Makefile.am 14 Aug 2002 17:35:58 -0000 1.1.2.2
+++ libmudflap/Makefile.am 17 Aug 2002 00:51:35 -0000
@@ -9,11 +9,13 @@
TESTS_ENVIRONMENT = MUDFLAP_OPTIONS='-mode-check -viol-abort'
-TESTS = test/fail1.x test/fail10.x test/fail11.x test/fail12.x \
- test/fail2.x test/fail3.x test/fail4.x test/fail5.x test/fail6.x \
- test/fail7.x test/fail8.x test/fail9.x test/pass1.x test/pass10.x \
- test/pass11.x test/pass12.x test/pass2.x test/pass3.x test/pass4.x \
- test/pass5.x test/pass6.x test/pass7.x test/pass8.x test/pass9.x
+TESTS = test/fail1.x test/fail10.x test/fail11.x test/fail12.x \
+ test/fail13.x test/fail14.x test/fail15.x test/fail16.x test/fail17.x \
+ test/fail2.x test/fail3.x test/fail4.x test/fail5.x test/fail6.x \
+ test/fail7.x test/fail8.x test/fail9.x test/pass1.x test/pass10.x \
+ test/pass11.x test/pass12.x test/pass13.x test/pass14.x test/pass15.x \
+ test/pass16.x test/pass17.x test/pass2.x test/pass3.x test/pass4.x test/pass5.x \
+ test/pass6.x test/pass7.x test/pass8.x test/pass9.x
test/%.c: test/%-frag.c test/mf-driver.c test/buildtest.sh
@@ -45,11 +47,17 @@
LIBMUDFLAP_INCLUDES =
TOPLEVEL_INCLUDES =
+
MFCONFIG_CFLAGS = -I $(srcdir) -include mf-config.h
+mf-runtime.o: mf-runtime.h
+mf-hooks.o: mf-runtime.h
+mf-heuristics.o: mf-runtime.h
+
libmudflap_la_SOURCES = \
mf-runtime.c \
- mf-hooks.c
+ mf-hooks.c \
+ mf-heuristics.c
INCLUDES = \
$(MFCONFIG_CFLAGS)
Index: libmudflap/mf-heuristics.c
===================================================================
RCS file: libmudflap/mf-heuristics.c
diff -N libmudflap/mf-heuristics.c
--- libmudflap/mf-heuristics.c 1 Jan 1970 00:00:00 -0000
+++ libmudflap/mf-heuristics.c 17 Aug 2002 00:51:36 -0000
@@ -0,0 +1,91 @@
+
+/* Mudflap: narrow-pointer bounds-checking by tree rewriting.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Contributed by Frank Ch. Eigler <fche@redhat.com>
+ and Graydon Hoare <graydon@redhat.com>
+
+ This file is part of GCC.
+
+ XXX: libgcc license?
+*/
+
+#include <stdio.h>
+#include "mf-runtime.h"
+
+extern char _end;
+
+static void
+__mf_register_ro_sections ()
+{
+ char buf[512];
+ char flags[4];
+ void *low, *high;
+
+ FILE *fp;
+
+ TRACE_IN;
+
+ fp = fopen ("/proc/self/maps", "r");
+ if (!fp)
+ {
+ if (__mf_opts.trace_mf_calls)
+ {
+ fprintf (stderr, "mf: (heuristics) cannot open /proc/self/maps\n");
+ fprintf (stderr, "mf: (heuristics) registering 00-%p\n", &_end);
+ }
+ __mf_register (0, &_end, __MF_TYPE_GUESS,
+ "(heuristic) static 0-__end region");
+ return;
+ }
+
+ while (fgets (buf, sizeof(buf), fp))
+ {
+ if (sscanf (buf, "%p-%p %4c", &low, &high, flags) == 3)
+ {
+ if (flags[0] == 'r' &&
+ flags[1] == '-')
+ {
+ if (__mf_opts.trace_mf_calls)
+ {
+ fprintf (stderr, "mf: (heuristics) registering static region %p-%p\n",
+ low, high);
+ }
+ __mf_register (low, (high-low), __MF_TYPE_GUESS,
+ "(heuristic) static read-only segment");
+ }
+
+ /* This clause will register the stack as a guess. Splitting regions in the
+ stack is much more delicate than in the heap. We will not do it yet. */
+ /*
+ else if (flags[2] == 'x')
+ {
+ if (__mf_opts.trace_mf_calls)
+ {
+ fprintf (stderr, "mf: (heuristics) registering executable region %p-%p\n",
+ low, high);
+ }
+ __mf_register (low, (high-low), __MF_TYPE_GUESS,
+ "(heuristic) static executable segment");
+ }
+ */
+ else
+ {
+ if (__mf_opts.trace_mf_calls)
+ {
+ fprintf (stderr, "mf: (heuristics) skipping region %s",buf);
+ }
+ }
+ }
+ }
+ fclose (fp);
+ TRACE_OUT;
+}
+
+
+void
+__mf_init_heuristics ()
+{
+ TRACE_IN;
+ __mf_register_ro_sections ();
+ TRACE_OUT;
+}
Index: libmudflap/mf-hooks.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-hooks.c,v
retrieving revision 1.1.2.5
diff -u -r1.1.2.5 mf-hooks.c
--- libmudflap/mf-hooks.c 14 Aug 2002 15:56:43 -0000 1.1.2.5
+++ libmudflap/mf-hooks.c 17 Aug 2002 00:51:36 -0000
@@ -32,13 +32,23 @@
void *
__wrap_malloc (size_t c)
{
- void *buf;
+ char *buf;
extern void * __real_malloc (size_t);
+ size_t size_with_crumple_zomes;
- buf = (void *) __real_malloc (c);
+ if (UNLIKELY (!__mf_active_p))
+ return __real_malloc (c);
+
+ size_with_crumple_zomes = c + (2 * __mf_opts.crumple_zone);
+ buf = (char *) __real_malloc (size_with_crumple_zomes);
+
if (buf)
- __mf_register ((uintptr_t) buf, c, __MF_TYPE_HEAP, "malloc region");
-
+ {
+ buf += __mf_opts.crumple_zone;
+ __mf_register ((uintptr_t) buf, c,
+ __MF_TYPE_HEAP, "malloc region");
+ }
+
return buf;
}
@@ -46,27 +56,48 @@
void *
__wrap_calloc (size_t c, size_t n)
{
- void *buf;
+ char *buf;
extern void * __real_calloc (size_t c, size_t);
+ extern void * __real_malloc (size_t c);
+ extern void *__real_memset (void *s, int c, size_t n);
+ size_t size_with_crumple_zones;
+
+ if (UNLIKELY (!__mf_active_p))
+ return __real_calloc (c,n);
+
+ size_with_crumple_zones = (c * n) + (2 * __mf_opts.crumple_zone);
+ buf = (char *) __real_malloc (size_with_crumple_zones);
- buf = (void *) __real_calloc (c, n);
if (buf)
- __mf_register ((uintptr_t) buf, c*n, __MF_TYPE_HEAP, "calloc region");
-
+ {
+ __real_memset (buf, 0, size_with_crumple_zones);
+ buf += __mf_opts.crumple_zone;
+ __mf_register ((uintptr_t) buf, c*n,
+ __MF_TYPE_HEAP, "calloc region");
+ }
return buf;
}
void *
__wrap_realloc (void *buf, size_t c)
{
- void *buf2;
+ char *buf2;
extern void * __real_realloc (void *, size_t);
+ size_t size_with_crumple_zones;
+
+ if (UNLIKELY (!__mf_active_p))
+ return __real_realloc (buf,c);
- buf2 = (void *) __real_realloc (buf, c);
+ size_with_crumple_zones = c + (2 * __mf_opts.crumple_zone);
+ buf2 = (void *) __real_realloc (buf, size_with_crumple_zones);
if (buf)
__mf_unregister ((uintptr_t) buf, 0);
if (buf2)
- __mf_register ((uintptr_t) buf2, c, __MF_TYPE_HEAP, "realloc region");
+ {
+ buf2 += __mf_opts.crumple_zone;
+ __mf_register ((uintptr_t) buf2, c,
+ __MF_TYPE_HEAP, "realloc region");
+ }
return buf2;
}
@@ -81,6 +112,12 @@
extern void * __real_free (void *);
+ if (UNLIKELY (!__mf_active_p))
+ {
+ __real_free (buf);
+ return;
+ }
+
if (buf == NULL)
return;
@@ -90,13 +127,31 @@
{
if (free_queue [free_ptr] != NULL)
- __wrap_free (free_queue [free_ptr]);
+ {
+ char *base = free_queue [free_ptr];
+ base -= __mf_opts.crumple_zone;
+ if (__mf_opts.trace_mf_calls)
+ {
+ fprintf (stderr, "mf: freeing deferred pointer #%d %p = %p - %d\n",
+ __mf_opts.free_queue_length, base,
+ free_queue [free_ptr], __mf_opts.crumple_zone);
+ }
+ __real_free (base);
+ }
free_queue [free_ptr] = buf;
free_ptr = (free_ptr == (__mf_opts.free_queue_length-1) ? 0 : free_ptr + 1);
}
else
{
- __real_free (buf);
+ /* back pointer up a bit to the beginning of crumple zone */
+ char *base = (char *)buf;
+ base -= __mf_opts.crumple_zone;
+ if (__mf_opts.trace_mf_calls)
+ {
+ fprintf (stderr, "mf: freeing pointer %p = %p - %d\n", base,
+ buf, __mf_opts.crumple_zone);
+ }
+ __real_free (base);
}
}
Index: libmudflap/mf-runtime.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-runtime.c,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 mf-runtime.c
--- libmudflap/mf-runtime.c 14 Aug 2002 15:42:27 -0000 1.1.2.3
+++ libmudflap/mf-runtime.c 17 Aug 2002 00:51:37 -0000
@@ -30,6 +30,10 @@
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif
+#ifndef min
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
#ifdef _MUDFLAP
#error "Do not compile this file with -fmudflap!"
#endif
@@ -37,9 +41,6 @@
/* ------------------------------------------------------------------------ */
/* {{{ Utility macros */
-#define UNLIKELY(e) (__builtin_expect (!!(e), 0))
-#define LIKELY(e) (__builtin_expect (!!(e), 1))
-
#define MINPTR ((uintptr_t) 0)
#define MAXPTR (~ (uintptr_t) 0)
@@ -53,7 +54,8 @@
/* {{{ Configuration macros */
struct __mf_options __mf_opts;
-static int __mf_active_p = 0;
+
+int __mf_active_p = 0;
static void
__mf_set_default_options ()
@@ -67,6 +69,7 @@
__mf_opts.multi_threaded = 0;
__mf_opts.free_queue_length = 0;
__mf_opts.persistent_count = 0;
+ __mf_opts.crumple_zone = 32;
__mf_opts.backtrace = 4;
__mf_opts.mudflap_mode = mode_check;
__mf_opts.violation_mode = viol_nop;
@@ -112,6 +115,9 @@
"violations fork a gdb process attached to current program",
set_option, (int)viol_gdb, (int *)&__mf_opts.violation_mode},
+ {"trace-calls",
+ "trace calls to mudflap runtime library",
+ set_option, 1, &__mf_opts.trace_mf_calls},
{"collect-stats",
"collect statistics on mudflap's operation",
set_option, 1, &__mf_opts.collect_stats},
@@ -137,6 +143,9 @@
{"persistent-count",
"keep a history of N unregistered regions",
read_integer_option, 0, &__mf_opts.persistent_count},
+ {"crumple-zone",
+ "surround allocations with crumple zones of N bytes",
+ read_integer_option, 0, &__mf_opts.crumple_zone},
{"backtrace",
"keep an N-level stack trace of each call context",
read_integer_option, 0, &__mf_opts.backtrace},
@@ -253,14 +262,6 @@
#define CTOR __attribute__ ((constructor))
#define DTOR __attribute__ ((destructor))
-#define TRACE_IN \
- if (__mf_opts.trace_mf_calls) \
- fprintf (stderr, "mf: enter %s\n", __FUNCTION__);
-
-#define TRACE_OUT \
- if (__mf_opts.trace_mf_calls) \
- fprintf (stderr, "mf: exit %s\n", __FUNCTION__);
-
extern void __mf_init () CTOR;
void __mf_init ()
@@ -283,6 +284,8 @@
__mf_active_p = 1;
+ __mf_init_heuristics ();
+
TRACE_OUT;
}
@@ -342,7 +345,7 @@
static unsigned long __mf_lookup_cache_reusecount [LOOKUP_CACHE_SIZE_MAX];
static unsigned long __mf_treerot_left, __mf_treerot_right;
static unsigned long __mf_count_register;
-static unsigned long __mf_total_register_size [__MF_TYPE_STATIC+1];
+static unsigned long __mf_total_register_size [__MF_TYPE_GUESS+1];
static unsigned long __mf_count_unregister;
static unsigned long __mf_total_unregister_size;
static unsigned long __mf_count_violation [__MF_VIOL_UNREGISTER+1];
@@ -381,8 +384,8 @@
/* Live objects: binary tree on __mf_object_t.low */
__mf_object_tree_t *__mf_object_root;
/* Dead objects: circular arrays */
-unsigned __mf_object_dead_head[__MF_TYPE_STATIC+1]; /* next empty spot */
-__mf_object_tree_t *__mf_object_cemetary[__MF_TYPE_STATIC+1][__MF_PERSIST_MAX];
+unsigned __mf_object_dead_head[__MF_TYPE_GUESS+1]; /* next empty spot */
+__mf_object_tree_t *__mf_object_cemetary[__MF_TYPE_GUESS+1][__MF_PERSIST_MAX];
unsigned __mf_recursion_protect;
@@ -469,6 +472,60 @@
/* }}} */
/* {{{ __mf_register */
+static __mf_object_tree_t *
+__mf_insert_new_object (uintptr_t low, uintptr_t high, int type,
+ const char *name, uintptr_t pc)
+{
+ extern void * __real_calloc (size_t c, size_t);
+
+ __mf_object_tree_t *new_obj;
+ new_obj = __real_calloc (1, sizeof(__mf_object_tree_t));
+ new_obj->data.low = low;
+ new_obj->data.high = high;
+ new_obj->data.type = type;
+ new_obj->data.name = name;
+ new_obj->data.alloc_pc = pc;
+ gettimeofday (& new_obj->data.alloc_time, NULL);
+
+ if (__mf_opts.backtrace > 0)
+ {
+ void *array [__mf_opts.backtrace];
+ size_t bt_size;
+ bt_size = backtrace (array, __mf_opts.backtrace);
+ new_obj->data.alloc_backtrace = backtrace_symbols (array, bt_size);
+ new_obj->data.alloc_backtrace_size = bt_size;
+ }
+
+ __mf_link_object (new_obj);
+ return new_obj;
+}
+
+
+static void
+__mf_remove_old_object (__mf_object_tree_t *old_obj)
+{
+ __mf_unlink_object (old_obj);
+
+ /* Remove any low/high pointers for this object from the lookup cache. */
+ if (LIKELY (old_obj->data.check_count)) /* Can it possibly exist in the cache? */
+ {
+ uintptr_t low = old_obj->data.low;
+ uintptr_t high = old_obj->data.high;
+ unsigned idx_low = __MF_CACHE_INDEX (low);
+ unsigned idx_high = __MF_CACHE_INDEX (high);
+ unsigned i;
+ for (i = idx_low; i <= idx_high; i++)
+ {
+ struct __mf_cache *entry = & __mf_lookup_cache [i];
+ if (entry->low == low && entry->high == high)
+ {
+ entry->low = entry->high = (uintptr_t) 0;
+ }
+ }
+ }
+}
+
+
void
__mf_register (uintptr_t ptr, uintptr_t sz, int type, const char *name)
{
@@ -498,6 +555,7 @@
static unsigned recursion = 0;
uintptr_t low = ptr;
uintptr_t high = CLAMPSZ (ptr, sz);
+ uintptr_t pc = (uintptr_t) __builtin_return_address (0);
if (UNLIKELY (recursion)) return;
recursion ++;
@@ -518,36 +576,80 @@
ovr_obj[0]->data.high == high)
{
/* do nothing */
- ;
+ recursion --;
+ return;
+ }
+ else if (type == __MF_TYPE_GUESS)
+ {
+ /* do nothing, someone has beat us here. */
+ recursion --;
+ return;
}
else
{
- __mf_violation (ptr, sz, (uintptr_t) __builtin_return_address (0),
- __MF_VIOL_REGISTER);
+ int i;
+ int all_guesses = 1;
+ for (i = 0; i < num_overlapping_objs; ++i)
+ {
+ if (ovr_obj[i]->data.type == __MF_TYPE_GUESS)
+ {
+
+ /* We're going to split our existing guess into 2
+ and put this new region in the middle */
+
+ uintptr_t guess1_low, guess1_high;
+ uintptr_t guess2_low, guess2_high;
+ uintptr_t guess_pc;
+ const char *guess_name;
+
+ guess_pc = ovr_obj[i]->data.alloc_pc;
+ guess_name = ovr_obj[i]->data.name;
+
+ guess1_low = ovr_obj[i]->data.low;
+ guess1_high = low - (1 + __mf_opts.crumple_zone);
+
+ guess2_low = high + (1 + __mf_opts.crumple_zone);
+ guess2_high = ovr_obj[i]->data.high;
+
+ /* Correct for possible over-shoot on crumple zones. */
+ guess2_low = min (guess2_low, guess2_high);
+ guess1_high = max (guess1_high, guess1_low);
+
+ if (__mf_opts.trace_mf_calls)
+ {
+ fprintf (stderr,
+ "mf: splitting guess region from %p-%p to %p-%p and %p-%p\n",
+ guess1_low,
+ guess2_high,
+ guess1_low,
+ guess1_high,
+ guess2_low,
+ guess2_high);
+ }
+
+ __mf_remove_old_object (ovr_obj[i]);
+
+ __mf_insert_new_object (guess1_low, guess1_high,
+ __MF_TYPE_GUESS,
+ guess_name, guess_pc);
+
+ __mf_insert_new_object (guess2_low, guess2_high,
+ __MF_TYPE_GUESS,
+ guess_name, guess_pc);
+
+ }
+ else
+ {
+ /* Two or more *real* mappings here. */
+ __mf_violation
+ (ptr, sz, (uintptr_t) __builtin_return_address (0),
+ __MF_VIOL_REGISTER);
+ }
+ }
}
-
- recursion --;
- return;
}
-
- new_obj = calloc (1, sizeof(__mf_object_tree_t));
- new_obj->data.low = low;
- new_obj->data.high = high;
- new_obj->data.type = type;
- new_obj->data.name = name;
- new_obj->data.alloc_pc = (uintptr_t) __builtin_return_address (0);
- gettimeofday (& new_obj->data.alloc_time, NULL);
-
- if (__mf_opts.backtrace > 0)
- {
- void *array [__mf_opts.backtrace];
- size_t bt_size;
- bt_size = backtrace (array, __mf_opts.backtrace);
- new_obj->data.alloc_backtrace = backtrace_symbols (array, bt_size);
- new_obj->data.alloc_backtrace_size = bt_size;
- }
-
- __mf_link_object (new_obj);
+
+ __mf_insert_new_object (low, high, type, name, pc);
/* We could conceivably call __mf_check() here to prime the cache,
but then the check_count field is not reliable. */
@@ -562,7 +664,7 @@
{
__mf_count_register ++;
__mf_total_register_size [(type < 0) ? 0 :
- (type > __MF_TYPE_STATIC) ? 0 :
+ (type > __MF_TYPE_GUESS) ? 0 :
type] += sz;
}
@@ -578,6 +680,8 @@
__mf_unregister (uintptr_t ptr, uintptr_t sz)
{
+ extern void __real_free (void *);
+
if (UNLIKELY (! __mf_active_p)) return;
switch (__mf_opts.mudflap_mode)
@@ -610,6 +714,21 @@
if (sz == 0) sz = 1;
num_overlapping_objs = __mf_find_objects (ptr, CLAMPSZ (ptr, sz), objs, 1);
+
+ {
+ /* do not unregister guessed regions */
+ int i;
+ for (i = 0; i < num_overlapping_objs; ++i)
+ {
+ if (objs[i]->data.type == __MF_TYPE_GUESS)
+ {
+ recursion--;
+ return;
+ }
+ }
+
+ }
+
if (UNLIKELY (num_overlapping_objs != 1))
{
/* XXX: also: should match ptr == old_obj->low ? */
@@ -621,25 +740,13 @@
}
old_obj = objs[0];
- __mf_unlink_object (old_obj);
-
- /* Remove any low/high pointers for this object from the lookup cache. */
- if (LIKELY (old_obj->data.check_count)) /* Can it possibly exist in the cache? */
+
+ if (__mf_opts.trace_mf_calls)
{
- uintptr_t low = old_obj->data.low;
- uintptr_t high = old_obj->data.high;
- unsigned idx_low = __MF_CACHE_INDEX (low);
- unsigned idx_high = __MF_CACHE_INDEX (high);
- unsigned i;
- for (i = idx_low; i <= idx_high; i++)
- {
- struct __mf_cache *entry = & __mf_lookup_cache [i];
- if (entry->low == low && entry->high == high)
- {
- entry->low = entry->high = (uintptr_t) 0;
- }
- }
+ fprintf (stderr, "mf: removing region %p-%p\n", old_obj->data.low, old_obj->data.high);
}
+
+ __mf_remove_old_object (old_obj);
if (__mf_opts.persistent_count > 0)
{
@@ -661,7 +768,7 @@
be recycled, and the previous resident to be designated del_obj. */
assert (old_obj->data.type >= __MF_TYPE_UNKNOWN &&
- old_obj->data.type <= __MF_TYPE_STATIC);
+ old_obj->data.type <= __MF_TYPE_GUESS);
{
unsigned row = old_obj->data.type;
unsigned plot = __mf_object_dead_head [row];
@@ -694,11 +801,12 @@
{
if (__mf_opts.backtrace > 0)
{
- free (del_obj->data.alloc_backtrace);
+
+ __real_free (del_obj->data.alloc_backtrace);
if (__mf_opts.persistent_count > 0)
- free (del_obj->data.dealloc_backtrace);
+ __real_free (del_obj->data.dealloc_backtrace);
}
- free (del_obj);
+ __real_free (del_obj);
}
recursion --;
@@ -747,7 +855,7 @@
unsigned cls;
unsigned i;
- for (cls = __MF_TYPE_UNKNOWN; cls <= __MF_TYPE_STATIC; cls++)
+ for (cls = __MF_TYPE_UNKNOWN; cls <= __MF_TYPE_GUESS; cls++)
{
assert (__mf_object_dead_head [cls] >= 0 &&
__mf_object_dead_head [cls] < __mf_opts.persistent_count);
@@ -996,7 +1104,7 @@
{
count = 0;
- for (row = __MF_TYPE_UNKNOWN; row <= __MF_TYPE_STATIC; row ++)
+ for (row = __MF_TYPE_UNKNOWN; row <= __MF_TYPE_GUESS; row ++)
{
unsigned plot;
unsigned i;
@@ -1051,6 +1159,7 @@
(obj->type == __MF_TYPE_HEAP ? "heap" :
obj->type == __MF_TYPE_STACK ? "stack" :
obj->type == __MF_TYPE_STATIC ? "static" :
+ obj->type == __MF_TYPE_GUESS ? "guess" :
"unknown"),
obj->check_count,
obj->alloc_time.tv_sec, obj->alloc_time.tv_usec, obj->alloc_pc);
@@ -1157,7 +1266,7 @@
{
unsigned dead_count = 0;
unsigned row, plot;
- for (row = __MF_TYPE_UNKNOWN; row <= __MF_TYPE_STATIC; row ++)
+ for (row = __MF_TYPE_UNKNOWN; row <= __MF_TYPE_GUESS; row ++)
for (plot = 0 ; plot < __mf_opts.persistent_count; plot ++)
if (__mf_object_cemetary [row][plot] != 0)
dead_count ++;
@@ -1180,6 +1289,7 @@
{
char buf [128];
static unsigned violation_number;
+ extern void __real_free (void *);
if (UNLIKELY (! __mf_active_p)) return;
Index: libmudflap/mf-runtime.h
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-runtime.h,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 mf-runtime.h
--- libmudflap/mf-runtime.h 13 Aug 2002 19:51:22 -0000 1.1.2.2
+++ libmudflap/mf-runtime.h 17 Aug 2002 00:51:37 -0000
@@ -12,9 +12,15 @@
extern struct __mf_cache __mf_lookup_cache [];
extern uintptr_t __mf_lc_mask;
extern unsigned char __mf_lc_shift;
+extern int __mf_active_p;
+
+#define UNLIKELY(e) (__builtin_expect (!!(e), 0))
+#define LIKELY(e) (__builtin_expect (!!(e), 1))
#define __MF_CACHE_INDEX(ptr) ((((uintptr_t) (ptr)) >> __mf_lc_shift) & __mf_lc_mask)
+extern void __mf_init_heuristics ();
+
extern void __mf_check (uintptr_t ptr, uintptr_t sz);
#define __MF_VIOL_UNKNOWN 0
#define __MF_VIOL_CHECK 1
@@ -25,6 +31,7 @@
#define __MF_TYPE_HEAP 1
#define __MF_TYPE_STACK 2
#define __MF_TYPE_STATIC 3
+#define __MF_TYPE_GUESS 4
extern void __mf_register (uintptr_t ptr, uintptr_t sz, int type, const char *name);
extern void __mf_unregister (uintptr_t ptr, uintptr_t sz);
extern void __mf_report ();
@@ -32,6 +39,13 @@
#define __MF_PERSIST_MAX 256
#define __MF_FREEQ_MAX 256
+#define TRACE_IN \
+ if (__mf_opts.trace_mf_calls) \
+ fprintf (stderr, "mf: enter %s\n", __FUNCTION__);
+
+#define TRACE_OUT \
+ if (__mf_opts.trace_mf_calls) \
+ fprintf (stderr, "mf: exit %s\n", __FUNCTION__);
struct __mf_options
{
@@ -62,6 +76,9 @@
/* Maintain a history of this many past unregistered objects. */
int persistent_count;
+
+ /* Pad allocated extents by this many bytes on either side. */
+ int crumple_zone;
/* Maintain this many stack frames for contexts. */
int backtrace;
Index: libmudflap/test/pass13-frag.c
===================================================================
RCS file: libmudflap/test/pass13-frag.c
diff -N libmudflap/test/pass13-frag.c
--- libmudflap/test/pass13-frag.c 1 Jan 1970 00:00:00 -0000
+++ libmudflap/test/pass13-frag.c 17 Aug 2002 00:51:37 -0000
@@ -0,0 +1,10 @@
+struct a {
+ int x;
+ int y;
+ char z;
+};
+
+struct a k;
+
+k.z = 'q';
+
Index: libmudflap/test/pass14-frag.c
===================================================================
RCS file: libmudflap/test/pass14-frag.c
diff -N libmudflap/test/pass14-frag.c
--- libmudflap/test/pass14-frag.c 1 Jan 1970 00:00:00 -0000
+++ libmudflap/test/pass14-frag.c 17 Aug 2002 00:51:37 -0000
@@ -0,0 +1,13 @@
+struct a {
+ int x;
+ int y;
+ char z;
+};
+
+struct a k;
+struct a *p;
+
+p = &k;
+
+p->z = 'q';
+
Index: libmudflap/test/pass15-frag.c
===================================================================
RCS file: libmudflap/test/pass15-frag.c
diff -N libmudflap/test/pass15-frag.c
--- libmudflap/test/pass15-frag.c 1 Jan 1970 00:00:00 -0000
+++ libmudflap/test/pass15-frag.c 17 Aug 2002 00:51:37 -0000
@@ -0,0 +1,16 @@
+struct base {
+ int basic;
+};
+
+struct derived {
+ struct base common;
+ char extra;
+};
+
+struct derived d;
+struct base *bp;
+
+bp = (struct base *)&d;
+
+bp->basic = 10;
+((struct derived *)bp)->extra = 'x';
Index: libmudflap/test/pass16-frag.c
===================================================================
RCS file: libmudflap/test/pass16-frag.c
diff -N libmudflap/test/pass16-frag.c
--- libmudflap/test/pass16-frag.c 1 Jan 1970 00:00:00 -0000
+++ libmudflap/test/pass16-frag.c 17 Aug 2002 00:51:37 -0000
@@ -0,0 +1,15 @@
+struct base {
+ int basic;
+};
+
+struct derived {
+ struct base common;
+ char extra;
+};
+
+struct base *bp;
+
+bp = (struct base *) malloc (sizeof (struct derived));
+
+bp->basic = 10;
+((struct derived *)bp)->extra = 'x';
Index: libmudflap/test/pass17-frag.c
===================================================================
RCS file: libmudflap/test/pass17-frag.c
diff -N libmudflap/test/pass17-frag.c
--- libmudflap/test/pass17-frag.c 1 Jan 1970 00:00:00 -0000
+++ libmudflap/test/pass17-frag.c 17 Aug 2002 00:51:37 -0000
@@ -0,0 +1,2 @@
+
+strlen("123456789");
Index: libmudflap/test/fail13-frag.c
===================================================================
RCS file: libmudflap/test/fail13-frag.c
diff -N libmudflap/test/fail13-frag.c
--- libmudflap/test/fail13-frag.c 1 Jan 1970 00:00:00 -0000
+++ libmudflap/test/fail13-frag.c 17 Aug 2002 00:51:37 -0000
@@ -0,0 +1,15 @@
+struct a {
+ int x;
+ int y;
+ char z;
+};
+
+struct b {
+ int x;
+ int y;
+};
+
+struct b k;
+
+(*((struct a*) &k)).z = 'q';
+
Index: libmudflap/test/fail14-frag.c
===================================================================
RCS file: libmudflap/test/fail14-frag.c
diff -N libmudflap/test/fail14-frag.c
--- libmudflap/test/fail14-frag.c 1 Jan 1970 00:00:00 -0000
+++ libmudflap/test/fail14-frag.c 17 Aug 2002 00:51:37 -0000
@@ -0,0 +1,18 @@
+struct a {
+ int x;
+ int y;
+ char z;
+};
+
+struct b {
+ int x;
+ int y;
+};
+
+struct b k;
+struct a *p;
+
+p = (struct a*) &k;
+
+p->z = 'q';
+
Index: libmudflap/test/fail15-frag.c
===================================================================
RCS file: libmudflap/test/fail15-frag.c
diff -N libmudflap/test/fail15-frag.c
--- libmudflap/test/fail15-frag.c 1 Jan 1970 00:00:00 -0000
+++ libmudflap/test/fail15-frag.c 17 Aug 2002 00:51:37 -0000
@@ -0,0 +1,16 @@
+struct base {
+ int basic;
+};
+
+struct derived {
+ struct base common;
+ char extra;
+};
+
+struct base b;
+struct base *bp;
+
+bp = (struct base *)&b;
+
+bp->basic = 10;
+((struct derived *)bp)->extra = 'x';
Index: libmudflap/test/fail16-frag.c
===================================================================
RCS file: libmudflap/test/fail16-frag.c
diff -N libmudflap/test/fail16-frag.c
--- libmudflap/test/fail16-frag.c 1 Jan 1970 00:00:00 -0000
+++ libmudflap/test/fail16-frag.c 17 Aug 2002 00:51:37 -0000
@@ -0,0 +1,15 @@
+struct base {
+ int basic;
+};
+
+struct derived {
+ struct base common;
+ char extra;
+};
+
+struct base *bp;
+
+bp = (struct base *) malloc (sizeof (struct base));;
+
+bp->basic = 10;
+((struct derived *)bp)->extra = 'x';
Index: libmudflap/test/fail17-frag.c
===================================================================
RCS file: libmudflap/test/fail17-frag.c
diff -N libmudflap/test/fail17-frag.c
--- libmudflap/test/fail17-frag.c 1 Jan 1970 00:00:00 -0000
+++ libmudflap/test/fail17-frag.c 17 Aug 2002 00:51:37 -0000
@@ -0,0 +1,5 @@
+
+char * x;
+x = (char *)malloc (10);
+strcpy (x, "123456789");
+strlen(x+10);