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]


Just committed:

[ libmudflap/ChangeLog ]

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

	* mf-impl.h: New file, private implementation header.
	* mf-runtime.h: Reorganize a bit.
	(CLAMPSZ): Fix arithmetic.
	(__MF_CACHE_MISS_P): Fix arithmetic.
	* mf-runtime.c: Reorganize a bit.
	(__mf_dynamic): New structure.
	(resolve_single_dynamic): New function.
	(__mf_resolve_dynamics): New function.
	(__mf_init): Initialize dynamic wrappers.
	* mf-hooks.c: Macro-ize __real calls.
	Clamp various bits of arithmetic.
	Add explicit __mf_check call contexts.
	* Makefile.am: Add dependencies on mf-impl.h
	* Makefile.in: Regenerate.
	* configure.in: Comment out shared override.
	* configure: Regenerate.


Index: libmudflap/Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/Makefile.am,v
retrieving revision 1.1.2.4
diff -u -r1.1.2.4 Makefile.am
--- libmudflap/Makefile.am	20 Aug 2002 16:56:01 -0000	1.1.2.4
+++ libmudflap/Makefile.am	26 Aug 2002 23:17:42 -0000
@@ -50,9 +50,9 @@
 LIBMUDFLAP_INCLUDES =
 TOPLEVEL_INCLUDES =
 
-mf-runtime.o: mf-runtime.h
-mf-hooks.o: mf-runtime.h
-mf-heuristics.o: mf-runtime.h
+mf-runtime.o: mf-runtime.h mf-impl.h
+mf-hooks.o: mf-runtime.h mf-impl.h
+mf-heuristics.o: mf-runtime.h mf-impl.h
 
 libmudflap_la_SOURCES = \
 	mf-runtime.c \
Index: libmudflap/configure.in
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/configure.in,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 configure.in
--- libmudflap/configure.in	12 Aug 2002 21:09:48 -0000	1.1.2.1
+++ libmudflap/configure.in	26 Aug 2002 23:17:43 -0000
@@ -21,8 +21,8 @@
 AM_CONFIG_HEADER(config.h)
 
 # override for now
-enable_shared=no
-disable_shared=yes
+#enable_shared=no
+#disable_shared=yes
 
 AC_LIBTOOL_DLOPEN
 AM_PROG_LIBTOOL
Index: libmudflap/mf-heuristics.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-heuristics.c,v
retrieving revision 1.1.2.4
diff -u -r1.1.2.4 mf-heuristics.c
--- libmudflap/mf-heuristics.c	22 Aug 2002 20:36:36 -0000	1.1.2.4
+++ libmudflap/mf-heuristics.c	26 Aug 2002 23:17:43 -0000
@@ -11,6 +11,7 @@
 
 #include <stdio.h>
 #include "mf-runtime.h"
+#include "mf-impl.h"
 
 #ifdef _MUDFLAP
 #error "Do not compile this file with -fmudflap!"
