This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[tree-ssa mudflap] bug fixes and new stack heuristic


Just committed:

[ libmudflap/ChangeLog ]

2002-08-20  Graydon Hoare  <graydon@redhat.com>

	* mf-runtime.h: New option: stack_bound (heuristic). 
	Move some macros out of implementation files.
	* mf-runtime.c: New option string: -stack-bound.
	Unify recursion protection with hooks. 
	Add more logging.
	(__mf_check): Call __mf_heuristic_check.
	(__mf_process_opts): Fix "no-" processing.
	* mf-heuristics.c (__mf_heuristic_check): New function.
	* mf-hooks.c: Much off-by-one fixing, recursion protection.


Index: libmudflap/mf-heuristics.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-heuristics.c,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 mf-heuristics.c
--- libmudflap/mf-heuristics.c	20 Aug 2002 16:56:01 -0000	1.1.2.2
+++ libmudflap/mf-heuristics.c	20 Aug 2002 21:04:50 -0000
@@ -12,6 +12,10 @@
 #include <stdio.h>
 #include "mf-runtime.h"
 
+#ifdef _MUDFLAP
+#error "Do not compile this file with -fmudflap!"
+#endif
+
 extern char _end;
 
 static void
@@ -25,40 +29,43 @@
 
   TRACE_IN;
 
