[tree-ssa libmudflap] heuristics, build tweaks

Frank Ch. Eigler fche@redhat.com
Tue Aug 27 15:37:00 GMT 2002


Hi -

I'm about to commit the following patch to libmudflap.
It reorganizes slightly how heuristics are used from __mf_check,
and how the libmudflap.{a,so} is constructed.  The wrapping/hook
functions (str*, malloc, etc.) are all broken into individual 
object files, for more convenient static linkage.  There is also
some other minor cleanup.


2002-08-27  Frank Ch. Eigler  <fche@redhat.com>

	libmudflap hook breakup:
	* Makefile.am (TESTS_ENVIRONMENT): Add ../../gcc to LD_LIBRARY_PATH
	for libgcc_s.
	(TESTS): Make dependent on libmudflap.
	(HOOKOBJS): Break up mf-hooks.o into many little hook objects,
	compiled from segments of mf-hooks.c.
	* mf-hooks.c: Corresponding changes: wrap each function in
	#ifdef/#endif.
	* Makefile.in: Regenerated.

	Heuristics reorganization:
	* mf-heuristics.c (__mf_register_ro_sections, __mf_init_heuristics): 
	Remove these functions.  Update callers.
	(__mf_heuristic_check): Incorporate all the various heuristics.
	Encode cacheability/retry judgement into trinary return value.
	Separate start-end logic into a separate fallback heuristic.  Only
	register relevant /proc/self/map segments.
	* mf-impl.h: Corresponding changes.
	* mf-runtime.c (__mf_check): Reorganize heuristics fallback logic.
	(__mf_init): Don't call __mf_init_heuristics.

	Tracing cleanup:
	* mf-heuristics.c, mf-runtime.c: Use new MUDFLAP_OPTION
	"-verbose-trace" to emit all tracing messages other than those of
	basic public api.  Eliminate some duplicate/excessive messages.
	* mf-runtime.h: Corresponding changes.

Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/Makefile.am,v
retrieving revision 1.1.2.6
diff -u -w -s -p -r1.1.2.6 Makefile.am
--- Makefile.am	27 Aug 2002 16:35:00 -0000	1.1.2.6
+++ Makefile.am	27 Aug 2002 22:29:33 -0000
@@ -7,7 +7,7 @@
 AUTOMAKE_OPTIONS = 1.3 cygnus
 MAINT_CHARSET = latin1
 
-TESTS_ENVIRONMENT = LD_LIBRARY_PATH='.libs' MUDFLAP_OPTIONS='-mode-check -viol-abort -no-heur-proc-map'
+TESTS_ENVIRONMENT = LD_LIBRARY_PATH='.libs:../../gcc' MUDFLAP_OPTIONS='-mode-check -viol-abort -no-heur-proc-map'
 
 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			\
@@ -34,6 +34,7 @@ test/fail%.x: test/fail%.c
 test/pass%.x: test/pass%.c
 	$(CC) -DSHOULD_PASS -rdynamic -fmudflap -g -o $@ $<
 
+$(TESTS): $(lib_LTLIBRARIES)
 
 # SUBDIRS = 
 # PWD = $${PWDCMD-pwd}
@@ -56,11 +57,53 @@ mf-heuristics.o: mf-runtime.h mf-impl.h
 
 libmudflap_la_SOURCES = \
 	mf-runtime.c \
-	mf-hooks.c \
 	mf-heuristics.c
 
-# libmudflap_la_LIBADD =
-# libmudflap_la_LDFLAGS = 
+HOOKOBJS = \
+ malloc-hook.lo \
+ free-hook.lo \
+ calloc-hook.lo \
+ realloc-hook.lo \
+ memcpy-hook.lo \
+ memmove-hook.lo \
+ memset-hook.lo \
+ memcmp-hook.lo \
+ memchr-hook.lo \
+ memrchr-hook.lo \
+ strcpy-hook.lo \
+ strncpy-hook.lo \
+ strcat-hook.lo \
+ strncat-hook.lo \
+ strcmp-hook.lo \
+ strcasecmp-hook.lo \
+ strncmp-hook.lo \
+ strncasecmp-hook.lo \
+ strdup-hook.lo \
+ strndup-hook.lo \
+ strchr-hook.lo \
+ strrchr-hook.lo \
+ strstr-hook.lo \
+ memmem-hook.lo \
+ strlen-hook.lo \
+ strnlen-hook.lo \
+ bzero-hook.lo \
+ bcopy-hook.lo \
+ bcmp-hook.lo \
+ index-hook.lo \
+ rindex-hook.lo \
+ dlopen-hook.lo \
+ mmap-hook.lo \
+ munmap-hook.lo
+
+
+$(HOOKOBJS): mf-hooks.c mf-runtime.h mf-impl.h
+	set -e; \
+	for i in $(HOOKOBJS); do \
+	     hook=`basename $$i -hook.lo`; \
+	     $(LTCOMPILE) -DWRAP_$$hook -c $(srcdir)/mf-hooks.c -o $$i; \
+	done
 
+libmudflap_la_LDFLAGS = 
+libmudflap_la_LIBADD = $(HOOKOBJS)
 libmudflap_la_DEPENDENCIES = $(libmudflap_la_LIBADD)
 
Index: mf-heuristics.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-heuristics.c,v
retrieving revision 1.1.2.5
diff -u -w -s -p -r1.1.2.5 mf-heuristics.c
--- mf-heuristics.c	26 Aug 2002 23:18:04 -0000	1.1.2.5
+++ mf-heuristics.c	27 Aug 2002 22:29:34 -0000
@@ -17,11 +17,13 @@
 #error "Do not compile this file with -fmudflap!"
 #endif
 