@@ -131,7 +132,7 @@
 void
 __mf_init_heuristics ()
 {
-  mf_state old_state;
+  enum __mf_state old_state;
   old_state = __mf_state;
   __mf_state = starting;
   TRACE_IN;
Index: libmudflap/mf-hooks.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-hooks.c,v
retrieving revision 1.1.2.9
diff -u -r1.1.2.9 mf-hooks.c
--- libmudflap/mf-hooks.c	22 Aug 2002 20:36:36 -0000	1.1.2.9
+++ libmudflap/mf-hooks.c	26 Aug 2002 23:17:43 -0000
@@ -19,38 +19,32 @@
 #include <assert.h>
 
 #include "mf-runtime.h"
-
+#include "mf-impl.h"
 
 #ifdef _MUDFLAP
 #error "Do not compile this file with -fmudflap!"
 #endif
 
-
-/* XXX: if -DPIC, use dlsym-style wrapping instead */
-
-
-#define UNLIKELY(e) (__builtin_expect (!!(e), 0))
-#define LIKELY(e) (__builtin_expect (!!(e), 1))
-
-#define STRINGIFY2(e) #e
-#define STRINGIFY(e) STRINGIFY2(e)
-#define MF_VALIDATE_EXTENT(value,size)                        \
+#define MF_VALIDATE_EXTENT(value,size,context)                \
  {                                                            \
   if (UNLIKELY (__MF_CACHE_MISS_P (value, size)))             \
     {                                                         \
-    mf_state resume_state = old_state;                        \
+    enum __mf_state resume_state = old_state;                 \
     __mf_state = old_state;                                   \
-    __mf_check ((unsigned)value, size, __FILE__ ":" STRINGIFY(__LINE__) " (" __PRETTY_FUNCTION__ ")" );                       \
+    __mf_check ((unsigned)value, size, __FILE__ ":" STRINGIFY(__LINE__) " (" context ")");  \
     old_state = resume_state;                                 \
     }                                                         \
  }
 
 
+
 #define BEGIN_PROTECT(ty, fname, ...)       \
   ty result;                                \
-  mf_state old_state;                       \
+  enum __mf_state old_state;                \
   if (UNLIKELY (__mf_state != active))      \
-    return __real_ ## fname (__VA_ARGS__);  \
+  {                                         \
+    return CALL_REAL(fname, __VA_ARGS__);   \
+  }                                         \
   else                                      \
   {                                         \
      TRACE_IN;                              \
@@ -59,7 +53,7 @@
   }
 
 #define END_PROTECT(ty, fname, ...)              \
-  result = (ty) __real_ ## fname (__VA_ARGS__);  \
+  result = (ty) CALL_REAL(fname, __VA_ARGS__);   \
   __mf_state = old_state;                        \
   TRACE_OUT;                                     \
   return result;
@@ -69,15 +63,16 @@
 /* {{{ malloc/free etc. */
 
 void *
-__wrap_malloc (size_t c)
+WRAPPER(malloc) (size_t c)
 {
-  extern void * __real_malloc (size_t);
-  size_t size_with_crumple_zomes;
-
+  size_t size_with_crumple_zones;
+  DECLARE(void *, malloc, size_t c);
   BEGIN_PROTECT (void *, malloc, c);
   
-  size_with_crumple_zomes = c + (2 * __mf_opts.crumple_zone);
-  result = (char *) __real_malloc (size_with_crumple_zomes);
+  size_with_crumple_zones = 
+    CLAMPADD(c,CLAMPADD(__mf_opts.crumple_zone,
+			__mf_opts.crumple_zone));
+  result = (char *) CALL_REAL(malloc, size_with_crumple_zones);
   
   __mf_state = old_state;
   
@@ -94,27 +89,29 @@
 
 
 void *
-__wrap_calloc (size_t c, size_t n)
+WRAPPER(calloc) (size_t c, size_t n)
 {
-  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;
-
+  DECLARE(void *, calloc, size_t, size_t);
+  DECLARE(void *, malloc, size_t);
+  DECLARE(void *, memset, void *, int, size_t);
   BEGIN_PROTECT (char *, calloc, c, n);
   
-  size_with_crumple_zones = (c * n) + (2 * __mf_opts.crumple_zone);  
-  result = (char *) __real_malloc (size_with_crumple_zones);
+  size_with_crumple_zones = 
+    CLAMPADD((c * n), /* XXX: CLAMPMUL */
+	     CLAMPADD(__mf_opts.crumple_zone,
+		      __mf_opts.crumple_zone));  
+  result = (char *) CALL_REAL(malloc, size_with_crumple_zones);
   
   if (LIKELY(result))
-    __real_memset (result, 0, size_with_crumple_zones);
+    CALL_REAL(memset, result, 0, size_with_crumple_zones);
   
   __mf_state = old_state;
   
   if (LIKELY(result))
     {
       result += __mf_opts.crumple_zone;
-      __mf_register ((uintptr_t) result, c*n, 
+      __mf_register ((uintptr_t) result, c*n, /* XXX: CLAMPMUL */
 		     __MF_TYPE_HEAP, "calloc region");
     }
   
@@ -123,9 +120,9 @@
 }
 
 void *
-__wrap_realloc (void *buf, size_t c)
+WRAPPER(realloc) (void *buf, size_t c)
 {
-  extern void * __real_realloc (void *, size_t);
+  DECLARE(void * , realloc, void *, size_t);
   size_t size_with_crumple_zones;
   char *base = buf;
 
@@ -134,8 +131,10 @@
   if (LIKELY(buf))
     base -= __mf_opts.crumple_zone;
 
-  size_with_crumple_zones = c + (2 * __mf_opts.crumple_zone);
-  result = (char *) __real_realloc (base, size_with_crumple_zones);
+  size_with_crumple_zones = 
+    CLAMPADD(c, CLAMPADD(__mf_opts.crumple_zone,
+			 __mf_opts.crumple_zone));
+  result = (char *) CALL_REAL(realloc, base, size_with_crumple_zones);
 
   __mf_state = old_state;      
 
@@ -155,25 +154,25 @@
 
 
 void
-__wrap_free (void *buf)
+WRAPPER(free) (void *buf)
 {
   /* 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 = 0;
   static int freeq_initialized = 0;
-  mf_state old_state;
-  extern void * __real_free (void *);  
-  extern void *__real_memset (void *s, int c, size_t n);
+  enum __mf_state old_state;
+  DECLARE(void * , free, void *);  
+  DECLARE(void *, memset, void *s, int c, size_t n);
 
   if (UNLIKELY (__mf_state != active))
     {
-      __real_free (buf);
+      CALL_REAL(free, buf);
       return;
     }
 
   if (UNLIKELY(!freeq_initialized))
     {
-      __real_memset (free_queue, 0, 
+      CALL_REAL(memset, free_queue, 0, 
 		     __MF_FREEQ_MAX * sizeof (void *));
       freeq_initialized = 1;
     }
@@ -201,7 +200,7 @@
 		       __mf_opts.free_queue_length, base, 
 		       free_queue [free_ptr], __mf_opts.crumple_zone);
 	    }
-	  __real_free (base);
+	  CALL_REAL(free, base);
 	}
       free_queue [free_ptr] = buf;
       free_ptr = (free_ptr == (__mf_opts.free_queue_length-1) ? 0 : free_ptr + 1);
@@ -216,7 +215,7 @@
 	  fprintf (stderr, "mf: freeing pointer %p = %p - %d\n", base, 
 		   buf, __mf_opts.crumple_zone);
 	}
-      __real_free (base);
+      CALL_REAL(free, base);
     }
   
   __mf_state = old_state;
@@ -224,11 +223,11 @@
 }
 
 void *
-__wrap_dlopen (const char *filename, int flag)
+WRAPPER(dlopen) (const char *filename, int flag)
 {
-  extern void * __real_dlopen(const char *filename, int flag);
+  DECLARE(void * , dlopen, const char *filename, int flag);
   BEGIN_PROTECT(void *, dlopen, filename, flag);
-  result = __real_dlopen (filename, flag);
+  result = CALL_REAL(dlopen, filename, flag);
   __mf_state = old_state;
   __mf_init_heuristics ();
   TRACE_OUT;
@@ -237,16 +236,16 @@
 
 
 void  *  
-__wrap_mmap(void  *start,  size_t length, int prot , 
-	    int flags, int fd, off_t offset)
+WRAPPER(mmap) (void  *start,  size_t length, int prot , 
+	       int flags, int fd, off_t offset)
 {
 
-  extern void *__real_mmap (void *, size_t, int, 
+  DECLARE(void *, mmap, void *, size_t, int, 
 			    int, int, off_t);
   BEGIN_PROTECT(void *, mmap, start, length, 
 		prot, flags, fd, offset);
 
-  result = __real_mmap (start, length, prot, 
+  result = CALL_REAL(mmap, start, length, prot, 
 			flags, fd, offset);
 
   __mf_state = old_state;
@@ -254,7 +253,10 @@
   if ((uintptr_t)result != -1)
     {
       __mf_register ((uintptr_t) result, 
-		     (uintptr_t) result + length - 1,
+		     (uintptr_t) CLAMPADD(((uintptr_t)result),
+					  ((uintptr_t)
+					   CLAMPSUB(((uintptr_t)length),
+						    ((uintptr_t)1)))),
 		     __MF_TYPE_GUESS, 
 		     "(heuristic) mmap region");
     }
@@ -264,12 +266,12 @@
 }
 
 int 
-__wrap_munmap(void *start, size_t length)
+WRAPPER(munmap) (void *start, size_t length)
 {
-  extern void *__real_munmmap (void *, size_t);
+  DECLARE(int, munmap, void *, size_t);
   BEGIN_PROTECT(int, munmap, start, length);
   
-  result = __real_munmap (start, length);
+  result = CALL_REAL(munmap, start, length);
 
   __mf_state = old_state;
   __mf_unregister ((uintptr_t)start, length);
@@ -279,70 +281,71 @@
 /* {{{ str*,mem*,b* */
 
 void *
-__wrap_memcpy (void *dest, const void *src, size_t n)
+WRAPPER(memcpy) (void *dest, const void *src, size_t n)
 {
-  extern void *__real_memcpy (void *dest, const void *src, size_t n);
+  DECLARE(void *, 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);
+  MF_VALIDATE_EXTENT(src, n, "memcpy source");
+  MF_VALIDATE_EXTENT(dest, n, "memcpy dest");
   END_PROTECT (void *, memcpy, dest, src, n);
 }
 
 
 
 void *
-__wrap_memmove (void *dest, const void *src, size_t n)
+WRAPPER(memmove) (void *dest, const void *src, size_t n)
 {
-  extern void *__real_memmove (void *dest, const void *src, size_t n);
+  DECLARE(void *, 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);
+  MF_VALIDATE_EXTENT(src, n, "memmove src");
+  MF_VALIDATE_EXTENT(dest, n, "memmove dest");
   END_PROTECT(void *, memmove, dest, src, n);
 }
 
 
 void *
-__wrap_memset (void *s, int c, size_t n) 
+WRAPPER(memset) (void *s, int c, size_t n) 
 {
-  extern void *__real_memset (void *s, int c, size_t n);
+  DECLARE(void *, memset, void *s, int c, size_t n);
   BEGIN_PROTECT(void *, memset, s, c, n);
-  MF_VALIDATE_EXTENT(s, n);
+  MF_VALIDATE_EXTENT(s, n, "memset dest");
   END_PROTECT(void *, memset, s, c, n);
 }
 
 int
-__wrap_memcmp (const void *s1, const void *s2, size_t n)
+WRAPPER(memcmp) (const void *s1, const void *s2, size_t n)
 {
-  extern int __real_memcmp (const void *s1, const void *s2, size_t n);
+  DECLARE(int , 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);
+  MF_VALIDATE_EXTENT(s1, n, "memcmp 1st arg");
+  MF_VALIDATE_EXTENT(s2, n, "memcmp 2nd arg");
   END_PROTECT(int, memcmp, s1, s2, n);
 }
 
 void *
-__wrap_memchr (const void *s, int c, size_t n)
+WRAPPER(memchr) (const void *s, int c, size_t n)
 {
-  extern void *__real_memchr (const void *s, int c, size_t n);
+  DECLARE(void *, memchr, const void *s, int c, size_t n);
   BEGIN_PROTECT(void *, memchr, s, c, n);
-  MF_VALIDATE_EXTENT(s, n);
+  MF_VALIDATE_EXTENT(s, n, "memchr region");
   END_PROTECT(void *, memchr, s, c, n);
 }
 
 void *
-__wrap_memrchr (const void *s, int c, size_t n)
+WRAPPER(memrchr) (const void *s, int c, size_t n)
 {
-  extern void *__real_memrchr (const void *s, int c, size_t n);
+  DECLARE(void *, memrchr, const void *s, int c, size_t n);
   BEGIN_PROTECT(void *, memrchr, s, c, n);
-  MF_VALIDATE_EXTENT(s, n);
+  MF_VALIDATE_EXTENT(s, n, "memrchr region");
   END_PROTECT(void *, memrchr, s, c, n);
 }
 
 
 char *
-__wrap_strcpy (char *dest, const char *src)
+WRAPPER(strcpy) (char *dest, const char *src)
 {
-  extern char *__real_strcpy (char *dest, const char *src);
+  DECLARE(int, strlen, const char *s);
+  DECLARE(char *, strcpy, char *dest, const char *src);
   int n;
 
   /* nb: just because strlen(src) == n doesn't mean (src + n) or (src + n +
@@ -351,43 +354,45 @@
 
   BEGIN_PROTECT(char *, strcpy, dest, src); 
   TRACE("mf: strcpy %p -> %p\n", src, dest);
-  n = __real_strlen (src);
-  MF_VALIDATE_EXTENT(src, (n + 1)); 
-  MF_VALIDATE_EXTENT(dest, (n + 1));
+  n = CALL_REAL(strlen, src);
+  MF_VALIDATE_EXTENT(src, CLAMPADD(n, 1), "strcpy src"); 
+  MF_VALIDATE_EXTENT(dest, CLAMPADD(n, 1), "strcpy dest");
   END_PROTECT(char *, strcpy, dest, src);
 }
 
 char *
-__wrap_strncpy (char *dest, const char *src, size_t n)
+WRAPPER(strncpy) (char *dest, const char *src, size_t n)
 {
-  extern char *__real_strncpy (char *dest, const char *src, size_t n);
+  DECLARE(int, strnlen, const char *s, size_t n);
+  DECLARE(char *, strncpy, char *dest, const char *src, size_t n);
   int len;
 
   BEGIN_PROTECT(char *, strncpy, dest, src, n);
   TRACE("mf: strncpy %d chars %p -> %p\n", n, src, dest);
-  len = __real_strnlen (src, n);
-  MF_VALIDATE_EXTENT(src, len);
-  MF_VALIDATE_EXTENT(dest, len); /* nb: strNcpy */
+  len = CALL_REAL(strnlen, src, n);
+  MF_VALIDATE_EXTENT(src, len, "strncpy src");
+  MF_VALIDATE_EXTENT(dest, len, "strncpy dest"); /* nb: strNcpy */
   END_PROTECT(char *, strncpy, dest, src, n);
 }
 
 char *
-__wrap_strcat (char *dest, const char *src)
+WRAPPER(strcat) (char *dest, const char *src)
 {
-  extern char *__real_strcat (char *dest, const char *src);
+  DECLARE(int, strlen, const char *s);
+  DECLARE(char *, strcat, char *dest, const char *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));
+  dest_sz = CALL_REAL(strlen, dest);
+  src_sz = CALL_REAL(strlen, src);  
+  MF_VALIDATE_EXTENT(src, CLAMPADD(src_sz, 1), "strcat src");
+  MF_VALIDATE_EXTENT(dest, CLAMPADD(dest_sz, CLAMPADD(src_sz, 1)), "strcat dest");
   END_PROTECT(char *, strcat, dest, src);
 }
 
 char *
-__wrap_strncat (char *dest, const char *src, size_t n)
+WRAPPER(strncat) (char *dest, const char *src, size_t n)
 {
 
   /* nb: validating the extents (s,n) might be a mistake for two reasons.
@@ -410,90 +415,101 @@
   this same logic applies to further uses of strnlen later down in this
   file. */
 
-  extern char *__real_strncat (char *dest, const char *src, size_t n);
+  DECLARE(int, strnlen, const char *s, size_t n);
+  DECLARE(char *, 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));
+  src_sz = CALL_REAL(strnlen, src, n);
+  dest_sz = CALL_REAL(strnlen, dest, n);
+  MF_VALIDATE_EXTENT(src, src_sz, "strncat src");
+  MF_VALIDATE_EXTENT(dest, (CLAMPADD(dest_sz, CLAMPADD(src_sz, 1))), 
+		     "strncat dest");
   END_PROTECT(char *, strncat, dest, src, n);
 }
 
 int
-__wrap_strcmp (const char *s1, const char *s2)
+WRAPPER(strcmp) (const char *s1, const char *s2)
 {
-  extern int __real_strcmp (const char *s1, const char *s2);
+  DECLARE(int, strlen, const char *s);
+  DECLARE(int, strcmp, const char *s1, const char *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);
+  s1_sz = CALL_REAL(strlen, s1);
+  s2_sz = CALL_REAL(strlen, s2);  
+  MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), "strcmp 1st arg");
+  MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), "strcmp 2nd arg");
   END_PROTECT(int, strcmp, s1, s2);
 }
 
 int