-  fp = fopen ("/proc/self/maps", "r");
-  if (!fp)
+  if (LIKELY (__mf_opts.heur_proc_map == 1))
     {
-      if (__mf_opts.trace_mf_calls)
+      fp = fopen ("/proc/self/maps", "r");
+      if (!fp)
 	{
-	  fprintf (stderr, "mf: (heuristics) cannot open /proc/self/maps\n");
-	  fprintf (stderr, "mf: (heuristics) registering 00-%p\n", &_end);
+	  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 ((uintptr_t) 0, (uintptr_t) &_end,
+			 __MF_TYPE_GUESS, 
+			 "(heuristic) static 0-__end region");
+	  TRACE_OUT;
+	  return;
 	}
-      __mf_register ((uintptr_t) 0, (uintptr_t) &_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)
+      
+      while (fgets (buf, sizeof(buf), fp))
 	{
-	  if (flags[0] == 'r' &&
-	      flags[1] == '-')
+	  if (sscanf (buf, "%p-%p %4c", &low, &high, flags) == 3)
 	    {
-	      if (__mf_opts.trace_mf_calls)
+	      if (flags[0] == 'r' &&
+		  flags[1] == '-')
 		{
-		  fprintf (stderr, "mf: (heuristics) registering static region %p-%p\n",
-			  low, high);
-		}
-	      __mf_register ((uintptr_t) low, (uintptr_t) (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. */
-	  /*
+		  if (__mf_opts.trace_mf_calls)
+		    {
+		      fprintf (stderr, "mf: (heuristics) registering static region %p-%p\n",
+			       low, high);
+		    }
+		  __mf_register ((uintptr_t) low, (uintptr_t) (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)
@@ -70,19 +77,61 @@
 			     "(heuristic) static executable segment");
 	    }
 	  */
-	  else
-	    {
-	      if (__mf_opts.trace_mf_calls)
-		{		  
-		  fprintf (stderr, "mf: (heuristics) skipping region %s",buf);
+	      else
+		{
+		  if (__mf_opts.trace_mf_calls)
+		    {		  
+		      fprintf (stderr, "mf: (heuristics) skipping region %s",buf);
+		    }
 		}
 	    }
 	}
+      fclose (fp);
     }
-  fclose (fp);
   TRACE_OUT;
 }
 
+
+int 
+__mf_heuristic_check (uintptr_t ptr, uintptr_t ptr_high)
+{
+
+  /* First heuristic is to check stack bounds */
+
+  if (__mf_opts.stack_bound)
+    {
+      TRACE ("mf: stack bound check on %p - %p\n", 
+	     ptr, ptr_high);
+      
+      uintptr_t stack_top_guess = (uintptr_t)__builtin_frame_address(0);
+      const uintptr_t stack_segment_base = 0xC0000000;
+      const uintptr_t stack_segment_top  = 0xBFFFC000;
+      
+      TRACE ("mf: stack estimated as %p - %p\n", 
+	     stack_top_guess, stack_segment_base);
+      
+      if (LIKELY(ptr >= stack_segment_top && 
+		 ptr <= stack_segment_base))
+	{
+	  if (UNLIKELY(ptr_high > stack_segment_base))
+	    {
+	      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 ("mf: no heuristics validate extent %p - %p\n", 
+	 ptr, ptr_high);
+    return 0;
+}
 
 void
 __mf_init_heuristics ()
Index: libmudflap/mf-hooks.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-hooks.c,v
retrieving revision 1.1.2.6
diff -u -r1.1.2.6 mf-hooks.c
--- libmudflap/mf-hooks.c	17 Aug 2002 00:52:35 -0000	1.1.2.6
+++ libmudflap/mf-hooks.c	20 Aug 2002 21:04:51 -0000
@@ -28,78 +28,130 @@
 
 /* XXX: if -DPIC, use dlsym-style wrapping instead */
 
+
+#define UNLIKELY(e) (__builtin_expect (!!(e), 0))
+#define LIKELY(e) (__builtin_expect (!!(e), 1))
+
+#define MF_VALIDATE_EXTENT(value,size)                        \
+ {                                                            \
+  struct __mf_cache * elem =                                  \
+    & __mf_lookup_cache [((unsigned)value >> __mf_lc_shift) & \
+			 __mf_lc_mask];                       \
+  if (UNLIKELY ((elem->low > (unsigned)value) ||              \
+		(elem->high < (unsigned)value+size)))         \
+    {                                                         \
+    mf_state resume_state = old_state;                        \
+    __mf_state = old_state;                                   \
+    __mf_check ((unsigned)value, size);                       \
+    old_state = resume_state;                                 \
+    }                                                         \
+ }
+
+
+#define BEGIN_PROTECT(ty, fname, ...)       \
+  ty result;                                \
+  mf_state old_state;                       \
+  if (UNLIKELY (__mf_state != active))      \
+    return __real_ ## fname (__VA_ARGS__);  \
+  else                                      \
+  {                                         \
+     TRACE_IN;                              \
+     old_state = __mf_state;                \
+     __mf_state = reentrant;                \
+  }
+
+#define END_PROTECT(ty, fname, ...)              \
+  result = (ty) __real_ ## fname (__VA_ARGS__);  \
+  __mf_state = old_state;                        \
+  TRACE_OUT;                                     \
+  return result;
+
+
+
 /* {{{ malloc/free etc. */
 void *
 __wrap_malloc (size_t c)
 {
-  char *buf;
   extern void * __real_malloc (size_t);
   size_t size_with_crumple_zomes;
 
-  if (UNLIKELY (!__mf_active_p))
-    return __real_malloc (c);
+  BEGIN_PROTECT (void *, malloc, c);
   
   size_with_crumple_zomes = c + (2 * __mf_opts.crumple_zone);
-  buf = (char *) __real_malloc (size_with_crumple_zomes);
+  result = (char *) __real_malloc (size_with_crumple_zomes);
+  
+  __mf_state = old_state;
   
-  if (buf)
+  if (LIKELY(result))
     {
-      buf += __mf_opts.crumple_zone;
-      __mf_register ((uintptr_t) buf, c,
+      result += __mf_opts.crumple_zone;
+      __mf_register ((uintptr_t) result, c,
 		     __MF_TYPE_HEAP, "malloc region");
     }
-  
-  return buf;
+
+  TRACE_OUT;
+  return result;
 }
 
 
 void *
 __wrap_calloc (size_t c, size_t n)
 {
-  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);
+  BEGIN_PROTECT (char *, calloc, c, n);
   
   size_with_crumple_zones = (c * n) + (2 * __mf_opts.crumple_zone);  
-  buf = (char *) __real_malloc (size_with_crumple_zones);
-
-  if (buf)
+  result = (char *) __real_malloc (size_with_crumple_zones);
+  
+  if (LIKELY(result))
+    __real_memset (result, 0, size_with_crumple_zones);
+  
+  __mf_state = old_state;
+  
+  if (LIKELY(result))
     {
-      __real_memset (buf, 0, size_with_crumple_zones);
-      buf += __mf_opts.crumple_zone;
-      __mf_register ((uintptr_t) buf, c*n, 
+      result += __mf_opts.crumple_zone;
+      __mf_register ((uintptr_t) result, c*n, 
 		     __MF_TYPE_HEAP, "calloc region");
     }
-  return buf;
+  
+  TRACE_OUT;
+  return result;
 }
 
 void *
 __wrap_realloc (void *buf, size_t c)
 {
-  char *buf2;
   extern void * __real_realloc (void *, size_t);
   size_t size_with_crumple_zones;
+  char *base = buf;
+
+  BEGIN_PROTECT (char *, realloc, buf, c);
 
-  if (UNLIKELY (!__mf_active_p))
-    return __real_realloc (buf,c);
+  if (LIKELY(buf))
+    base -= __mf_opts.crumple_zone;
 
   size_with_crumple_zones = c + (2 * __mf_opts.crumple_zone);
-  buf2 = (void *) __real_realloc (buf, size_with_crumple_zones);
-  if (buf)
+  result = (char *) __real_realloc (base, size_with_crumple_zones);
+
+  __mf_state = old_state;      
+
+  if (LIKELY(buf))
     __mf_unregister ((uintptr_t) buf, 0);
-  if (buf2)
+  
+  if (LIKELY(result))
     {
-      buf2 += __mf_opts.crumple_zone;
-      __mf_register ((uintptr_t) buf2, c, 
+      result += __mf_opts.crumple_zone;
+      __mf_register ((uintptr_t) result, c, 
 		     __MF_TYPE_HEAP, "realloc region");
     }
 
-  return buf2;
+  TRACE_OUT;
+  return result;
 }
 
 
@@ -109,21 +161,26 @@
   /* Use a circular queue to delay some number (__mf_opts.free_queue_length) of free()s.  */
   static void *free_queue [__MF_FREEQ_MAX];
   static unsigned free_ptr;
-
+  mf_state old_state;
   extern void * __real_free (void *);
 
-  if (UNLIKELY (!__mf_active_p))
+  if (UNLIKELY (__mf_state != active))
     {
       __real_free (buf);
       return;
     }
 
-  if (buf == NULL)
+  if (UNLIKELY(buf == NULL))
     return;
 
+  TRACE_IN;
+
   __mf_unregister ((uintptr_t) buf, 0);
+
+  old_state = __mf_state;
+  __mf_state = reentrant;
       
-  if (__mf_opts.free_queue_length > 0) 
+  if (UNLIKELY(__mf_opts.free_queue_length > 0))
     {
       
       if (free_queue [free_ptr] != NULL)
@@ -153,32 +210,23 @@
 	}
       __real_free (base);
     }
+  
+  __mf_state = old_state;
+  TRACE_OUT;
 }
 
 
 /* }}} */
 /* {{{ str*,mem*,b* */
 
-#define UNLIKELY(e) (__builtin_expect (!!(e), 0))
-#define LIKELY(e) (__builtin_expect (!!(e), 1))
-
-#define MF_VALIDATE_EXTENT(value,size)                        \
- {                                                            \
-  struct __mf_cache * elem =                                  \
-    & __mf_lookup_cache [((unsigned)value >> __mf_lc_shift) & \
-			 __mf_lc_mask];                       \
-  if (UNLIKELY ((elem->low > (unsigned)value) ||              \
-		(elem->high < (unsigned)value+size)))         \
-    __mf_check ((unsigned)value, size);                       \
- }
-
 void *
 __wrap_memcpy (void *dest, const void *src, size_t n)
 {
   extern void *__real_memcpy (void *dest, const void *src, size_t n);
+  BEGIN_PROTECT(void *, memcpy, dest, src, n);
   MF_VALIDATE_EXTENT(src, n);
   MF_VALIDATE_EXTENT(dest, n);
-  return __real_memcpy (dest, src, n);
+  END_PROTECT (void *, memcpy, dest, src, n);
 }
 
 
@@ -187,9 +235,10 @@
 __wrap_memmove (void *dest, const void *src, size_t n)
 {
   extern void *__real_memmove (void *dest, const void *src, size_t n);
+  BEGIN_PROTECT(void *, memmove, dest, src, n);
   MF_VALIDATE_EXTENT(src, n);
   MF_VALIDATE_EXTENT(dest, n);
-  return __real_memmove (dest, src, n);
+  END_PROTECT(void *, memmove, dest, src, n);
 }
 
 
@@ -197,33 +246,37 @@
 __wrap_memset (void *s, int c, size_t n) 
 {
   extern void *__real_memset (void *s, int c, size_t n);
+  BEGIN_PROTECT(void *, memset, s, c, n);
   MF_VALIDATE_EXTENT(s, n);
-  return __real_memset (s, c, n);
+  END_PROTECT(void *, memset, s, c, n);
 }
 
 int
 __wrap_memcmp (const void *s1, const void *s2, size_t n)
 {
   extern int __real_memcmp (const void *s1, const void *s2, size_t n);
+  BEGIN_PROTECT(int, memcmp, s1, s2, n);
   MF_VALIDATE_EXTENT(s1, n);
   MF_VALIDATE_EXTENT(s2, n);
-  return __real_memcmp (s1, s2, n);
+  END_PROTECT(int, memcmp, s1, s2, n);
 }
 
 void *
 __wrap_memchr (const void *s, int c, size_t n)
 {
   extern void *__real_memchr (const void *s, int c, size_t n);
+  BEGIN_PROTECT(void *, memchr, s, c, n);
   MF_VALIDATE_EXTENT(s, n);
-  return __real_memchr (s, c, n);
+  END_PROTECT(void *, memchr, s, c, n);
 }
 
 void *
 __wrap_memrchr (const void *s, int c, size_t n)
 {
   extern void *__real_memrchr (const void *s, int c, size_t n);
+  BEGIN_PROTECT(void *, memrchr, s, c, n);
   MF_VALIDATE_EXTENT(s, n);
-  return __real_memrchr (s, c, n);
+  END_PROTECT(void *, memrchr, s, c, n);
 }
 
 
@@ -231,42 +284,52 @@
 __wrap_strcpy (char *dest, const char *src)
 {
   extern char *__real_strcpy (char *dest, const char *src);
-  int n = __real_strlen (src);
+  int n;
 
   /* nb: just because strlen(src) == n doesn't mean (src + n) or (src + n +
      1) are valid pointers. the allocated object might have size < n.
      check anyways. */
 
+  BEGIN_PROTECT(char *, strcpy, dest, src); 
+  TRACE("mf: strcpy %p %s-> %p\n", src, dest);
+  n = __real_strlen (src);
   MF_VALIDATE_EXTENT(src, (n + 1)); 
   MF_VALIDATE_EXTENT(dest, (n + 1));
-  return __real_strcpy (dest, src);
+  END_PROTECT(char *, strcpy, dest, src);
 }
 
 char *
 __wrap_strncpy (char *dest, const char *src, size_t n)
 {
   extern char *__real_strncpy (char *dest, const char *src, size_t n);
-  int len = __real_strnlen (src, n);
+  int len;
+
+  BEGIN_PROTECT(char *, strncpy, dest, src, n);
+  TRACE("mf: strncpy %d chars %p %s -> %p\n", n, src, dest);
+  len = __real_strnlen (src, n);
   MF_VALIDATE_EXTENT(src, len);
-  MF_VALIDATE_EXTENT(dest, (len + 1));
-  return __real_strncpy (dest, src, n);
+  MF_VALIDATE_EXTENT(dest, len); /* nb: strNcpy */
+  END_PROTECT(char *, strncpy, dest, src, n);
 }
 
 char *
 __wrap_strcat (char *dest, const char *src)
 {
   extern char *__real_strcat (char *dest, const char *src);
-  int dest_sz = __real_strlen (dest);
-  int src_sz = __real_strlen (src);  
+  int dest_sz;
+  int src_sz;
+
+  BEGIN_PROTECT(char *, strcat, dest, src);
+  dest_sz = __real_strlen (dest);
+  src_sz = __real_strlen (src);  
   MF_VALIDATE_EXTENT(src, (src_sz + 1));
   MF_VALIDATE_EXTENT(dest, (dest_sz + src_sz + 1));
-  return __real_strcat (dest, src);
+  END_PROTECT(char *, strcat, dest, src);
 }
 
 char *
 __wrap_strncat (char *dest, const char *src, size_t n)
 {
-  extern char *__real_strncat (char *dest, const char *src, size_t n);
 
   /* nb: validating the extents (s,n) might be a mistake for two reasons.
      
@@ -288,66 +351,105 @@
   this same logic applies to further uses of strnlen later down in this
   file. */
 
-  int src_sz = __real_strnlen (src, n);
-  int dest_sz = __real_strnlen (dest, n);
+  extern char *__real_strncat (char *dest, const char *src, size_t n);
+  int src_sz;
+  int dest_sz;
+
+  BEGIN_PROTECT(char *, strncat, dest, src, n);
+  src_sz = __real_strnlen (src, n);
+  dest_sz = __real_strnlen (dest, n);
   MF_VALIDATE_EXTENT(src, src_sz);
   MF_VALIDATE_EXTENT(dest, (dest_sz + src_sz + 1));
-  return __real_strncat (dest, src, n);
+  END_PROTECT(char *, strncat, dest, src, n);
 }
 
 int
 __wrap_strcmp (const char *s1, const char *s2)
 {
   extern int __real_strcmp (const char *s1, const char *s2);
-  int s1_sz = __real_strlen (s1);
-  int s2_sz = __real_strlen (s2);  
+  int s1_sz;
+  int s2_sz;
+
+  BEGIN_PROTECT(int, strcmp, s1, s2);
+  s1_sz = __real_strlen (s1);
+  s2_sz = __real_strlen (s2);  
   MF_VALIDATE_EXTENT(s1, s1_sz+1);
   MF_VALIDATE_EXTENT(s2, s2_sz+1);
-  return __real_strcmp (s1, s2);
+  END_PROTECT(int, strcmp, s1, s2);
 }
 
 int
 __wrap_strcasecmp (const char *s1, const char *s2)
 {
   extern int __real_strcasecmp (const char *s1, const char *s2);
-  int s1_sz = __real_strlen (s1);
-  int s2_sz = __real_strlen (s2);  
+  int s1_sz;
+  int s2_sz;
+
+  BEGIN_PROTECT(int, strcasecmp, s1, s2);
+  s1_sz = __real_strlen (s1);
+  s2_sz = __real_strlen (s2);  
   MF_VALIDATE_EXTENT(s1, s1_sz+1);
   MF_VALIDATE_EXTENT(s2, s2_sz+1);
-  return __real_strcasecmp (s1, s2);
+  END_PROTECT(int, strcasecmp, s1, s2);
 }
 
 int
 __wrap_strncmp (const char *s1, const char *s2, size_t n)
 {
   extern int __real_strncmp (const char *s1, const char *s2, size_t n);
-  int s1_sz = __real_strnlen (s1, n);
-  int s2_sz = __real_strnlen (s2, n);
+  int s1_sz;
+  int s2_sz;
+
+  BEGIN_PROTECT(int, strncmp, s1, s2, n);
+  s1_sz = __real_strnlen (s1, n);
+  s2_sz = __real_strnlen (s2, n);
   MF_VALIDATE_EXTENT(s1, s1_sz);
   MF_VALIDATE_EXTENT(s2, s2_sz);
-  return __real_strncmp (s1, s2, n);
+  END_PROTECT(int, strncmp, s1, s2, n);
 }
 
 int
 __wrap_strncasecmp (const char *s1, const char *s2, size_t n)
 {
   extern int __real_strncasecmp (const char *s1, const char *s2, size_t n);
-  int s1_sz = __real_strnlen (s1, n);
-  int s2_sz = __real_strnlen (s2, n);
+  int s1_sz;
+  int s2_sz;
+
+  BEGIN_PROTECT(int, strncasecmp, s1, s2, n);
+  s1_sz = __real_strnlen (s1, n);
+  s2_sz = __real_strnlen (s2, n);
   MF_VALIDATE_EXTENT(s1, s1_sz);
   MF_VALIDATE_EXTENT(s2, s2_sz);
-  return __real_strncasecmp (s1, s2, n);
+  END_PROTECT(int, strncasecmp, s1, s2, n);
 }
 
 char *
 __wrap_strdup (const char *s)
 {
   extern char *__real_strdup (const char *s);
-  int n = __real_strlen (s);
-  char *result;
+  extern void *__real_malloc (size_t sz);
+  int n;
+
+  BEGIN_PROTECT(char *, strdup, s);
+  n = __real_strlen (s);
   MF_VALIDATE_EXTENT(s, n+1);
-  result = __real_strdup (s);
-  __mf_register ((uintptr_t) result, n, __MF_TYPE_HEAP, "strdup region");
+
+  result = (char *)__real_malloc (n+1 + 2*(__mf_opts.crumple_zone));
+
+  if (UNLIKELY(!result))
+    {
+      __mf_state = old_state;
+      TRACE_OUT;
+      return result;
+    }
+
+  result += __mf_opts.crumple_zone;
+  __real_memcpy (result, s, n);
+  result[n] = '\0';
+
+  __mf_register ((uintptr_t) result, n+1, __MF_TYPE_HEAP, "strdup region");
+  __mf_state = old_state;
+  TRACE_OUT;
   return result;
 }
 
@@ -355,11 +457,30 @@
 __wrap_strndup (const char *s, size_t n)
 {
   extern char *__real_strndup (const char *s, size_t n);
-  char *result;
-  int sz = __real_strnlen (s, n);
-  MF_VALIDATE_EXTENT(s, sz);
-  result = __real_strndup (s, n);
-  __mf_register ((uintptr_t) result, sz, __MF_TYPE_HEAP, "strndup region");
+  extern void *__real_malloc (size_t sz);
+  int sz;
+
+  BEGIN_PROTECT(char *, strndup, s, n);
+  sz = __real_strnlen (s, n);
+  MF_VALIDATE_EXTENT(s, sz); /* nb: strNdup */
+
+  /* note: strndup still adds a \0, even with the N limit! */
+  result = (char *)__real_malloc (n+1 + 2*(__mf_opts.crumple_zone));
+
+  if (UNLIKELY(!result))
+    {
+      __mf_state = old_state;
+      TRACE_OUT;
+      return result;
+    }
+
+  result += __mf_opts.crumple_zone;
+  __real_memcpy (result, s, n);
+  result[n] = '\0';
+
+  __mf_register ((uintptr_t) result, n+1, __MF_TYPE_HEAP, "strndup region");
+  __mf_state = old_state;
+  TRACE_OUT;
   return result;
 }
 
@@ -368,18 +489,24 @@
 __wrap_strchr (const char *s, int c)
 {
   extern char *__real_strchr (const char *s, int c);
-  int n = __real_strlen (s);
+  int n;
+
+  BEGIN_PROTECT(char *, strchr, s, c);
+  n = __real_strlen (s);
   MF_VALIDATE_EXTENT(s, n+1);
-  return __real_strchr (s, c);
+  END_PROTECT(char *, strchr, s, c);
 }
 
 char *
 __wrap_strrchr (const char *s, int c)
 {
   extern char *__real_strrchr (const char *s, int c);
-  int n = __real_strlen (s);
+  int n;
+
+  BEGIN_PROTECT(char *, strrchr, s, c);
+  n = __real_strlen (s);
   MF_VALIDATE_EXTENT(s, n+1);
-  return __real_strrchr (s, c);
+  END_PROTECT(char *, strrchr, s, c);
 }
 
 
@@ -387,11 +514,15 @@
 __wrap_strstr (const char *haystack, const char *needle)
 {
   extern char *__real_strstr (const char *haystack, const char *needle);
-  int haystack_sz = __real_strlen (haystack);
-  int needle_sz = __real_strlen (needle);
+  int haystack_sz;
+  int needle_sz;
+
+  BEGIN_PROTECT(char *, strstr, haystack, needle);
+  haystack_sz = __real_strlen (haystack);
+  needle_sz = __real_strlen (needle);
   MF_VALIDATE_EXTENT(haystack, haystack_sz+1);
   MF_VALIDATE_EXTENT(needle, needle_sz+1);
-  return __real_strstr (haystack, needle);
+  END_PROTECT(char *, strstr, haystack, needle);
 }
 
 
@@ -401,71 +532,115 @@
 {
   extern void *__real_memmem (const void *haystack, size_t haystacklen,
 			      const void *needle, size_t needlelen);
+
+  BEGIN_PROTECT(void *, memmem, haystack, haystacklen, needle, needlelen);
   MF_VALIDATE_EXTENT(haystack, haystacklen);
   MF_VALIDATE_EXTENT(needle, needlelen);
-  return __real_memmem (haystack, haystacklen, needle, needlelen);
+  END_PROTECT(char *, memmem, haystack, haystacklen, needle, needlelen);
 }
 
 int
 __wrap_strlen (const char *s)
 {
   extern int __real_strlen (const char *s);
-  int n = __real_strlen (s);
-  MF_VALIDATE_EXTENT(s, n+1);
-  return n;
+
+  BEGIN_PROTECT(int, strlen, s);
+  result = __real_strlen (s);
+  MF_VALIDATE_EXTENT(s, result+1);
+  __mf_state = old_state;
+  TRACE_OUT;
+  return result;
 }
 
 int
 __wrap_strnlen (const char *s, size_t n)
 {
   extern int __real_strnlen (const char *s, size_t n);
-  int m = __real_strnlen (s, n);
-  MF_VALIDATE_EXTENT(s, m);
-  return m;
+
+  BEGIN_PROTECT(int, strnlen, s, n);
+  result = __real_strnlen (s, n);
+  MF_VALIDATE_EXTENT(s, result);
+  __mf_state = old_state;
+  TRACE_OUT;
+  return result;
 }
 
 void
 __wrap_bzero (void *s, size_t n)
 {
   extern void __real_bzero (void *s, size_t n);
+  mf_state old_state;
+
+  if (UNLIKELY (__mf_state != active))
+    {
+      __real_bzero (s, n);
+      return;
+    }
+  TRACE_IN;
+  old_state = __mf_state;
+  __mf_state = reentrant;
   MF_VALIDATE_EXTENT(s, n);
-  return __real_bzero (s, n);
+  __real_bzero (s, n);
+  __mf_state = old_state;
+  TRACE_OUT;
 }
 
 void
 __wrap_bcopy (const void *src, void *dest, size_t n)
 {
   extern void __real_bcopy (const void *src, void *dest, size_t n);
+  mf_state old_state;
+
+  if (UNLIKELY (__mf_state != active))
+    {
+      __real_bcopy (src, dest, n);
+      return;
+    }
+  TRACE_IN;
+  old_state = __mf_state;
+  __mf_state = reentrant;
   MF_VALIDATE_EXTENT(src, n);
   MF_VALIDATE_EXTENT(dest, n);
-  return __real_bcopy (src, dest, n);
+  __real_bcopy (src, dest, n);
+  __mf_state = old_state;
+  TRACE_OUT;
 }
 
 int
 __wrap_bcmp (const void *s1, const void *s2, size_t n)
 {
   extern int __real_bcmp (const void *s1, const void *s2, size_t n);
+
+  BEGIN_PROTECT(int, bcmp, s1, s2, n);
   MF_VALIDATE_EXTENT(s1, n);
   MF_VALIDATE_EXTENT(s2, n);
-  return __real_bcmp (s1, s2, n);
+  END_PROTECT(int, bcmp, s1, s2, n);
 }
 
 char *
 __wrap_index (const char *s, int c)
 {
   extern char *__real_index (const char *s, int c);
-  int n = __real_strlen (s);
+  int n;
+
+  BEGIN_PROTECT(char *, index, s, c);
+  n = __real_strlen (s);
   MF_VALIDATE_EXTENT(s, n+1);
-  return __real_index (s, c);
+  END_PROTECT(char *, index, s, c);
 }
 
+
+
 char *
 __wrap_rindex (const char *s, int c)
 {
   extern char *__real_rindex (const char *s, int c);
-  int n = __real_strlen (s);
+  int n;
+
+  BEGIN_PROTECT(char *, rindex, s, c);
+  n = __real_strlen (s);
   MF_VALIDATE_EXTENT(s, n+1);
-  return __real_rindex (s, c);
+  END_PROTECT(char *, rindex, s, c);
 }
 
 /* 
@@ -477,7 +652,9 @@
 {
   extern void __real_ ();
   MF_VALIDATE_EXTENT();
-  return __real_ ();
+  result = __real_ ();
+  __mf_state = old_state;
+  return result;
 }
 
 */
Index: libmudflap/mf-runtime.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-runtime.c,v
retrieving revision 1.1.2.5
diff -u -r1.1.2.5 mf-runtime.c
--- libmudflap/mf-runtime.c	20 Aug 2002 16:56:01 -0000	1.1.2.5
+++ libmudflap/mf-runtime.c	20 Aug 2002 21:04:51 -0000
@@ -55,7 +55,19 @@
 
 struct __mf_options __mf_opts;
 
-int __mf_active_p = 0;
+mf_state __mf_state = inactive;
+
+#define BEGIN_RECURSION_PROTECT           \
+  mf_state old_state;                     \
+  if (UNLIKELY (__mf_state == reentrant)) \
+    return;                               \
+  old_state = __mf_state;                 \
+  __mf_state = reentrant;
+
+#define END_RECURSION_PROTECT             \
+  __mf_state = old_state;
+
+
 
 static void
 __mf_set_default_options ()
@@ -67,6 +79,7 @@
   __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;
@@ -142,6 +155,10 @@
      "support /proc/self/map heuristics",
      set_option, 1, &__mf_opts.heur_proc_map},
 
+    {"stack-bound",
+     "enable a simple upper stack bound heuristic",
+     set_option, 1, &__mf_opts.stack_bound},
+     
     {"free-queue-length", 
      "queue N deferred free() calls before performing them",
      read_integer_option, 0, &__mf_opts.free_queue_length},
@@ -223,6 +240,7 @@
       case '-':
 	if (*optstr+1)
 	  {	    
+	    int negate = 0;
 	    optstr++;
 
 	    if (*optstr == '?' || strcmp (optstr, "help") == 0)
@@ -230,19 +248,18 @@
 		__mf_usage ();
 		exit (0);
 	      }
+
+	    
+	    if (strncmp (optstr, "no-", 3) == 0)
+	      {
+		negate = 1;
+		optstr = & optstr[3];
+	      }
 	    
 	    for (opts = options; opts->name; opts++)
 	      {
-		int negate = 0;
-
-		if (strncmp (optstr, "no-", 3) == 0)
-		  {
-		    negate = 1;
-		    optstr = & optstr[3];
-		  }
-
 		if (strncmp (optstr, opts->name, 
-				     strlen (opts->name)) == 0)
+			     strlen (opts->name)) == 0)
 		  {
 		    optstr += strlen (opts->name);
 		    assert (opts->target);
@@ -294,6 +311,8 @@
 {
   char *ov = 0;
 
+  __mf_state = starting;
+
   __mf_set_default_options ();
 
   ov = getenv ("MUDFLAP_OPTIONS");
@@ -309,10 +328,10 @@
 	}
     }
 
-  __mf_active_p = 1;
-
   __mf_init_heuristics ();
 
+  __mf_state = active;
+
   TRACE_OUT;
 }
 
@@ -414,8 +433,6 @@
 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;
-
 static __mf_object_tree_t *__mf_find_object (uintptr_t low, uintptr_t high);
 static unsigned __mf_find_objects (uintptr_t ptr_low, uintptr_t ptr_high, 
 				   __mf_object_tree_t **objs, unsigned max_objs);
@@ -435,14 +452,10 @@
   struct __mf_cache *entry = & __mf_lookup_cache [entry_idx];
   int violation_p = 0;
   uintptr_t ptr_high = CLAMPSZ (ptr, sz);
-  static unsigned recursion = 0;
 
   struct __mf_cache old_entry = *entry;
 
-  if (UNLIKELY (! __mf_active_p)) return;
-
-  if (UNLIKELY (recursion)) return;
-  recursion ++;
+  BEGIN_RECURSION_PROTECT;
   
   switch (__mf_opts.mudflap_mode)
     {
@@ -467,8 +480,11 @@
 	  }
 	else
 	  {
-	    /* XXX:  */
-	    violation_p = 1;
+	    if (! __mf_heuristic_check (ptr, ptr_high))
+	      {	      
+		/* XXX:  */
+		violation_p = 1;
+	      }
 	  }
       }    
       break;
@@ -486,14 +502,13 @@
 	/* && (old_entry.low != 0) && (old_entry.high != 0)) */
 	__mf_lookup_cache_reusecount [entry_idx] ++;    
     }
-
-  if (__mf_opts.trace_mf_calls)
-    fprintf (stderr, "mf chk p=%08lx s=%lu\n", ptr, sz);
-
+  
+  TRACE ("mf: check p=%p s=%lu viol=%d\n", (void *)ptr, sz, violation_p);
+  END_RECURSION_PROTECT;
+  
   if (UNLIKELY (violation_p))
-    __mf_violation (ptr, sz, (uintptr_t) __builtin_return_address (0), __MF_VIOL_CHECK);
-
-  recursion --;
+    __mf_violation (ptr, sz, (uintptr_t) __builtin_return_address (0), 
+		    __MF_VIOL_CHECK);
 }
 
 /* }}} */