+/* XXX */
 extern char _end;
-
+extern char _start;
 static const uintptr_t stack_segment_base = 0xC0000000;
 static const uintptr_t stack_segment_top  = 0xBF800000;
 
+
 static int
 is_stack_address (uintptr_t addr)
 {
@@ -31,112 +33,89 @@ is_stack_address (uintptr_t addr)
 }
 
 
-static void
-__mf_register_ro_sections ()
-{
-  char buf[512];
-  char flags[4];
-  void *low, *high;
 
-  FILE *fp;
 
-  TRACE_IN;
 
-  if (LIKELY (__mf_opts.heur_proc_map == 1))
+/* Run some quick validation of the given region.  If successful, return non-zero.
+   If the result is cacheworthy, return something positive. */
+int 
+__mf_heuristic_check (uintptr_t ptr, uintptr_t ptr_high)
     {
-      fp = fopen ("/proc/self/maps", "r");
-      if (!fp)
+  TRACE_IN;
+
+  /* The first heuristic is to check stack bounds.  Since this is a
+     transient condition and quick to check, don't cache its
+     result. */
+  if (__mf_opts.heur_stack_bound)
 	{
-	  if (__mf_opts.trace_mf_calls)
+      uintptr_t stack_top_guess = (uintptr_t)__builtin_frame_address(0);
+
+      VERBOSE_TRACE ("mf: stack estimated as %p-%p\n", 
+		     stack_top_guess, stack_segment_base);
+
+      if (ptr_high <= stack_segment_base &&
+	  ptr >= stack_top_guess &&
+	  ptr_high >= ptr)
 	    {
-	      fprintf (stderr, "mf: (heuristics) cannot open /proc/self/maps\n");
-	      fprintf (stderr, "mf: (heuristics) registering 00-%p\n", &_end);
-	    }
-	  __mf_register ((uintptr_t) 0, (uintptr_t) &_end,
-			 __MF_TYPE_GUESS, 
-			 "(heuristic) static 0-__end region");
 	  TRACE_OUT;
-	  return;
+	  return 1; /* uncacheable */
 	}
+    }
+
+  /* The second heuristic is to scan the range of memory regions
+     listed in /proc/self/maps, a special file provided by the Linux
+     kernel.  Its results may be cached, and in fact, a GUESS object
+     may as well be recorded for interesting matching sections.  */
+
+  if (__mf_opts.heur_proc_map)
+    {
+      char buf[512];
+      char flags[4];
+      void *low, *high;
+      FILE *fp;
       
+      fp = fopen ("/proc/self/maps", "r");
+      if (fp)
+	{
       while (fgets (buf, sizeof(buf), fp))
 	{
 	  if (sscanf (buf, "%p-%p %4c", &low, &high, flags) == 3)
 	    {
-	      if (! (is_stack_address ((uintptr_t)low) || 
-		     is_stack_address ((uintptr_t)high)))
+		  if ((uintptr_t) low <= ptr &&
+		      (uintptr_t) high >= ptr_high)
 		{
-		  if (__mf_opts.trace_mf_calls)
-		    {
-		      fprintf (stderr, "mf: (heuristics) registering static region %p-%p\n",
-			       low, high);
-		    }
+		      VERBOSE_TRACE ("mf: registering region %p-%p given %s\n",
+				     low, high, buf);
+		      
+		      /* XXX: bad hack; permit __mf_register to do its job.  */
+		      __mf_state = active;
 		  __mf_register ((uintptr_t) low, (uintptr_t) (high-low),
 				 __MF_TYPE_GUESS, 
-				 "(heuristic) static segment");
-		} 
-	      else
-		{
-		  if (__mf_opts.trace_mf_calls)
-		    {		  
-		      fprintf (stderr, "mf: (heuristics) skipping region %s",buf);
-		    }
+				     "/proc/self/maps segment");
+		      __mf_state = reentrant;
+
+		      TRACE_OUT;
+		      return 0; /* undecided tending to cachable yes */
 		}
 	    }
 	}
       fclose (fp);
     }
-  TRACE_OUT;
 }
 
+  /* The third heuristic is to approve all accesses between _start and _end,
+     which should include all text and initialized data.  */
 
-int 
-__mf_heuristic_check (uintptr_t ptr, uintptr_t ptr_high)
-{
-
-  /* First heuristic is to check stack bounds */
-
-  if (__mf_opts.stack_bound)
-    {
-      uintptr_t stack_top_guess = (uintptr_t)__builtin_frame_address(0);
-
-      TRACE ("mf: stack bound check on %p - %p\n", 
-	     ptr, ptr_high);
-            
-      TRACE ("mf: stack estimated as %p - %p\n", 
-	     stack_top_guess, stack_segment_base);
-      
-      if (LIKELY(is_stack_address (ptr)))
+  if (__mf_opts.heur_start_end)
 	{
-	  if (UNLIKELY(ptr_high > stack_segment_base))
+      if (ptr >= (uintptr_t) & _start && ptr_high <= (uintptr_t) & _end)
 	    {
-	      TRACE ("mf: ptr_high %p off bottom of stack %p\n",
-		     ptr_high, stack_segment_base);
-	      return 0;
-	    }
-	  if (UNLIKELY(ptr < stack_top_guess))
-	    {
-	      TRACE ("mf: ptr %p off top of stack %p\n",
-		     ptr_high, stack_top_guess);
-	      return 0;
-	    }
-	  return (ptr_high >= ptr);
+	  TRACE_OUT;
+	  return 1; /* uncacheable */
 	}            
     }
 
-  TRACE ("mf: no heuristics validate extent %p - %p\n", 
-	 ptr, ptr_high);
-    return 0;
-}
 