-__wrap_strcasecmp (const char *s1, const char *s2)
+WRAPPER(strcasecmp) (const char *s1, const char *s2)
 {
-  extern int __real_strcasecmp (const char *s1, const char *s2);
+  DECLARE(int, strlen, const char *s);
+  DECLARE(int, strcasecmp, const char *s1, const char *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);
+  s1_sz = CALL_REAL(strlen, s1);
+  s2_sz = CALL_REAL(strlen, s2);  
+  MF_VALIDATE_EXTENT(s1, CLAMPADD(s1_sz, 1), "strcasecmp 1st arg");
+  MF_VALIDATE_EXTENT(s2, CLAMPADD(s2_sz, 1), "strcasecmp 2nd arg");
   END_PROTECT(int, strcasecmp, s1, s2);
 }
 
 int
-__wrap_strncmp (const char *s1, const char *s2, size_t n)
+WRAPPER(strncmp) (const char *s1, const char *s2, size_t n)
 {
-  extern int __real_strncmp (const char *s1, const char *s2, size_t n);
+  DECLARE(int, strnlen, const char *s, size_t n);
+  DECLARE(int, strncmp, const char *s1, const char *s2, size_t 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);
+  s1_sz = CALL_REAL(strnlen, s1, n);
+  s2_sz = CALL_REAL(strnlen, s2, n);
+  MF_VALIDATE_EXTENT(s1, s1_sz, "strncmp 1st arg");
+  MF_VALIDATE_EXTENT(s2, s2_sz, "strncmp 2nd arg");
   END_PROTECT(int, strncmp, s1, s2, n);
 }
 
 int
