This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa mudflap]
- From: graydon at redhat dot com
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 26 Aug 2002 19:20:05 -0400
- Subject: [tree-ssa mudflap]
- Reply-to: graydon at redhat dot com
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