@@ -556,11 +571,11 @@
 void
 __mf_register (uintptr_t ptr, uintptr_t sz, int type, const char *name)
 {
-  if (UNLIKELY (! __mf_active_p)) return;
 
-  if (__mf_opts.trace_mf_calls)
-    fprintf (stderr, "mf reg p=%08lx s=%lu t=%d n=`%s'\n", 
-	     ptr, sz, type, name ? name : "");
+  if (UNLIKELY (!(__mf_state == active || __mf_state == starting))) return;
+
+  TRACE("mf: reg p=%p s=%lu t=%d n='%s'\n", (void *)ptr, sz, 
+	type, name ? name : "");
 
   switch (__mf_opts.mudflap_mode)
     {
@@ -582,13 +597,11 @@
 	__mf_object_tree_t *ovr_obj[1];
 	__mf_object_tree_t *new_obj;
 	unsigned num_overlapping_objs;
-	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 ++;
+	BEGIN_RECURSION_PROTECT;
 	
 	/* Treat unknown size indication as 1.  */
 	if (UNLIKELY (sz == 0)) sz = 1;
@@ -606,13 +619,15 @@
 		ovr_obj[0]->data.high == high)
 	      {
 		/* do nothing */
-		recursion --;
+		TRACE ("mf: duplicate static reg %p\n", (void *)low);
+		END_RECURSION_PROTECT;
 		return;
 	      }
 	    else if (type == __MF_TYPE_GUESS)
 	      {
 		/* do nothing, someone has beat us here. */
-		recursion --;
+		TRACE ("mf: existing guessed reg %p\n", (void *)low);
+		END_RECURSION_PROTECT;
 		return;
 	      }
 	    else
@@ -641,18 +656,14 @@
 
 			guess2_low = CLAMPADD (high, (1 + __mf_opts.crumple_zone));
 			guess2_high = ovr_obj[i]->data.high;
+
+			TRACE("mf: splitting guess region %p-%p\n", 
+			      guess1_low, guess2_high);
+		    
 			/* NB: split regions may disappear if low > high. */
-			
-			if (__mf_opts.trace_mf_calls)
-			  {
-			    fprintf (stderr, 
-				     "mf: splitting guess region %08lx-%08lx\n",
-				     guess1_low, guess2_high);
-			  }
 
-			__mf_unlink_object (ovr_obj[i]);
+			__mf_remove_old_object (ovr_obj[i]);
 			__real_free (ovr_obj[i]->data.alloc_backtrace);
-			/* __real_free (ovr_obj[i]->data.dealloc_backtrace); */
 			__real_free (ovr_obj[i]);
 			ovr_obj[i] = NULL;
 
@@ -675,6 +686,7 @@
 		    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),
 			   __MF_VIOL_REGISTER);