-__wrap_strncasecmp (const char *s1, const char *s2, size_t n)
+WRAPPER(strncasecmp) (const char *s1, const char *s2, size_t n)
 {
-  extern int __real_strncasecmp (const char *s1, const char *s2, size_t n);
+  DECLARE(int, strnlen, const char *s, size_t n);
+  DECLARE(int, strncasecmp, const char *s1, const char *s2, size_t 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);
+  s1_sz = CALL_REAL(strnlen, s1, n);
+  s2_sz = CALL_REAL(strnlen, s2, n);
+  MF_VALIDATE_EXTENT(s1, s1_sz, "strncasecmp 1st arg");
+  MF_VALIDATE_EXTENT(s2, s2_sz, "strncasecmp 2nd arg");
   END_PROTECT(int, strncasecmp, s1, s2, n);
 }
 
 char *
-__wrap_strdup (const char *s)
+WRAPPER(strdup) (const char *s)
 {
-  extern char *__real_strdup (const char *s);
-  extern void *__real_malloc (size_t sz);
+  DECLARE(int, strlen, const char *s);
+  DECLARE(char *, strdup, const char *s);
+  DECLARE(void *, malloc, size_t sz);
+  DECLARE(void *, memcpy, void *dest, const void *src, size_t n);
   int n;
 
   BEGIN_PROTECT(char *, strdup, s);
-  n = __real_strlen (s);
-  MF_VALIDATE_EXTENT(s, n+1);
+  n = CALL_REAL(strlen, s);
+  MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), "strdup region");
 
-  result = (char *)__real_malloc (n+1 + 2*(__mf_opts.crumple_zone));
+  result = (char *)CALL_REAL(malloc, 
+			     CLAMPADD(CLAMPADD(n,1),
+				      CLAMPADD(__mf_opts.crumple_zone,
+					       __mf_opts.crumple_zone)));
 
   if (UNLIKELY(!result))
     {
@@ -503,29 +519,35 @@
     }
 
   result += __mf_opts.crumple_zone;
-  __real_memcpy (result, s, n);
+  CALL_REAL(memcpy, result, s, n);
   result[n] = '\0';
 
-  __mf_register ((uintptr_t) result, n+1, __MF_TYPE_HEAP, "strdup region");
+  __mf_register ((uintptr_t) result, CLAMPADD(n,1), 
+		 __MF_TYPE_HEAP, "strdup region");
   __mf_state = old_state;
   TRACE_OUT;
   return result;
 }
 
 char *
-__wrap_strndup (const char *s, size_t n)
+WRAPPER(strndup) (const char *s, size_t n)
 {
-  extern char *__real_strndup (const char *s, size_t n);
-  extern void *__real_malloc (size_t sz);
+  DECLARE(int, strnlen, const char *s, size_t n);
+  DECLARE(char *, strndup, const char *s, size_t n);
+  DECLARE(void *, malloc, size_t sz);
+  DECLARE(void *, memcpy, void *dest, const void *src, size_t n);
   int sz;
 
   BEGIN_PROTECT(char *, strndup, s, n);
-  sz = __real_strnlen (s, n);
-  MF_VALIDATE_EXTENT(s, sz); /* nb: strNdup */
+  sz = CALL_REAL(strnlen, s, n);
+  MF_VALIDATE_EXTENT(s, sz, "strndup region"); /* nb: strNdup */
 
   /* note: strndup still adds a \0, even with the N limit! */
-  result = (char *)__real_malloc (n+1 + 2*(__mf_opts.crumple_zone));
-
+  result = (char *)CALL_REAL(malloc, 
+			     CLAMPADD(CLAMPADD(n,1),
+				      CLAMPADD(__mf_opts.crumple_zone,
+					       __mf_opts.crumple_zone)));
+  
   if (UNLIKELY(!result))
     {
       __mf_state = old_state;
@@ -534,10 +556,11 @@
     }
 
   result += __mf_opts.crumple_zone;
-  __real_memcpy (result, s, n);
+  CALL_REAL(memcpy, result, s, n);
   result[n] = '\0';
 
-  __mf_register ((uintptr_t) result, n+1, __MF_TYPE_HEAP, "strndup region");
+  __mf_register ((uintptr_t) result, CLAMPADD(n,1), 
+		 __MF_TYPE_HEAP, "strndup region");
   __mf_state = old_state;
   TRACE_OUT;
   return result;
@@ -545,178 +568,167 @@
 
 
 char *
-__wrap_strchr (const char *s, int c)
+WRAPPER(strchr) (const char *s, int c)
 {
-  extern char *__real_strchr (const char *s, int c);
+  DECLARE(int, strlen, const char *s);
+  DECLARE(char *, strchr, const char *s, int c);
   int n;
 
   BEGIN_PROTECT(char *, strchr, s, c);
-  n = __real_strlen (s);
-  MF_VALIDATE_EXTENT(s, n+1);
+  n = CALL_REAL(strlen, s);
+  MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), "strchr region");
   END_PROTECT(char *, strchr, s, c);
 }
 
 char *
-__wrap_strrchr (const char *s, int c)
+WRAPPER(strrchr) (const char *s, int c)
 {
-  extern char *__real_strrchr (const char *s, int c);
+  DECLARE(int, strlen, const char *s);
+  DECLARE(char *, strrchr, const char *s, int c);
   int n;
 
   BEGIN_PROTECT(char *, strrchr, s, c);
-  n = __real_strlen (s);
-  MF_VALIDATE_EXTENT(s, n+1);
+  n = CALL_REAL(strlen, s);
+  MF_VALIDATE_EXTENT(s, CLAMPADD(n,1), "strrchr region");
   END_PROTECT(char *, strrchr, s, c);
 }
 
 
 char *