-void
-__mf_init_heuristics ()
-{
-  enum __mf_state old_state;
-  old_state = __mf_state;
-  __mf_state = starting;
-  TRACE_IN;
-  __mf_register_ro_sections ();
   TRACE_OUT;
-  __mf_state = old_state;
+  return -1; /* hard failure */
 }
Index: mf-hooks.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-hooks.c,v
retrieving revision 1.1.2.11
diff -u -w -s -p -r1.1.2.11 mf-hooks.c
--- mf-hooks.c	27 Aug 2002 16:35:00 -0000	1.1.2.11
+++ mf-hooks.c	27 Aug 2002 22:29:34 -0000
@@ -62,6 +62,7 @@ XXX: libgcc license?
 
 /* {{{ malloc/free etc. */
 
+#ifdef WRAP_malloc
 WRAPPER(void *, malloc, size_t c)
 {
   size_t size_with_crumple_zones;
@@ -85,8 +86,10 @@ WRAPPER(void *, malloc, size_t c)
   TRACE_OUT;
   return result;
 }
+#endif
 
 
+#ifdef WRAP_calloc
 WRAPPER(void *, calloc, size_t c, size_t n)
 {
   size_t size_with_crumple_zones;
@@ -116,7 +119,9 @@ WRAPPER(void *, calloc, size_t c, size_t
   TRACE_OUT;
   return result;
 }
+#endif
 
+#ifdef WRAP_realloc
 WRAPPER(void *, realloc, void *buf, size_t c)
 {
   DECLARE(void * , realloc, void *, size_t);
@@ -148,8 +153,10 @@ WRAPPER(void *, realloc, void *buf, size
   TRACE_OUT;
   return result;
 }
+#endif
 
 
+#ifdef WRAP_free
 WRAPPER(void, free, void *buf)
 {
   /* Use a circular queue to delay some number (__mf_opts.free_queue_length) of free()s.  */
@@ -217,18 +224,23 @@ WRAPPER(void, free, void *buf)
   __mf_state = old_state;
   TRACE_OUT;
 }
+#endif
 
+
+#ifdef WRAP_dlopen
 WRAPPER(void *, dlopen, const char *filename, int flag)
 {
   DECLARE(void * , dlopen, const char *filename, int flag);
   BEGIN_PROTECT(void *, dlopen, filename, flag);
   result = CALL_REAL(dlopen, filename, flag);
   __mf_state = old_state;
-  __mf_init_heuristics ();
   TRACE_OUT;
   return result;
 }
+#endif
+
 
+#ifdef WRAP_mmap
 WRAPPER(void *, mmap, 
 	void  *start,  size_t length, int prot, 
 	int flags, int fd, off_t offset)
@@ -258,7 +270,10 @@ WRAPPER(void *, mmap, 
   TRACE_OUT;
   return result;
 }
+#endif
+
 
+#ifdef WRAP_munmap
 WRAPPER(int , munmap, void *start, size_t length)
 {
   DECLARE(int, munmap, void *, size_t);
@@ -269,10 +284,12 @@ WRAPPER(int , munmap, void *start, size_
   __mf_state = old_state;
   __mf_unregister ((uintptr_t)start, length);
 }
+#endif
 
 /* }}} */
 /* {{{ str*,mem*,b* */
 
+#ifdef WRAP_memcpy
 WRAPPER(void *, memcpy, void *dest, const void *src, size_t n)
 {
   DECLARE(void *, memcpy, void *dest, const void *src, size_t n);
@@ -281,9 +298,10 @@ WRAPPER(void *, memcpy, void *dest, cons
   MF_VALIDATE_EXTENT(dest, n, "memcpy dest");
   END_PROTECT (void *, memcpy, dest, src, n);
 }
+#endif
 
 
-
+#ifdef WRAP_memmove
 WRAPPER(void *, memmove, void *dest, const void *src, size_t n)
 {
   DECLARE(void *, memmove, void *dest, const void *src, size_t n);
@@ -292,7 +310,9 @@ WRAPPER(void *, memmove, void *dest, con
   MF_VALIDATE_EXTENT(dest, n, "memmove dest");
   END_PROTECT(void *, memmove, dest, src, n);
 }
+#endif
 
+#ifdef WRAP_memset
 WRAPPER(void *, memset, void *s, int c, size_t n)
 {
   DECLARE(void *, memset, void *s, int c, size_t n);
@@ -300,7 +320,9 @@ WRAPPER(void *, memset, void *s, int c, 
   MF_VALIDATE_EXTENT(s, n, "memset dest");
   END_PROTECT(void *, memset, s, c, n);
 }
+#endif
 
+#ifdef WRAP_memcmp
 WRAPPER(int, memcmp, const void *s1, const void *s2, size_t n)
 {
   DECLARE(int , memcmp, const void *s1, const void *s2, size_t n);
@@ -309,7 +331,9 @@ WRAPPER(int, memcmp, const void *s1, con
   MF_VALIDATE_EXTENT(s2, n, "memcmp 2nd arg");
   END_PROTECT(int, memcmp, s1, s2, n);
 }
+#endif
 
+#ifdef WRAP_memchr
 WRAPPER(void *, memchr, const void *s, int c, size_t n)
 {
   DECLARE(void *, memchr, const void *s, int c, size_t n);
@@ -317,7 +341,9 @@ WRAPPER(void *, memchr, const void *s, i
   MF_VALIDATE_EXTENT(s, n, "memchr region");
   END_PROTECT(void *, memchr, s, c, n);
 }
+#endif
 
+#ifdef WRAP_memrchr
 WRAPPER(void *, memrchr, const void *s, int c, size_t n)
 {
   DECLARE(void *, memrchr, const void *s, int c, size_t n);
@@ -325,8 +351,9 @@ WRAPPER(void *, memrchr, const void *s, 
   MF_VALIDATE_EXTENT(s, n, "memrchr region");
   END_PROTECT(void *, memrchr, s, c, n);
 }
+#endif
 
-
+#ifdef WRAP_strcpy
 WRAPPER(char *, strcpy, char *dest, const char *src)
 {
   DECLARE(int, strlen, const char *s);
@@ -344,7 +371,9 @@ WRAPPER(char *, strcpy, char *dest, cons
   MF_VALIDATE_EXTENT(dest, CLAMPADD(n, 1), "strcpy dest");
   END_PROTECT(char *, strcpy, dest, src);
 }
+#endif
 
+#ifdef WRAP_strncpy
 WRAPPER(char *, strncpy, char *dest, const char *src, size_t n)
 {
   DECLARE(int, strnlen, const char *s, size_t n);
@@ -358,7 +387,9 @@ WRAPPER(char *, strncpy, char *dest, con
   MF_VALIDATE_EXTENT(dest, len, "strncpy dest"); /* nb: strNcpy */
   END_PROTECT(char *, strncpy, dest, src, n);
 }
+#endif
 
+#ifdef WRAP_strcat
 WRAPPER(char *, strcat, char *dest, const char *src)
 {
   DECLARE(int, strlen, const char *s);
@@ -373,7 +404,9 @@ WRAPPER(char *, strcat, char *dest, cons
   MF_VALIDATE_EXTENT(dest, CLAMPADD(dest_sz, CLAMPADD(src_sz, 1)), "strcat dest");
   END_PROTECT(char *, strcat, dest, src);
 }
+#endif
 
+#ifdef WRAP_strncat
 WRAPPER(char *, strncat, char *dest, const char *src, size_t n)
 {
 
@@ -410,7 +443,9 @@ WRAPPER(char *, strncat, char *dest, con
 		     "strncat dest");
   END_PROTECT(char *, strncat, dest, src, n);
 }
+#endif
 
+#ifdef WRAP_strcmp
 WRAPPER(int, strcmp, const char *s1, const char *s2)
 {
   DECLARE(int, strlen, const char *s);
@@ -425,7 +460,9 @@ WRAPPER(int, strcmp, const char *s1, con
   MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), "strcmp 2nd arg");
   END_PROTECT(int, strcmp, s1, s2);
 }
+#endif
 
+#ifdef WRAP_strcasecmp
 WRAPPER(int, strcasecmp, const char *s1, const char *s2)
 {
   DECLARE(int, strlen, const char *s);
@@ -440,7 +477,9 @@ WRAPPER(int, strcasecmp, const char *s1,
   MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), "strcasecmp 2nd arg");
   END_PROTECT(int, strcasecmp, s1, s2);
 }
+#endif
 
+#ifdef WRAP_strncmp
 WRAPPER(int, strncmp, const char *s1, const char *s2, size_t n)
 {
   DECLARE(int, strnlen, const char *s, size_t n);
@@ -455,7 +494,9 @@ WRAPPER(int, strncmp, const char *s1, co
   MF_VALIDATE_EXTENT(s2, s2_sz, "strncmp 2nd arg");
   END_PROTECT(int, strncmp, s1, s2, n);
 }
+#endif
 
+#ifdef WRAP_strncasecmp
 WRAPPER(int, strncasecmp, const char *s1, const char *s2, size_t n)
 {
   DECLARE(int, strnlen, const char *s, size_t n);
@@ -470,7 +511,9 @@ WRAPPER(int, strncasecmp, const char *s1
   MF_VALIDATE_EXTENT(s2, s2_sz, "strncasecmp 2nd arg");
   END_PROTECT(int, strncasecmp, s1, s2, n);
 }
+#endif
 
+#ifdef WRAP_strdup
 WRAPPER(char *, strdup, const char *s)
 {
   DECLARE(int, strlen, const char *s);
@@ -505,7 +548,9 @@ WRAPPER(char *, strdup, const char *s)
   TRACE_OUT;
   return result;
 }
+#endif
 
+#ifdef WRAP_strndup
 WRAPPER(char *, strndup, const char *s, size_t n)
 {
   DECLARE(int, strnlen, const char *s, size_t n);
@@ -541,8 +586,9 @@ WRAPPER(char *, strndup, const char *s, 
   TRACE_OUT;
   return result;
 }
+#endif
 
-
+#ifdef WRAP_strchr
 WRAPPER(char *, strchr, const char *s, int c)
 {
   DECLARE(int, strlen, const char *s);
@@ -554,7 +600,9 @@ WRAPPER(char *, strchr, const char *s, i
   MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), "strchr region");
   END_PROTECT(char *, strchr, s, c);
 }
+#endif
 
+#ifdef WRAP_strrchr
 WRAPPER(char *, strrchr, const char *s, int c)
 {
   DECLARE(int, strlen, const char *s);
@@ -566,8 +614,9 @@ WRAPPER(char *, strrchr, const char *s, 
   MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), "strrchr region");
   END_PROTECT(char *, strrchr, s, c);
 }
+#endif
 
-
+#ifdef WRAP_strstr
 WRAPPER(char *, strstr, const char *haystack, const char *needle)
 {
   DECLARE(int, strlen, const char *s);
@@ -582,7 +631,9 @@ WRAPPER(char *, strstr, const char *hays
   MF_VALIDATE_EXTENT(needle, CLAMPADD(needle_sz, 1), "strstr needle");
   END_PROTECT(char *, strstr, haystack, needle);
 }
+#endif
 
+#ifdef WRAP_memmem
 WRAPPER(void *, memmem, 
 	const void *haystack, size_t haystacklen,
 	const void *needle, size_t needlelen)
@@ -595,7 +646,9 @@ WRAPPER(void *, memmem, 
   MF_VALIDATE_EXTENT(needle, needlelen, "memmem needle");
   END_PROTECT(char *, memmem, haystack, haystacklen, needle, needlelen);
 }
+#endif
 
+#ifdef WRAP_strlen
 WRAPPER(int, strlen, const char *s)
 {
   DECLARE(int, strlen, const char *s);
@@ -607,7 +660,9 @@ WRAPPER(int, strlen, const char *s)
   TRACE_OUT;
   return result;
 }
+#endif
 
+#ifdef WRAP_strnlen
 WRAPPER(int, strnlen, const char *s, size_t n)
 {
   DECLARE(int, strnlen, const char *s, size_t n);
@@ -619,7 +674,9 @@ WRAPPER(int, strnlen, const char *s, siz
   TRACE_OUT;
   return result;
 }
+#endif
 
+#ifdef WRAP_bzero
 WRAPPER(void, bzero, void *s, size_t n)
 {
   DECLARE(void , bzero, void *s, size_t n);
@@ -638,7 +695,9 @@ WRAPPER(void, bzero, void *s, size_t n)
   __mf_state = old_state;
   TRACE_OUT;
 }
+#endif
 
+#ifdef WRAP_bcopy
 WRAPPER(void, bcopy, const void *src, void *dest, size_t n)
 {
   DECLARE(void , bcopy, const void *src, void *dest, size_t n);
@@ -658,7 +717,9 @@ WRAPPER(void, bcopy, const void *src, vo
   __mf_state = old_state;
   TRACE_OUT;
 }
+#endif
 
+#ifdef WRAP_bcmp
 WRAPPER(int, bcmp, const void *s1, const void *s2, size_t n)
 {
   DECLARE(int , bcmp, const void *s1, const void *s2, size_t n);
@@ -668,7 +729,9 @@ WRAPPER(int, bcmp, const void *s1, const
   MF_VALIDATE_EXTENT(s2, n, "bcmp 2nd arg");
   END_PROTECT(int, bcmp, s1, s2, n);
 }
+#endif
 
+#ifdef WRAP_index
 WRAPPER(char *, index, const char *s, int c)
 {
   DECLARE(int, strlen, const char *s);
@@ -680,9 +743,9 @@ WRAPPER(char *, index, const char *s, in
   MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), "index region");
   END_PROTECT(char *, index, s, c);
 }
+#endif
 
-
-
+#ifdef WRAP_rindex
 WRAPPER(char *, rindex, const char *s, int c)
 {
   DECLARE(int, strlen, const char *s);
@@ -694,7 +757,7 @@ WRAPPER(char *, rindex, const char *s, i
   MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), "rindex region");
   END_PROTECT(char *, rindex, s, c);
 }
-
+#endif
 
 /* }}} */
 /* {{{ *printf,*scanf */
Index: mf-impl.h
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-impl.h,v
retrieving revision 1.1.2.2
diff -u -w -s -p -r1.1.2.2 mf-impl.h
--- mf-impl.h	27 Aug 2002 16:35:00 -0000	1.1.2.2
+++ mf-impl.h	27 Aug 2002 22:29:34 -0000
@@ -19,13 +19,14 @@
 
 /* Private functions. */ 
 
-extern void __mf_init_heuristics ();
 extern void __mf_violation (uintptr_t ptr, uintptr_t sz, 
 			    uintptr_t pc, const char *location, 
 			    int type);
 
 extern size_t __mf_backtrace (char ***, void *, unsigned);
 extern void __mf_resolve_dynamics ();
+extern int __mf_heuristic_check (uintptr_t, uintptr_t);
+
 
 /* ------------------------------------------------------------------------ */
 /* Type definitions. */
@@ -63,15 +64,15 @@ struct __mf_options
   /* Print verbose description of violations. */
   int verbose_violations;
 
+  /* Emit internal tracing message. */
+  int verbose_trace;
+
   /* Perform occasional tree-rotations to optimize lookups. */
   int optimize_object_tree;
 
   /* Support multiple threads. */
   int multi_threaded;
 
-  /* use __libc_stack_end heuristic */
-  int stack_bound;
-  
   /* Maintain a queue of this many deferred free()s, 
      to trap use of freed memory. */
   int free_queue_length;
@@ -109,7 +110,9 @@ struct __mf_options
   violation_mode;
 
   /* Violation heuristics selection. */
-  int heur_proc_map;  /* Register /proc/self/map regions.  */
+  int heur_stack_bound; /* allow current stack region */
+  int heur_proc_map;  /* allow & cache /proc/self/map regions.  */
+  int heur_start_end; /* allow & cache _start .. _end */
 };
 
 
@@ -175,12 +178,15 @@ extern struct __mf_dynamic __mf_dynamic;
 #define LIKELY(e) (__builtin_expect (!!(e), 1))
 #define STRINGIFY2(e) #e
 #define STRINGIFY(e) STRINGIFY2(e)
+#define VERBOSE_TRACE(...)                         \
+  if (UNLIKELY (__mf_opts.verbose_trace)) \
+      fprintf (stderr, __VA_ARGS__);
 #define TRACE(...)                         \
   if (UNLIKELY (__mf_opts.trace_mf_calls)) \
       fprintf (stderr, __VA_ARGS__);
 
-#define TRACE_IN TRACE("mf: enter %s\n", __PRETTY_FUNCTION__)
-#define TRACE_OUT TRACE("mf: exit %s\n", __PRETTY_FUNCTION__)
+#define TRACE_IN VERBOSE_TRACE ("mf: enter %s\n", __PRETTY_FUNCTION__)
+#define TRACE_OUT VERBOSE_TRACE ("mf: exit %s\n", __PRETTY_FUNCTION__)
 
 
 #define __MF_PERSIST_MAX 256
Index: mf-runtime.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-runtime.c,v
retrieving revision 1.1.2.9
diff -u -w -s -p -r1.1.2.9 mf-runtime.c
--- mf-runtime.c	26 Aug 2002 23:18:04 -0000	1.1.2.9
+++ mf-runtime.c	27 Aug 2002 22:29:34 -0000
@@ -87,13 +87,13 @@ static void
 __mf_set_default_options ()
 {
   __mf_opts.trace_mf_calls = 0;
+  __mf_opts.verbose_trace = 0;
   __mf_opts.collect_stats = 0;
   __mf_opts.internal_checking = 0;
   __mf_opts.print_leaks = 0;
   __mf_opts.verbose_violations = 0;
   __mf_opts.optimize_object_tree = 0;
   __mf_opts.multi_threaded = 0;
-  __mf_opts.stack_bound = 0;
   __mf_opts.free_queue_length = 0;
   __mf_opts.persistent_count = 0;
   __mf_opts.crumple_zone = 32;
@@ -101,6 +101,8 @@ __mf_set_default_options ()
   __mf_opts.mudflap_mode = mode_check;
   __mf_opts.violation_mode = viol_nop;
   __mf_opts.heur_proc_map = 1;
+  __mf_opts.heur_stack_bound = 0;
+  __mf_opts.heur_start_end = 0;
 }
 
 static struct option
@@ -146,6 +148,10 @@ options [] =
     {"trace-calls", 
      "trace calls to mudflap runtime library",
      set_option, 1, &__mf_opts.trace_mf_calls},
+    {"verbose-trace", 
+     "trace internal events within mudflap runtime library",
+     set_option, 1, &__mf_opts.verbose_trace},
+
     {"collect-stats", 
      "collect statistics on mudflap's operation",
      set_option, 1, &__mf_opts.collect_stats},
@@ -168,9 +174,12 @@ options [] =
     {"heur-proc-map", 
      "support /proc/self/map heuristics",
      set_option, 1, &__mf_opts.heur_proc_map},
-    {"stack-bound",
+    {"heur-stack-bound",
      "enable a simple upper stack bound heuristic",
-     set_option, 1, &__mf_opts.stack_bound},
+     set_option, 1, &__mf_opts.heur_stack_bound},
+    {"heur-start-end", 
+     "support _start.._end heuristics",
+     set_option, 1, &__mf_opts.heur_start_end},
      
     {"free-queue-length", 
      "queue N deferred free() calls before performing them",
@@ -423,8 +432,6 @@ void __mf_init ()
 	}
     }
 
-  __mf_init_heuristics ();
-
   __mf_state = active;
 
   TRACE_OUT;
@@ -447,7 +454,7 @@ static unsigned long __mf_count_check;
 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_GUESS+1];
+static unsigned long __mf_total_register_size [__MF_TYPE_MAX+1];
 static unsigned long __mf_count_unregister;
 static unsigned long __mf_total_unregister_size;
 static unsigned long __mf_count_violation [__MF_VIOL_UNREGISTER+1];
@@ -508,10 +515,11 @@ void __mf_check (uintptr_t ptr, uintptr_
   struct __mf_cache *entry = & __mf_lookup_cache [entry_idx];
   int violation_p = 0;
   uintptr_t ptr_high = CLAMPSZ (ptr, sz);
-
   struct __mf_cache old_entry = *entry;
 
   BEGIN_RECURSION_PROTECT;
+  TRACE ("mf: check p=%p s=%lu "
+	 "location=`%s'\n", (void *)ptr, sz, location);
   
   switch (__mf_opts.mudflap_mode)
     {
@@ -525,10 +533,9 @@ void __mf_check (uintptr_t ptr, uintptr_
 
     case mode_check:
       {
-
-	int attempts = 2;
-
-	while (attempts--)
+	unsigned heuristics = 0;
+	/* Looping only occurs if heuristics were triggered.  */
+	while (1) 
 	  {
 	    __mf_object_tree_t *node = __mf_find_object (ptr, ptr_high);
 	    __mf_object_t *obj = (node != NULL ? (& node->data) : NULL);
@@ -538,29 +545,33 @@ void __mf_check (uintptr_t ptr, uintptr_
 		entry->low = obj->low;
 		entry->high = obj->high;
 		obj->check_count ++;  /* XXX: what about overflow?  */
-		attempts = 0;
+		break;
 	      }
-	    else
+	    else if (heuristics++ < 2) /* XXX parametrize this number? */
 	      {
-		if (__mf_heuristic_check (ptr, ptr_high))
+		int judgement = __mf_heuristic_check (ptr, ptr_high);
+		if (judgement < 0)
 		  {
-		    attempts = 0;
+		    violation_p = 1;
+		    break;
 		  }
-		else
-		  {	      
-		    /* Possible violation. */
-		    if (attempts > 0)
+		else if (judgement > 0)
 		      {
-			/* Try re-initializing heuristics. */
-			__mf_init_heuristics (); 
+		    violation_p = 0;
+		    break;
 		      }
-		    else
+		else if (judgement == 0)
 		      {
-			/* This is our second time around,
-			   therefore we are out of luck. */
-			violation_p = 1;
+		    /* Undecided: try again.  Most likely, the heuristics function
+		       has deposited an object in the database and is expecting us
+		       to find it the next time around.  */
+		    continue;
 		      }
 		  }
+	    else /* no more heuristics iterations allowed */
+	      {
+		violation_p = 1;
+		break;
 	      }
 	  }
       }    
@@ -580,8 +591,6 @@ void __mf_check (uintptr_t ptr, uintptr_
 	__mf_lookup_cache_reusecount [entry_idx] ++;    
     }
   
-  TRACE ("mf: check p=%p s=%lu viol=%d location=%s\n", (void *)ptr, sz, 
-	 violation_p, location);
   END_RECURSION_PROTECT;
   
   if (UNLIKELY (violation_p))
@@ -646,10 +655,9 @@ __mf_remove_old_object (__mf_object_tree
 void
 __mf_register (uintptr_t ptr, uintptr_t sz, int type, const char *name)
 {
+  /* if (UNLIKELY (!(__mf_state == active || __mf_state == starting))) return; */
 
-  if (UNLIKELY (!(__mf_state == active || __mf_state == starting))) return;
-
-  TRACE("mf: reg p=%p s=%lu t=%d n='%s'\n", (void *)ptr, sz, 
+  TRACE ("mf: register p=%p s=%lu t=%d n='%s'\n", (void *)ptr, sz, 
 	type, name ? name : "");
 
   switch (__mf_opts.mudflap_mode)
@@ -665,6 +673,7 @@ __mf_register (uintptr_t ptr, uintptr_t 
 
     case mode_populate:
       /* Clear the cache.  */
+      /* XXX: why the entire cache? */
       memset (__mf_lookup_cache, 0, sizeof(__mf_lookup_cache));
       break;
 
@@ -695,7 +704,7 @@ __mf_register (uintptr_t ptr, uintptr_t 
 		ovr_obj[0]->data.high == high)
 	      {
 		/* do nothing */
-		TRACE ("mf: duplicate static reg %p\n", (void *)low);
+		VERBOSE_TRACE ("mf: duplicate static reg %p\n", (void *)low);
 		END_RECURSION_PROTECT;
 		return;
 	      }
@@ -713,9 +722,15 @@ __mf_register (uintptr_t ptr, uintptr_t 
 		      }
 		  }
 
+		/* XXX: the following logic is too restrictive.
+		   We should handle the case of inserting a big GUESS
+		   on top of a little (say) HEAP area.  The new GUESS
+		   thingie should be split up the same way as if the
+		   little HEAPie was added second.  */
 		if (all_guesses)
 		  {
-		    TRACE ("mf: replacing %d existing guess%s at %p with %p - %p\n", 
+		    VERBOSE_TRACE ("mf: replacing %d existing guess%s at %p "
+				   "with %p - %p\n", 
 			   num_overlapping_objs,
 			   (num_overlapping_objs > 1 ? "es" : ""),
 			   (void *)low,
@@ -734,7 +749,7 @@ __mf_register (uintptr_t ptr, uintptr_t 
 		  } 
 		else 
 		  {
-		    TRACE ("mf: preserving %d regions at %p\n", 
+		    VERBOSE_TRACE ("mf: preserving %d regions at %p\n", 
 			   num_overlapping_objs, (void *)low);
 		  }		
 		END_RECURSION_PROTECT;
@@ -766,7 +781,7 @@ __mf_register (uintptr_t ptr, uintptr_t 
 			guess2_low = CLAMPADD (high, (1 + __mf_opts.crumple_zone));
 			guess2_high = ovr_obj[i]->data.high;
 
-			TRACE("mf: splitting guess region %p-%p\n", 
+			VERBOSE_TRACE ("mf: splitting guess region %p-%p\n", 
 			      guess1_low, guess2_high);
 		    
 			/* NB: split regions may disappear if low > high. */
@@ -795,7 +810,6 @@ __mf_register (uintptr_t ptr, uintptr_t 
 		    else
 		      {
 			/* Two or more *real* mappings here. */
-			TRACE("mf: reg violation %p\n", (void *)low);
 			__mf_violation 
 			  (ptr, sz, 
 			   (uintptr_t) __builtin_return_address (0), NULL,
@@ -820,7 +834,7 @@ __mf_register (uintptr_t ptr, uintptr_t 
     {
       __mf_count_register ++;
       __mf_total_register_size [(type < 0) ? 0 :
-				(type > __MF_TYPE_GUESS) ? 0 : 
+				(type > __MF_TYPE_MAX) ? 0 : 
 				type] += sz;
     }
 }
@@ -834,6 +848,8 @@ __mf_unregister (uintptr_t ptr, uintptr_
   DECLARE (void, free, void *ptr);
   BEGIN_RECURSION_PROTECT;
 
+  TRACE ("mf: unregister p=%p s=%lu\n", (void *)ptr, sz);
+
   switch (__mf_opts.mudflap_mode)
     { 
     case mode_nop:
@@ -870,7 +886,7 @@ __mf_unregister (uintptr_t ptr, uintptr_
 	    {
 	      if (objs[i]->data.type == __MF_TYPE_GUESS)
 		{
-		  TRACE("mf: ignored guess unreg %p\n", objs[i]->data.low); 		  
+		  VERBOSE_TRACE ("mf: ignored guess unreg %p\n", objs[i]->data.low);
 		  END_RECURSION_PROTECT;
 		  return;
 		}
@@ -879,8 +895,7 @@ __mf_unregister (uintptr_t ptr, uintptr_
 
 	if (UNLIKELY (num_overlapping_objs != 1))
 	  {
-	    /* XXX: also: should match ptr == old_obj->low ? */
-	    TRACE("mf: unreg viol %p\n", (void *)ptr);
+	    /* XXX: also: should check/assert ptr == old_obj->low ? */
 	    END_RECURSION_PROTECT;
 	    __mf_violation (ptr, sz,
 			    (uintptr_t) __builtin_return_address (0), NULL,
@@ -890,7 +905,7 @@ __mf_unregister (uintptr_t ptr, uintptr_
 	
 	old_obj = objs[0];
 
-	TRACE("mf: removing %p-%p\n", old_obj->data.low, old_obj->data.high); 
+	VERBOSE_TRACE ("mf: removing %p-%p\n", old_obj->data.low, old_obj->data.high); 
 
 	__mf_remove_old_object (old_obj);
 	
@@ -964,7 +979,6 @@ __mf_unregister (uintptr_t ptr, uintptr_
       __mf_total_unregister_size += sz;
     }
 
-  TRACE("mf: unr p=%p s=%lu\n", (void *)ptr, sz);
   END_RECURSION_PROTECT;
 }
 
@@ -1367,13 +1381,14 @@ __mf_report ()
 	       "*******\n"
 	       "mudflap stats:\n"
 	       "calls to __mf_check: %lu rot: %lu/%lu\n"
-	       "         __mf_register: %lu [%luB, %luB, %luB, %luB]\n"
+	       "         __mf_register: %lu [%luB, %luB, %luB, %luB, %luB]\n"
 	       "         __mf_unregister: %lu [%luB]\n"
 	       "         __mf_violation: [%lu, %lu, %lu, %lu]\n",
 	       __mf_count_check, __mf_treerot_left, __mf_treerot_right,
 	       __mf_count_register,
 	       __mf_total_register_size[0], __mf_total_register_size[1],
 	       __mf_total_register_size[2], __mf_total_register_size[3],
+	       __mf_total_register_size[4], /* XXX */
 	       __mf_count_unregister, __mf_total_unregister_size,
 	       __mf_count_violation[0], __mf_count_violation[1],
 	       __mf_count_violation[2], __mf_count_violation[3]);
@@ -1490,16 +1505,18 @@ __mf_violation (uintptr_t ptr, uintptr_t
     violation_number ++;
     fprintf (stderr,
 	     "*******\n"
-	     "mudflap violation %u: time=%lu.%06lu ptr=%08lx size=%lu pc=%08lx%s%s%s type=%s\n", 
+	     "mudflap violation %u (%s): time=%lu.%06lu "
+	     "ptr=%08lx size=%lu pc=%08lx%s%s%s\n", 
 	     violation_number,
-	     now.tv_sec, now.tv_usec, ptr, sz, pc,
-	     (location != NULL ? " location=`" : ""),
-	     (location != NULL ? location : ""),
-	     (location != NULL ? "'" : ""),
 	     ((type == __MF_VIOL_CHECK) ? "check" :
 	      (type == __MF_VIOL_REGISTER) ? "register" :
 	      (type == __MF_VIOL_UNREGISTER) ? "unregister" :
-	      "unknown"));
+	      "unknown"),
+	     now.tv_sec, now.tv_usec, 
+	     ptr, sz, pc,
+	     (location != NULL ? " location=`" : ""),
+	     (location != NULL ? location : ""),
+	     (location != NULL ? "'" : ""));
 
     if (__mf_opts.backtrace > 0)
       {
@@ -1561,7 +1578,7 @@ __mf_violation (uintptr_t ptr, uintptr_t
 	    unsigned after = (low > obj->high) ? low - obj->high : 0;
 	    unsigned into = (high >= obj->low && low <= obj->high) ? low - obj->low : 0;
 
-	    fprintf (stderr, "Nearby object %u: ptr is %uB %s\n",
+	    fprintf (stderr, "Nearby object %u: region is %uB %s\n",
 		     i + 1,
 		     (before ? before :
 		      after ? after :
Index: mf-runtime.h
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-runtime.h,v
retrieving revision 1.1.2.7
diff -u -w -s -p -r1.1.2.7 mf-runtime.h
--- mf-runtime.h	26 Aug 2002 23:18:04 -0000	1.1.2.7
+++ mf-runtime.h	27 Aug 2002 22:29:34 -0000
@@ -44,6 +44,7 @@ extern void __mf_check (uintptr_t ptr, u
 #define __MF_TYPE_STACK 2
 #define __MF_TYPE_STATIC 3
 #define __MF_TYPE_GUESS 4
+#define __MF_TYPE_MAX __MF_TYPE_GUESS
 
 /* The "public" mudflap API */
 extern void __mf_register (uintptr_t ptr, uintptr_t sz, int type, const char *name);



More information about the Gcc-patches mailing list