@@ -688,7 +700,7 @@
 	/* We could conceivably call __mf_check() here to prime the cache,
 	   but then the check_count field is not reliable.  */
 	
-	recursion --;	
+	END_RECURSION_PROTECT;
 	break;
       }
 
@@ -712,7 +724,7 @@
 
   extern void  __real_free (void *);
 
-  if (UNLIKELY (! __mf_active_p)) return;
+  BEGIN_RECURSION_PROTECT;
 
   switch (__mf_opts.mudflap_mode)
     { 
@@ -736,10 +748,7 @@
 	__mf_object_tree_t *del_obj = NULL;  /* Object to actually delete. */
 	__mf_object_tree_t *objs[1] = {NULL};
 	unsigned num_overlapping_objs;
-	
-	if (UNLIKELY (recursion)) return;
-	recursion ++;
-	
+		
 	/* Treat unknown size indication as 1.  */
 	if (sz == 0) sz = 1;
 	
@@ -752,29 +761,26 @@
 	    {
 	      if (objs[i]->data.type == __MF_TYPE_GUESS)
 		{
-		  recursion--;
+		  TRACE("mf: ignored guess unreg %p\n", objs[i]->data.low); 		  
+		  END_RECURSION_PROTECT;
 		  return;
 		}
-	    }
-	    
+	    }	    
 	}
 
 	if (UNLIKELY (num_overlapping_objs != 1))
 	  {
 	    /* XXX: also: should match ptr == old_obj->low ? */
-	    
+	    TRACE("mf: unreg viol %p\n", (void *)ptr);
+	    END_RECURSION_PROTECT;
 	    __mf_violation (ptr, sz, (uintptr_t) __builtin_return_address (0),
 			    __MF_VIOL_UNREGISTER);
-	    recursion --;
 	    return;
 	  }
 	
 	old_obj = objs[0];
 