-__wrap_strstr (const char *haystack, const char *needle)
+WRAPPER(strstr) (const char *haystack, const char *needle)
 {
-  extern char *__real_strstr (const char *haystack, const char *needle);
+  DECLARE(int, strlen, const char *s);
+  DECLARE(char *, strstr, const char *haystack, const char *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);
+  haystack_sz = CALL_REAL(strlen, haystack);
+  needle_sz = CALL_REAL(strlen, needle);
+  MF_VALIDATE_EXTENT(haystack, CLAMPADD(haystack_sz, 1), "strstr haystack");
+  MF_VALIDATE_EXTENT(needle, CLAMPADD(needle_sz, 1), "strstr needle");
   END_PROTECT(char *, strstr, haystack, needle);
 }
 
 
 void *
-__wrap_memmem (const void *haystack, size_t haystacklen,
+WRAPPER(memmem) (const void *haystack, size_t haystacklen,
 	       const void *needle, size_t needlelen)
 {
-  extern void *__real_memmem (const void *haystack, size_t haystacklen,
+  DECLARE(void *, 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);
+  MF_VALIDATE_EXTENT(haystack, haystacklen, "memmem haystack");
+  MF_VALIDATE_EXTENT(needle, needlelen, "memmem needle");
   END_PROTECT(char *, memmem, haystack, haystacklen, needle, needlelen);
 }
 
 int
-__wrap_strlen (const char *s)
+WRAPPER(strlen) (const char *s)
 {
-  extern int __real_strlen (const char *s);
+  DECLARE(int, strlen, const char *s);
 
   BEGIN_PROTECT(int, strlen, s);
-  result = __real_strlen (s);
-  MF_VALIDATE_EXTENT(s, result+1);
+  result = CALL_REAL(strlen, s);
+  MF_VALIDATE_EXTENT(s, CLAMPADD(result, 1), "strlen region");
   __mf_state = old_state;
   TRACE_OUT;
   return result;
 }
 
 int
-__wrap_strnlen (const char *s, size_t n)
+WRAPPER(strnlen) (const char *s, size_t n)
 {
-  extern int __real_strnlen (const char *s, size_t n);
+  DECLARE(int, strnlen, const char *s, size_t n);
 
   BEGIN_PROTECT(int, strnlen, s, n);
-  result = __real_strnlen (s, n);
-  MF_VALIDATE_EXTENT(s, result);
+  result = CALL_REAL(strnlen, s, n);
+  MF_VALIDATE_EXTENT(s, result, "strnlen region");
   __mf_state = old_state;
   TRACE_OUT;
   return result;
 }
 
 void
-__wrap_bzero (void *s, size_t n)
+WRAPPER(bzero) (void *s, size_t n)
 {
-  extern void __real_bzero (void *s, size_t n);
-  mf_state old_state;
+  DECLARE(void , bzero, void *s, size_t n);
+  enum __mf_state old_state;
 
   if (UNLIKELY (__mf_state != active))
     {
-      __real_bzero (s, n);
+      CALL_REAL(bzero, s, n);
       return;
     }
   TRACE_IN;
   old_state = __mf_state;
   __mf_state = reentrant;
-  MF_VALIDATE_EXTENT(s, n);
-  __real_bzero (s, n);
+  MF_VALIDATE_EXTENT(s, n, "bzero region");
+  CALL_REAL(bzero, s, n);
   __mf_state = old_state;
   TRACE_OUT;
 }
 
 void
-__wrap_bcopy (const void *src, void *dest, size_t n)
+WRAPPER(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;
+  DECLARE(void , bcopy, const void *src, void *dest, size_t n);
+  enum __mf_state old_state;
 
   if (UNLIKELY (__mf_state != active))
     {
-      __real_bcopy (src, dest, n);
+      CALL_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);
-  __real_bcopy (src, dest, n);
+  MF_VALIDATE_EXTENT(src, n, "bcopy src");
+  MF_VALIDATE_EXTENT(dest, n, "bcopy dest");
+  CALL_REAL(bcopy, src, dest, n);
   __mf_state = old_state;
   TRACE_OUT;
 }
 
 int
-__wrap_bcmp (const void *s1, const void *s2, size_t n)
+WRAPPER(bcmp) (const void *s1, const void *s2, size_t n)
 {
-  extern int __real_bcmp (const void *s1, const void *s2, size_t n);
+  DECLARE(int , 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);
+  MF_VALIDATE_EXTENT(s1, n, "bcmp 1st arg");
+  MF_VALIDATE_EXTENT(s2, n, "bcmp 2nd arg");
   END_PROTECT(int, bcmp, s1, s2, n);
 }
 
 char *
-__wrap_index (const char *s, int c)
+WRAPPER(index) (const char *s, int c)
 {
-  extern char *__real_index (const char *s, int c);
+  DECLARE(int, strlen, const char *s);
+  DECLARE(char *, index, const char *s, int c);
   int n;
 
   BEGIN_PROTECT(char *, index, s, c);
-  n = __real_strlen (s);
-  MF_VALIDATE_EXTENT(s, n+1);
+  n = CALL_REAL(strlen, s);
+  MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), "index region");
   END_PROTECT(char *, index, s, c);
 }
 
 
 
 char *
-__wrap_rindex (const char *s, int c)
+WRAPPER(rindex) (const char *s, int c)
 {
-  extern char *__real_rindex (const char *s, int c);
+  DECLARE(int, strlen, const char *s);
+  DECLARE(char *, rindex, const char *s, int c);
   int n;
 
   BEGIN_PROTECT(char *, rindex, s, c);
-  n = __real_strlen (s);
-  MF_VALIDATE_EXTENT(s, n+1);
+  n = CALL_REAL(strlen, s);
+  MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), "rindex region");
   END_PROTECT(char *, rindex, s, c);
 }
-
-/* 
-
-general form: 
-
-void
-__wrap_ ()
-{
-  extern void __real_ ();
-  MF_VALIDATE_EXTENT();
-  result = __real_ ();
-  __mf_state = old_state;
-  return result;
-}
-
-*/
 
 
 /* }}} */
Index: libmudflap/mf-impl.h
===================================================================
RCS file: libmudflap/mf-impl.h
diff -N libmudflap/mf-impl.h
--- libmudflap/mf-impl.h	1 Jan 1970 00:00:00 -0000
+++ libmudflap/mf-impl.h	26 Aug 2002 23:17:44 -0000
@@ -0,0 +1,278 @@
+#ifndef __MF_IMPL_H
+#define __MF_IMPL_H
+
+/* 
+   Implementation header for mudflap runtime library.
+   
+   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.
+
+*/
+
+#ifdef _MUDFLAP
+#error "Do not compile this file with -fmudflap!"
+#endif
+
+/* 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 ();
+
+/* ------------------------------------------------------------------------ */
+/* Type definitions. */
+/* ------------------------------------------------------------------------ */
+
+/* The mf_state type codes describe recursion and initialization order. */
+
+enum __mf_state
+  {
+    inactive, 
+    starting, 
+    active, 
+    reentrant
+  }; 
+
+/* The __mf_options structure records optional or tunable aspects of the
+ mudflap library's behavior. There is a single global instance of this
+ structure which is populated from user input (in an environment variable)
+ when the library initializes. */
+
+struct __mf_options
+{
+  /* Emit a trace message for each call. */
+  int trace_mf_calls;
+
+  /* Collect and emit statistics. */
+  int collect_stats;
+
+  /* Execute internal checking code */
+  int internal_checking;
+
+  /* Print list of leaked heap objects on shutdown. */
+  int print_leaks;       
+
+  /* Print verbose description of violations. */
+  int verbose_violations;
+
+  /* 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;
+
+  /* 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;
+
+  /* Major operation mode */
+
+  enum
+  {
+    mode_nop,        /* mudflaps do nothing */
+    mode_populate,   /* mudflaps populate tree but do not check for violations */
+    mode_check,      /* mudflaps populate and check for violations (normal) */
+    mode_violate     /* mudflaps trigger a violation on every call (diagnostic) */
+  }
+  mudflap_mode;
+
+
+  /* How to handle a violation. */
+
+  enum
+  {
+    viol_nop,        /* Return control to application. */ 
+    viol_segv,       /* Signal self with segv. */
+    viol_abort,      /* Call abort (). */
+    viol_gdb         /* Fork a debugger on self */
+  }
+  violation_mode;
+
+  /* Violation heuristics selection. */
+  int heur_proc_map;  /* Register /proc/self/map regions.  */
+};
+
+
+#ifdef PIC
+
+/* This is a table of dynamically resolved function pointers. */
+
+struct __mf_dynamic 
+{
+  void * dyn_bcmp;
+  void * dyn_bcopy;
+  void * dyn_bzero;
+  void * dyn_calloc;
+  void * dyn_dlopen;
+  void * dyn_free;
+  void * dyn_index;
+  void * dyn_malloc;
+  void * dyn_memchr;
+  void * dyn_memcmp;
+  void * dyn_memcpy;
+  void * dyn_memmem;
+  void * dyn_memmove;
+  void * dyn_memrchr;
+  void * dyn_memset;
+  void * dyn_mmap;
+  void * dyn_munmap;
+  void * dyn_realloc;
+  void * dyn_rindex;
+  void * dyn_strcasecmp;
+  void * dyn_strcat;
+  void * dyn_strchr;
+  void * dyn_strcmp;
+  void * dyn_strcpy;
+  void * dyn_strdup;
+  void * dyn_strlen;
+  void * dyn_strncasecmp;
+  void * dyn_strncat;
+  void * dyn_strncmp;
+  void * dyn_strncpy;
+  void * dyn_strndup;
+  void * dyn_strnlen;
+  void * dyn_strrchr;
+  void * dyn_strstr;
+};
+
+#endif /* PIC */
+
+/* ------------------------------------------------------------------------ */
+/* Private global variables. */
+/* ------------------------------------------------------------------------ */
+
+extern enum __mf_state __mf_state;
+extern struct __mf_options __mf_opts;
+#ifdef PIC
+extern struct __mf_dynamic __mf_dynamic;
+#endif 
+
+/* ------------------------------------------------------------------------ */
+/* Utility macros. */
+/* ------------------------------------------------------------------------ */
+
+#define UNLIKELY(e) (__builtin_expect (!!(e), 0))
+#define LIKELY(e) (__builtin_expect (!!(e), 1))
+#define STRINGIFY2(e) #e
+#define STRINGIFY(e) STRINGIFY2(e)
+#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 __MF_PERSIST_MAX 256
+#define __MF_FREEQ_MAX 256
+
+/* 
+   Wrapping and redirection:
+
+   Mudflap redirects a number of libc functions into itself, for "cheap"
+   verification (eg. strcpy, bzero, memcpy) and also to register /
+   unregister regions of memory as they are manipulated by the program
+   (eg. malloc/free, mmap/munmap).
+
+   There are two methods of wrapping. 
+
+   (1) The static method involves a list of -wrap=foo flags being passed to
+   the linker, which then links references to "foo" to the symbol
+   "__wrap_foo", and links references to "__real_foo" to the symbol "foo".
+   When compiled without -DPIC, libmudflap.a contains such __wrap_foo
+   functions which delegate to __real_foo functions in libc to get their
+   work done.
+
+   (2) The dynamic method involves providing a definition of symbol foo in
+   libmudflap.so and linking it earlier in the compiler command line,
+   before libc.so. The function "foo" in libmudflap must then call
+   dlsym(RTLD_NEXT, "foo") to acquire a pointer to the "real" libc foo, or
+   at least the "next" foo in the dynamic link resolution order.
+
+   We switch between these two techniques by the presence of the -DPIC
+   #define passed in by libtool when building libmudflap.
+*/
+
+
+#ifdef PIC
+#define __USE_GNU
+#include <dlfcn.h>
+
+#define WRAPPER(fname) fname
+#define DECLARE(ty, fname, ...) \
+ typedef ty (*__mf_fn_ ## fname) (__VA_ARGS__);
+#define CALL_REAL(fname, ...)                         \
+  ({ if (UNLIKELY(!__mf_dynamic.dyn_ ## fname))       \
+     __mf_resolve_dynamics ();                        \
+  ((__mf_fn_ ## fname)(__mf_dynamic.dyn_ ## fname))   \
+                      (__VA_ARGS__);})
+
+
+#else /* not PIC --> static library */
+
+#define WRAPPER(fname) __wrap_ ## fname
+#define DECLARE(ty, fname, ...)             \
+ extern ty __real_ ## fname (__VA_ARGS__);
+#define CALL_REAL(fname, ...)               \
+ __real_ ## fname (__VA_ARGS__)
+
+#endif /* PIC */
+
+
+/* previous incarnation of PIC strategy */
+
+/* 
+#define WRAPPER(fname) fname
+
+#define DECLARE(ty, fname, ...)                  \
+ typedef ty (*__mf_fn_ ## fname) (__VA_ARGS__);  \
+ static __mf_fn_ ## fname __dynamic_ ## fname = NULL;
+
+#define CALL_REAL(fname, ...)               \
+({                                          \
+ if (__dynamic_ ## fname == NULL)           \
+ {                                          \
+  enum __mf_state prev_state;               \
+  prev_state = __mf_state;                  \
+  __mf_state = active;                      \
+  char *err = NULL;                         \
+  __dynamic_ ## fname = (__mf_fn_ ## fname) dlsym (RTLD_NEXT, #fname);   \
+  err = dlerror ();                         \
+  if (err != NULL)                          \
+  {                                         \
+    fprintf (stderr, "mf: error dlsym(" STRINGIFY(fname) ") failed: %s\n", err); \
+    abort ();                               \
+  }                                         \
+    else if (__dynamic_ ## fname == NULL)            \
+  {                                         \
+    fprintf (stderr, "mf: error dlsym(" STRINGIFY(fname) ") returned null\n"); \
+    abort ();                               \
+  }                                         \
+  __mf_state = prev_state;                  \
+ }                                          \
+ (*__dynamic_ ## fname) (__VA_ARGS__);      \
+})
+ */
+
+
+#endif /* __MF_IMPL_H */
Index: libmudflap/mf-runtime.c
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-runtime.c,v
retrieving revision 1.1.2.8
diff -u -r1.1.2.8 mf-runtime.c
--- libmudflap/mf-runtime.c	22 Aug 2002 20:36:36 -0000	1.1.2.8
+++ libmudflap/mf-runtime.c	26 Aug 2002 23:17:44 -0000
@@ -25,6 +25,7 @@
 #include <signal.h>
 
 #include "mf-runtime.h"
+#include "mf-impl.h"
 
 #ifndef max
 #define max(a,b) ((a) > (b) ? (a) : (b))
@@ -41,13 +42,17 @@
 /* ------------------------------------------------------------------------ */
 /* {{{ Utility macros */
 
-#define MINPTR ((uintptr_t) 0)
-#define MAXPTR (~ (uintptr_t) 0)
+/* Protect against recursive calls. */
+#define BEGIN_RECURSION_PROTECT           \
+  enum __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;
 
-/* Clamp the addition/subtraction of uintptr_t's to [MINPTR,MAXPTR] */
-#define CLAMPSUB(ptr,offset) ((ptr) >= (offset) ? (ptr)-(offset) : MINPTR)
-#define CLAMPADD(ptr,offset) ((ptr) <= MAXPTR-(offset) ? (ptr)+(offset) : MAXPTR)
-#define CLAMPSZ(ptr,size) ((ptr) <= MAXPTR-(size)+1 ? (ptr)+(size)-1 : MAXPTR)
 
 /* }}} */
 /* ------------------------------------------------------------------------ */
@@ -68,26 +73,16 @@
 unsigned char __mf_lc_shift = LOOKUP_CACHE_SHIFT_DFL;
 #define LOOKUP_CACHE_SIZE (__mf_lc_mask + 1)
 
+struct __mf_options __mf_opts;
+enum __mf_state __mf_state = inactive;
+#ifdef PIC
+struct __mf_dynamic __mf_dynamic;
+#endif
+
 /* }}} */
 /* ------------------------------------------------------------------------ */
 /* {{{ Configuration engine */
 
-struct __mf_options __mf_opts;
-
-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 ()
 {
@@ -333,6 +328,74 @@
 #define CTOR  __attribute__ ((constructor))
 #define DTOR  __attribute__ ((destructor))
 
+#ifdef PIC
+
+static void 
+resolve_single_dynamic (void **target, const char *name)
+{
+  char *err;
+  assert (target);
+  *target = NULL;
+  *target = dlsym (RTLD_NEXT, name);
+  err = dlerror ();
+  if (err)
+    {
+      fprintf (stderr, "mf: error in dlsym(\"%s\"): %s\n",
+	       name, err);
+      abort ();
+    }  
+  if (! *target)
+    {
+      fprintf (stderr, "mf: dlsym(\"%s\") = NULL\n", name);
+      abort ();
+    }
+}
+
+void 
+__mf_resolve_dynamics () 
+{
+  TRACE_IN;
+#define RESOLVE(fname) \
+resolve_single_dynamic (&__mf_dynamic.dyn_ ## fname, #fname)
+  RESOLVE(bcmp);
+  RESOLVE(bcopy);
+  RESOLVE(bzero);
+  RESOLVE(calloc);
+  RESOLVE(dlopen);
+  RESOLVE(free);
+  RESOLVE(index);
+  RESOLVE(malloc);
+  RESOLVE(memchr);
+  RESOLVE(memcmp);
+  RESOLVE(memcpy);
+  RESOLVE(memmem);
+  RESOLVE(memmove);
+  RESOLVE(memrchr);
+  RESOLVE(memset);
+  RESOLVE(mmap);
+  RESOLVE(munmap);
+  RESOLVE(realloc);
+  RESOLVE(rindex);
+  RESOLVE(strcasecmp);
+  RESOLVE(strcat);
+  RESOLVE(strchr);
+  RESOLVE(strcmp);
+  RESOLVE(strcpy);
+  RESOLVE(strdup);
+  RESOLVE(strlen);
+  RESOLVE(strncasecmp);
+  RESOLVE(strncat);
+  RESOLVE(strncmp);
+  RESOLVE(strncpy);
+  RESOLVE(strndup);
+  RESOLVE(strnlen);
+  RESOLVE(strrchr);
+  RESOLVE(strstr);
+#undef RESOLVE
+  TRACE_OUT;
+}
+
+#endif /* PIC */
 
 extern void __mf_init () CTOR;
 void __mf_init ()
@@ -341,6 +404,10 @@
 
   __mf_state = starting;
 
+#ifdef PIC
+  __mf_resolve_dynamics ();
+#endif
+
   __mf_set_default_options ();
 
   ov = getenv ("MUDFLAP_OPTIONS");
@@ -482,14 +549,15 @@
 		else
 		  {	      
 		    /* Possible violation. */
-		    if (attempts)
+		    if (attempts > 0)
 		      {
 			/* Try re-initializing heuristics. */
 			__mf_init_heuristics (); 
 		      }
 		    else
 		      {
-			/* Second time around: out of luck. */
+			/* This is our second time around,
+			   therefore we are out of luck. */
 			violation_p = 1;
 		      }
 		  }
@@ -529,10 +597,10 @@
 __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);
+  DECLARE (void *, calloc, size_t c, size_t n);
 
   __mf_object_tree_t *new_obj;
-  new_obj = __real_calloc (1, sizeof(__mf_object_tree_t));
+  new_obj = CALL_REAL(calloc, 1, sizeof(__mf_object_tree_t));
   new_obj->data.low = low;
   new_obj->data.high = high;
   new_obj->data.type = type;
@@ -655,10 +723,10 @@
 
 		    for (i = 0; i < num_overlapping_objs; ++i)
 		      {
-			extern void  __real_free (void *);
+			DECLARE (void, free, void *ptr);
 			__mf_remove_old_object (ovr_obj[i]);
-			__real_free (ovr_obj[i]->data.alloc_backtrace);
-			__real_free (ovr_obj[i]);			
+			CALL_REAL(free, ovr_obj[i]->data.alloc_backtrace);
+			CALL_REAL(free, ovr_obj[i]);
 		      }
 
 		    __mf_insert_new_object (low, high, __MF_TYPE_GUESS, 
@@ -687,7 +755,7 @@
 			uintptr_t guess2_low, guess2_high;
 			uintptr_t guess_pc;
 			const char *guess_name;
-			extern void  __real_free (void *);
+			DECLARE (void, free, void *ptr);
 		
 			guess_pc = ovr_obj[i]->data.alloc_pc;
 			guess_name = ovr_obj[i]->data.name;
@@ -704,8 +772,8 @@
 			/* NB: split regions may disappear if low > high. */
 
 			__mf_remove_old_object (ovr_obj[i]);
-			__real_free (ovr_obj[i]->data.alloc_backtrace);
-			__real_free (ovr_obj[i]);
+		        CALL_REAL(free, ovr_obj[i]->data.alloc_backtrace);
+			CALL_REAL(free, ovr_obj[i]);
 			ovr_obj[i] = NULL;
 
 			/* XXX: preserve other information: stats? backtraces */
@@ -763,9 +831,7 @@
 void
 __mf_unregister (uintptr_t ptr, uintptr_t sz)
 {
-
-  extern void  __real_free (void *);
-
+  DECLARE (void, free, void *ptr);
   BEGIN_RECURSION_PROTECT;
 
   switch (__mf_opts.mudflap_mode)
@@ -878,11 +944,13 @@
 	  {
 	    if (__mf_opts.backtrace > 0)
 	      {
-		__real_free (del_obj->data.alloc_backtrace);
+		CALL_REAL(free, del_obj->data.alloc_backtrace);
 		if (__mf_opts.persistent_count > 0)
-		  __real_free (del_obj->data.dealloc_backtrace);
+		  {
+		    CALL_REAL(free, del_obj->data.dealloc_backtrace);
+		  }
 	      }
-	    __real_free (del_obj);
+	    CALL_REAL(free, del_obj);
 	  }
 	
 	break;
@@ -1400,8 +1468,7 @@
 {
   char buf [128];
   static unsigned violation_number;
-  extern void  __real_free (void *);
-
+  DECLARE(void, free, void *ptr);
   BEGIN_RECURSION_PROTECT;
 
   TRACE("mf: violation pc=%p location=%s type=%d ptr=%p size=%lu\n", pc, 
@@ -1448,7 +1515,7 @@
 	  fprintf (stderr, "      %s\n", symbols[i]);
 	
 	/* Calling free() here would trigger a violation.  */
-	__real_free (symbols);
+	CALL_REAL(free, symbols);
       }
     
     
Index: libmudflap/mf-runtime.h
===================================================================
RCS file: /cvs/gcc/gcc/libmudflap/Attic/mf-runtime.h,v
retrieving revision 1.1.2.6
diff -u -r1.1.2.6 mf-runtime.h
--- libmudflap/mf-runtime.h	21 Aug 2002 19:55:28 -0000	1.1.2.6
+++ libmudflap/mf-runtime.h	26 Aug 2002 23:17:44 -0000
@@ -1,7 +1,6 @@
 #ifndef __MF_RUNTIME_H
 #define __MF_RUNTIME_H
 
-
 /* ------------------------------------------------------------------------ */
 /* Public libmudflap declarations */
 
@@ -10,6 +9,14 @@
 typedef unsigned long uintptr_t;
 #endif
 
+#define MINPTR ((uintptr_t) 0)
+#define MAXPTR (~ (uintptr_t) 0)
+
+/* Clamp the addition/subtraction of uintptr_t's to [MINPTR,MAXPTR] */
+#define CLAMPSUB(ptr,offset) ((ptr) >= (offset) ? (ptr)-(offset) : MINPTR)
+#define CLAMPADD(ptr,offset) ((ptr) <= MAXPTR-(offset) ? (ptr)+(offset) : MAXPTR)
+#define CLAMPSZ(ptr,size) ((size) ? ((ptr) <= MAXPTR-(size)+1 ? (ptr)+(size)-1 : MAXPTR) : (ptr))
+
 struct __mf_cache { uintptr_t low; uintptr_t high; };
 extern struct __mf_cache __mf_lookup_cache [];
 extern uintptr_t __mf_lc_mask;
@@ -18,115 +25,29 @@
 #define __MF_CACHE_MISS_P(ptr,sz) ({ \
              struct __mf_cache *elem = & __mf_lookup_cache[__MF_CACHE_INDEX((ptr))]; \
              ((elem->low > (uintptr_t) (ptr)) ||                  \
-	      (elem->high < ((uintptr_t) (ptr) + (uintptr_t) ((sz) - 1)))); })
+	      (elem->high < (CLAMPADD((uintptr_t) (ptr), (uintptr_t) CLAMPSUB(sz,1) )))); })
 /* XXX: the above should use CLAMPSZ () */
 extern void __mf_check (uintptr_t ptr, uintptr_t sz, const char *location);
 
 
-/* ------------------------------------------------------------------------ */
-/* Internal libmudflap declarations */
-/* XXX: should be in a separate file.  */
-
-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))
-
-extern void __mf_init_heuristics ();
+/* Codes to describe the context in which a violation occurs. */
 
 #define __MF_VIOL_UNKNOWN 0
 #define __MF_VIOL_CHECK 1
 #define __MF_VIOL_REGISTER 2
 #define __MF_VIOL_UNREGISTER 3
-extern void __mf_violation (uintptr_t ptr, uintptr_t sz, 
-			    uintptr_t pc, const char *location, 
-			    int type);
+
+/* Codes to describe a region of memory being registered. */
+  
 #define __MF_TYPE_UNKNOWN 0
 #define __MF_TYPE_HEAP 1
 #define __MF_TYPE_STACK 2
 #define __MF_TYPE_STATIC 3
 #define __MF_TYPE_GUESS 4
+
+/* The "public" mudflap API */
 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 ();
-extern size_t __mf_backtrace (char ***, void *, unsigned);
-
-#define __MF_PERSIST_MAX 256
-#define __MF_FREEQ_MAX 256
-
-#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
-{
-  /* Emit a trace message for each call. */
-  int trace_mf_calls;
-
-  /* Collect and emit statistics. */
-  int collect_stats;
-
-  /* Execute internal checking code */
-  int internal_checking;
-
-  /* Print list of leaked heap objects on shutdown. */
-  int print_leaks;       
-
-  /* Print verbose description of violations. */
-  int verbose_violations;
-
-  /* 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;
-
-  /* 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;
-
-  /* Major operation mode */
-
-  enum
-  {
-    mode_nop,        /* mudflaps do nothing */
-    mode_populate,   /* mudflaps populate tree but do not check for violations */
-    mode_check,      /* mudflaps populate and check for violations (normal) */
-    mode_violate     /* mudflaps trigger a violation on every call (diagnostic) */
-  }
-  mudflap_mode;
-
-
-  /* How to handle a violation. */
-
-  enum
-  {
-    viol_nop,        /* Return control to application. */ 
-    viol_segv,       /* Signal self with segv. */
-    viol_abort,      /* Call abort (). */
-    viol_gdb         /* Fork a debugger on self */
-  }
-  violation_mode;
-
-  /* Violation heuristics selection. */
-  int heur_proc_map;  /* Register /proc/self/map regions.  */
-};
-
-extern struct __mf_options __mf_opts;
 
 #endif


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