-	if (__mf_opts.trace_mf_calls)
-	  {
-	    fprintf (stderr, "mf: removing region %08lx-%08lx\n", old_obj->data.low, old_obj->data.high); 
-	  }
+	TRACE("mf: removing %p-%p\n", old_obj->data.low, old_obj->data.high); 
 
 	__mf_remove_old_object (old_obj);
 	
@@ -839,7 +845,6 @@
 	    __real_free (del_obj);
 	  }
 	
-	recursion --;
 	break;
       }
     } /* end switch (__mf_opts.mudflap_mode) */
@@ -851,8 +856,8 @@
       __mf_total_unregister_size += sz;
     }
 
-  if (__mf_opts.trace_mf_calls)    
-    fprintf (stderr, "mf unr p=%08lx s=%lu\n", ptr, sz);
+  TRACE("mf: unr p=%p s=%lu\n", (void *)ptr, sz);
+  END_RECURSION_PROTECT;
 }
 
 /* }}} */
@@ -1008,7 +1013,7 @@
   __mf_object_tree_t* objects[1]; /* Find at most one.  */
   unsigned count;
 
-  if (__mf_opts.internal_checking)
+  if (UNLIKELY(__mf_opts.internal_checking))
     __mf_validate_objects ();
 
   count = __mf_find_objects_rec (low, high, & __mf_object_root, objects, 1);
@@ -1023,7 +1028,7 @@
 __mf_find_objects (uintptr_t ptr_low, uintptr_t ptr_high,
 		   __mf_object_tree_t **objs, unsigned max_objs)
 {
-  if (__mf_opts.internal_checking)
+  if (UNLIKELY(__mf_opts.internal_checking))
     __mf_validate_objects ();
 
   return __mf_find_objects_rec (ptr_low, ptr_high, & __mf_object_root, objs, max_objs);
@@ -1038,7 +1043,7 @@
   __mf_object_tree_t *node = *link;
 
   assert (ptr != NULL);
-  if (node == NULL) 
+  if (UNLIKELY(node == NULL))
     {
       *link = ptr;
       return;
@@ -1056,7 +1061,7 @@
 void
 __mf_link_object (__mf_object_tree_t *ptr)
 {
-  if (__mf_opts.internal_checking)
+  if (UNLIKELY(__mf_opts.internal_checking))
     __mf_validate_objects ();
 
   return __mf_link_object2 (ptr, & __mf_object_root);
@@ -1071,7 +1076,7 @@
   __mf_object_tree_t *node = *link;
   
   assert (ptr != NULL);
-  if (node == ptr) 
+  if (UNLIKELY(node == ptr))
     {
       static unsigned promote_left_p = 0;
       promote_left_p = 1 - promote_left_p;
@@ -1178,7 +1183,8 @@
 static void
 __mf_describe_object (__mf_object_t *obj)
 {
-  if (UNLIKELY (! __mf_active_p)) return;
+
+  if (UNLIKELY (__mf_state != active)) return;
 
   fprintf (stderr,
 	   "mudflap object %08lx: name=`%s'\n"
@@ -1246,7 +1252,7 @@
 __mf_report ()
 {
 
-  if (UNLIKELY (! __mf_active_p)) return;
+  if (UNLIKELY (__mf_state == active)) return;
 
   if (__mf_opts.collect_stats)
     {
@@ -1320,10 +1326,9 @@
   static unsigned violation_number;
   extern void  __real_free (void *);
 
-  if (UNLIKELY (! __mf_active_p)) return;
+  BEGIN_RECURSION_PROTECT;
 
-  if (__mf_opts.trace_mf_calls)
-    fprintf (stderr, "mf violation pc=%08lx type=%d\n", pc, type);
+  TRACE("mf: violation pc=%p type=%d ptr=%p sz=%d\n", pc, type, ptr, sz);
 
   if (__mf_opts.collect_stats)
     __mf_count_violation [(type < 0) ? 0 :
@@ -1432,7 +1437,6 @@
   switch (__mf_opts.violation_mode)
     {
     case viol_nop:
-      return;
       break;
     case viol_segv:
       kill (getpid(), SIGSEGV);
@@ -1445,6 +1449,8 @@
       system (buf);
       break;
     }
+  
+  END_RECURSION_PROTECT;
 }
 
 /* }}} */
Index: libmudflap/mf-runtime.h
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-runtime.h,v
retrieving revision 1.1.2.4
diff -u -r1.1.2.4 mf-runtime.h
--- libmudflap/mf-runtime.h	20 Aug 2002 16:56:01 -0000	1.1.2.4
+++ libmudflap/mf-runtime.h	20 Aug 2002 21:04:51 -0000
@@ -12,7 +12,9 @@
 extern struct __mf_cache __mf_lookup_cache [];
 extern uintptr_t __mf_lc_mask;
 extern unsigned char __mf_lc_shift;
-extern int __mf_active_p;
+
+typedef enum {inactive, starting, active, reentrant} mf_state;
+extern mf_state __mf_state;
 
 #define UNLIKELY(e) (__builtin_expect (!!(e), 0))
 #define LIKELY(e) (__builtin_expect (!!(e), 1))
@@ -39,13 +41,12 @@
 #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__);
+#define TRACE(...)                         \
+  if (UNLIKELY (__mf_opts.trace_mf_calls)) \
+      fprintf (stderr, __VA_ARGS__);
+
+#define TRACE_IN TRACE("mf: enter %s\n", __FUNCTION__)
+#define TRACE_OUT TRACE("mf: exit %s\n", __FUNCTION__)
 
 struct __mf_options
 {
@@ -69,6 +70,9 @@
 
   /* 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. */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]