diff options
author | fche <fche@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-10-13 18:27:16 +0000 |
---|---|---|
committer | fche <fche@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-10-13 18:27:16 +0000 |
commit | 0c61ade535e67b7e9bef7265af0a1dc99b0dabf3 (patch) | |
tree | 5ba143b308278286023d43a624647837da8e9cbd /libmudflap | |
parent | e68ba323fd543681236c6e56702da2e290d30c87 (diff) | |
download | gcc-0c61ade535e67b7e9bef7265af0a1dc99b0dabf3.tar.gz |
2004-10-12 Frank Ch. Eigler <fche@redhat.com>
* configure.ac: Check for more headers, functions.
* mf-hooks2.c (mkbuffer, unmkbuffer): New helper functions for
tracking overridden FILE buffers.
(fopen, setvbuf): New/revised hook functions for buffer overriding.
(setbuf,setlinebuf,fdopen,freopen,fopen64,freopen64,fclose): Ditto.
(fflush): Accept given NULL stream (means "all streams").
* mf-runtime.h.in:
* mf-runtime.c (__mfu_check): Accept accesses that span adjacent
HEAP/GUESS objects.
(LOOKUP_CACHE_SIZE_MAX): Raise to 64K entries tentatively.
(__mf_adapt_cache): Use them all.
* testsuite/libmudflap.c/pass35-frag.c: Update warning message.
* testsuite/libmudflap.c++/ctors.exp: Ditto.
* testsuite/libmudflap.c/{pass51,pass52}-frag.c: New tests.
* configure, config.h.in: Regenerated.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@88996 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libmudflap')
-rw-r--r-- | libmudflap/ChangeLog | 18 | ||||
-rw-r--r-- | libmudflap/config.h.in | 24 | ||||
-rwxr-xr-x | libmudflap/configure | 117 | ||||
-rw-r--r-- | libmudflap/configure.ac | 7 | ||||
-rw-r--r-- | libmudflap/mf-hooks2.c | 221 | ||||
-rw-r--r-- | libmudflap/mf-runtime.c | 58 | ||||
-rw-r--r-- | libmudflap/mf-runtime.h.in | 5 | ||||
-rw-r--r-- | libmudflap/testsuite/libmudflap.c++/ctors.exp | 2 | ||||
-rw-r--r-- | libmudflap/testsuite/libmudflap.c/pass35-frag.c | 2 | ||||
-rw-r--r-- | libmudflap/testsuite/libmudflap.c/pass51-frag.c | 41 | ||||
-rw-r--r-- | libmudflap/testsuite/libmudflap.c/pass52-frag.c | 36 |
11 files changed, 492 insertions, 39 deletions
diff --git a/libmudflap/ChangeLog b/libmudflap/ChangeLog index f9778d4b193..ee4feac614e 100644 --- a/libmudflap/ChangeLog +++ b/libmudflap/ChangeLog @@ -1,3 +1,21 @@ +2004-10-12 Frank Ch. Eigler <fche@redhat.com> + + * configure.ac: Check for more headers, functions. + * mf-hooks2.c (mkbuffer, unmkbuffer): New helper functions for + tracking overridden FILE buffers. + (fopen, setvbuf): New/revised hook functions for buffer overriding. + (setbuf,setlinebuf,fdopen,freopen,fopen64,freopen64,fclose): Ditto. + (fflush): Accept given NULL stream (means "all streams"). + * mf-runtime.h.in: + * mf-runtime.c (__mfu_check): Accept accesses that span adjacent + HEAP/GUESS objects. + (LOOKUP_CACHE_SIZE_MAX): Raise to 64K entries tentatively. + (__mf_adapt_cache): Use them all. + * testsuite/libmudflap.c/pass35-frag.c: Update warning message. + * testsuite/libmudflap.c++/ctors.exp: Ditto. + * testsuite/libmudflap.c/{pass51,pass52}-frag.c: New tests. + * configure, config.h.in: Regenerated. + 2004-10-05 Frank Ch. Eigler <fche@redhat.com> * configure.ac: Checking for sys/socket.h once is enough. diff --git a/libmudflap/config.h.in b/libmudflap/config.h.in index 41e61948905..7685b575c26 100644 --- a/libmudflap/config.h.in +++ b/libmudflap/config.h.in @@ -33,6 +33,9 @@ /* Define to 1 if you have the `fopen64' function. */ #undef HAVE_FOPEN64 +/* Define to 1 if you have the `freopen64' function. */ +#undef HAVE_FREOPEN64 + /* Define to 1 if you have the `fseeko64' function. */ #undef HAVE_FSEEKO64 @@ -126,9 +129,15 @@ /* Define to 1 if you have the `memrchr' function. */ #undef HAVE_MEMRCHR +/* Define to 1 if you have the `mmap' function. */ +#undef HAVE_MMAP + /* Define to 1 if you have the <mntent.h> header file. */ #undef HAVE_MNTENT_H +/* Define to 1 if you have the `munmap' function. */ +#undef HAVE_MUNMAP + /* Define to 1 if you have the <netdb.h> header file. */ #undef HAVE_NETDB_H @@ -141,12 +150,24 @@ /* Define to 1 if you have the <pwd.h> header file. */ #undef HAVE_PWD_H +/* Define to 1 if you have the `setbuf' function. */ +#undef HAVE_SETBUF + +/* Define to 1 if you have the `setbuffer' function. */ +#undef HAVE_SETBUFFER + /* Define to 1 if you have the `sethostname' function. */ #undef HAVE_SETHOSTNAME +/* Define to 1 if you have the `setlinebuf' function. */ +#undef HAVE_SETLINEBUF + /* Define to 1 if you have the `setmntent' function. */ #undef HAVE_SETMNTENT +/* Define to 1 if you have the `setvbuf' function. */ +#undef HAVE_SETVBUF + /* Define to 1 if you have the `signal' function. */ #undef HAVE_SIGNAL @@ -180,6 +201,9 @@ /* Define to 1 if you have the <sys/ipc.h> header file. */ #undef HAVE_SYS_IPC_H +/* Define to 1 if you have the <sys/mman.h> header file. */ +#undef HAVE_SYS_MMAN_H + /* Define to 1 if you have the <sys/sem.h> header file. */ #undef HAVE_SYS_SEM_H diff --git a/libmudflap/configure b/libmudflap/configure index 9b838d941af..0b51fe5ae5d 100755 --- a/libmudflap/configure +++ b/libmudflap/configure @@ -3597,9 +3597,10 @@ done + for ac_header in stdint.h execinfo.h signal.h dlfcn.h dirent.h pwd.h grp.h \ netdb.h sys/ipc.h sys/sem.h sys/shm.h sys/wait.h ctype.h mntent.h \ - sys/socket.h netinet/in.h arpa/inet.h dlfcn.h + sys/socket.h netinet/in.h arpa/inet.h dlfcn.h sys/mman.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then @@ -3858,7 +3859,113 @@ done -for ac_func in fopen64 fseeko64 ftello64 stat64 + +for ac_func in fopen64 fseeko64 ftello64 stat64 freopen64 +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + + + +for ac_func in setbuf setbuffer setlinebuf setvbuf do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 @@ -4699,7 +4806,9 @@ fi done -for ac_func in inet_ntoa + + +for ac_func in inet_ntoa mmap munmap do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 @@ -5656,7 +5765,7 @@ test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic" case $host in *-*-irix6*) # Find out which ABI we are using. - echo '#line 5659 "configure"' > conftest.$ac_ext + echo '#line 5768 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? diff --git a/libmudflap/configure.ac b/libmudflap/configure.ac index c6e73378d17..9310b35c946 100644 --- a/libmudflap/configure.ac +++ b/libmudflap/configure.ac @@ -61,10 +61,11 @@ enable_shared=no]) AC_CHECK_HEADERS(stdint.h execinfo.h signal.h dlfcn.h dirent.h pwd.h grp.h \ netdb.h sys/ipc.h sys/sem.h sys/shm.h sys/wait.h ctype.h mntent.h \ - sys/socket.h netinet/in.h arpa/inet.h dlfcn.h) + sys/socket.h netinet/in.h arpa/inet.h dlfcn.h sys/mman.h) AC_CHECK_FUNCS(backtrace backtrace_symbols gettimeofday signal) -AC_CHECK_FUNCS(fopen64 fseeko64 ftello64 stat64) +AC_CHECK_FUNCS(fopen64 fseeko64 ftello64 stat64 freopen64) +AC_CHECK_FUNCS(setbuf setbuffer setlinebuf setvbuf) AC_CHECK_FUNCS(strnlen memrchr strncpy memmem sethostname) AC_CHECK_FUNCS(__ctype_b_loc __ctype_tolower_loc __ctype_toupper_loc) AC_CHECK_FUNCS(getlogin cuserid getpwnam getpwuid getpwent getgrnam getgrgid getgrent) @@ -72,7 +73,7 @@ AC_CHECK_FUNCS(getlogin_r getpwnam_r getpwuid_r getgrnam_r getgrgid_r) AC_CHECK_FUNCS(getservent getservbyname getservbyport getaddrinfo gai_strerror) AC_CHECK_FUNCS(getprotoent getprotobyname getprotobynumber) AC_CHECK_FUNCS(getmntent setmntent addmntent) -AC_CHECK_FUNCS(inet_ntoa) +AC_CHECK_FUNCS(inet_ntoa mmap munmap) AC_TRY_COMPILE([#include <sys/types.h> #include <sys/ipc.h> diff --git a/libmudflap/mf-hooks2.c b/libmudflap/mf-hooks2.c index 52ff3c1b4a8..5a001ad26b9 100644 --- a/libmudflap/mf-hooks2.c +++ b/libmudflap/mf-hooks2.c @@ -584,6 +584,66 @@ WRAPPER2(char *, strerror, int errnum) } + +/* An auxiliary data structure for tracking the hand-made stdio + buffers we generate during the fopen/fopen64 hooks. In a civilized + language, this would be a simple dynamically sized FILE*->char* + lookup table, but this is C and we get to do it by hand. */ +struct mf_filebuffer +{ + FILE *file; + char *buffer; + struct mf_filebuffer *next; +}; +static struct mf_filebuffer *mf_filebuffers = NULL; + +static void +mkbuffer (FILE *f) +{ + /* Reset any buffer automatically provided by libc, since this may + have been done via mechanisms that libmudflap couldn't + intercept. */ + int rc; + size_t bufsize = BUFSIZ; + int bufmode; + char *buffer = malloc (bufsize); + struct mf_filebuffer *b = malloc (sizeof (struct mf_filebuffer)); + assert ((buffer != NULL) && (b != NULL)); + + /* Link it into list. */ + b->file = f; + b->buffer = buffer; + b->next = mf_filebuffers; + mf_filebuffers = b; + + /* Determine how the file is supposed to be buffered at the moment. */ + bufmode = fileno (f) == 2 ? _IONBF : (isatty (fileno (f)) ? _IOLBF : _IOFBF); + + rc = setvbuf (f, buffer, bufmode, bufsize); + assert (rc == 0); +} + +static void +unmkbuffer (FILE *f) +{ + struct mf_filebuffer *b = mf_filebuffers; + struct mf_filebuffer **pb = & mf_filebuffers; + while (b != NULL) + { + if (b->file == f) + { + *pb = b->next; + free (b->buffer); + free (b); + return; + } + pb = & b->next; + b = b->next; + } +} + + + WRAPPER2(FILE *, fopen, const char *path, const char *mode) { size_t n; @@ -602,6 +662,106 @@ WRAPPER2(FILE *, fopen, const char *path, const char *mode) __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen result"); #endif MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen result"); + + mkbuffer (p); + } + + return p; +} + + +WRAPPER2(int, setvbuf, FILE *stream, char *buf, int mode, size_t size) +{ + int rc = 0; + TRACE ("%s\n", __PRETTY_FUNCTION__); + + MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, "setvbuf stream"); + + unmkbuffer (stream); + + if (buf != NULL) + MF_VALIDATE_EXTENT (buf, size, __MF_CHECK_WRITE, "setvbuf buffer"); + + /* Override the user only if it's an auto-allocated buffer request. Otherwise + assume that the supplied buffer is already known to libmudflap. */ + if ((buf == NULL) && ((mode == _IOFBF) || (mode == _IOLBF))) + mkbuffer (stream); + else + rc = setvbuf (stream, buf, mode, size); + + return rc; +} + + +#ifdef HAVE_SETBUF +WRAPPER2(int, setbuf, FILE* stream, char *buf) +{ + return __mfwrap_setvbuf (stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ); +} +#endif + +#ifdef HAVE_SETBUFFER +WRAPPER2(int, setbuffer, FILE* stream, char *buf, size_t sz) +{ + return __mfwrap_setvbuf (stream, buf, buf ? _IOFBF : _IONBF, sz); +} +#endif + +#ifdef HAVE_SETLINEBUF +WRAPPER2(int, setlinebuf, FILE* stream) +{ + return __mfwrap_setvbuf(stream, NULL, _IOLBF, 0); +} +#endif + + + +WRAPPER2(FILE *, fdopen, int fd, const char *mode) +{ + size_t n; + FILE *p; + TRACE ("%s\n", __PRETTY_FUNCTION__); + + n = strlen (mode); + MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "fdopen mode"); + + p = fdopen (fd, mode); + if (NULL != p) { +#ifdef MF_REGISTER_fopen + __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fdopen result"); +#endif + MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fdopen result"); + + mkbuffer (p); + } + + return p; +} + + +WRAPPER2(FILE *, freopen, const char *path, const char *mode, FILE *s) +{ + size_t n; + FILE *p; + TRACE ("%s\n", __PRETTY_FUNCTION__); + + n = strlen (path); + MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen path"); + + MF_VALIDATE_EXTENT (s, (sizeof (*s)), __MF_CHECK_WRITE, "freopen stream"); + unmkbuffer (s); + + n = strlen (mode); + MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen mode"); + + p = freopen (path, mode, s); + if (NULL != p) { +#ifdef MF_REGISTER_fopen + __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "freopen result"); +#endif + MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "freopen result"); + + mkbuffer (p); } return p; @@ -627,6 +787,39 @@ WRAPPER2(FILE *, fopen64, const char *path, const char *mode) __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "fopen64 result"); #endif MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "fopen64 result"); + + mkbuffer (p); + } + + return p; +} +#endif + + +#ifdef HAVE_FREOPEN64 +WRAPPER2(FILE *, freopen64, const char *path, const char *mode, FILE *s) +{ + size_t n; + FILE *p; + TRACE ("%s\n", __PRETTY_FUNCTION__); + + n = strlen (path); + MF_VALIDATE_EXTENT (path, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen64 path"); + + MF_VALIDATE_EXTENT (s, (sizeof (*s)), __MF_CHECK_WRITE, "freopen64 stream"); + unmkbuffer (s); + + n = strlen (mode); + MF_VALIDATE_EXTENT (mode, CLAMPADD(n, 1), __MF_CHECK_READ, "freopen64 mode"); + + p = freopen (path, mode, s); + if (NULL != p) { +#ifdef MF_REGISTER_fopen + __mf_register (p, sizeof (*p), MF_REGISTER_fopen, "freopen64 result"); +#endif + MF_VALIDATE_EXTENT (p, sizeof (*p), __MF_CHECK_WRITE, "freopen64 result"); + + mkbuffer (p); } return p; @@ -644,6 +837,7 @@ WRAPPER2(int, fclose, FILE *stream) #ifdef MF_REGISTER_fopen __mf_unregister (stream, sizeof (*stream), MF_REGISTER_fopen); #endif + unmkbuffer (stream); return resp; } @@ -943,8 +1137,9 @@ WRAPPER2(int , remove, const char *path) WRAPPER2(int, fflush, FILE *stream) { TRACE ("%s\n", __PRETTY_FUNCTION__); - MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, - "fflush stream"); + if (stream != NULL) + MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, + "fflush stream"); return fflush (stream); } @@ -1071,28 +1266,6 @@ WRAPPER2(int , mkfifo, const char *path, mode_t mode) } -WRAPPER2(int, setvbuf, FILE *stream, char *buf, int mode , size_t size) -{ - TRACE ("%s\n", __PRETTY_FUNCTION__); - MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, - "setvbuf stream"); - if (NULL != buf) - MF_VALIDATE_EXTENT (buf, size, __MF_CHECK_READ, "setvbuf buf"); - return setvbuf (stream, buf, mode, size); -} - - -WRAPPER2(void, setbuf, FILE *stream, char *buf) -{ - TRACE ("%s\n", __PRETTY_FUNCTION__); - MF_VALIDATE_EXTENT (stream, sizeof (*stream), __MF_CHECK_WRITE, - "setbuf stream"); - if (NULL != buf) - MF_VALIDATE_EXTENT (buf, BUFSIZ, __MF_CHECK_READ, "setbuf buf"); - setbuf (stream, buf); -} - - #ifdef HAVE_DIRENT_H WRAPPER2(DIR *, opendir, const char *path) { diff --git a/libmudflap/mf-runtime.c b/libmudflap/mf-runtime.c index a0f9f739f53..64b1842766c 100644 --- a/libmudflap/mf-runtime.c +++ b/libmudflap/mf-runtime.c @@ -160,7 +160,7 @@ static void mfsplay_tree_rebalance (mfsplay_tree sp); /* Required globals. */ #define LOOKUP_CACHE_MASK_DFL 1023 -#define LOOKUP_CACHE_SIZE_MAX 4096 /* Allows max CACHE_MASK 0x0FFF */ +#define LOOKUP_CACHE_SIZE_MAX 65536 /* Allows max CACHE_MASK 0xFFFF */ #define LOOKUP_CACHE_SHIFT_DFL 2 struct __mf_cache __mf_lookup_cache [LOOKUP_CACHE_SIZE_MAX]; @@ -917,7 +917,7 @@ void __mfu_check (void *ptr, size_t sz, int type, const char *location) judgement = -1; } - /* We now know that the access spans one or more valid objects. */ + /* We now know that the access spans one or more only valid objects. */ if (LIKELY (judgement >= 0)) for (i = 0; i < obj_count; i++) { @@ -931,12 +931,58 @@ void __mfu_check (void *ptr, size_t sz, int type, const char *location) entry->high = obj->high; judgement = 1; } + } + + /* This access runs off the end of one valid object. That + could be okay, if other valid objects fill in all the + holes. We allow this only for HEAP and GUESS type + objects. Accesses to STATIC and STACK variables + should not be allowed to span. */ + if (UNLIKELY ((judgement == 0) && (obj_count > 1))) + { + unsigned uncovered = 0; + for (i = 0; i < obj_count; i++) + { + __mf_object_t *obj = all_ovr_obj[i]; + int j, uncovered_low_p, uncovered_high_p; + uintptr_t ptr_lower, ptr_higher; + + uncovered_low_p = ptr_low < obj->low; + ptr_lower = CLAMPSUB (obj->low, 1); + uncovered_high_p = ptr_high > obj->high; + ptr_higher = CLAMPADD (obj->high, 1); - /* XXX: Access runs off left or right side of this - object. That could be okay, if there are - other objects that fill in all the holes. */ + for (j = 0; j < obj_count; j++) + { + __mf_object_t *obj2 = all_ovr_obj[j]; + + if (i == j) continue; + + /* Filter out objects that cannot be spanned across. */ + if (obj2->type == __MF_TYPE_STACK + || obj2->type == __MF_TYPE_STATIC) + continue; + + /* Consider a side "covered" if obj2 includes + the next byte on that side. */ + if (uncovered_low_p + && (ptr_lower >= obj2->low && ptr_lower <= obj2->high)) + uncovered_low_p = 0; + if (uncovered_high_p + && (ptr_high >= obj2->low && ptr_higher <= obj2->high)) + uncovered_high_p = 0; + } + + if (uncovered_low_p || uncovered_high_p) + uncovered ++; + } + + /* Success if no overlapping objects are uncovered. */ + if (uncovered == 0) + judgement = 1; } + if (dealloc_me != NULL) CALL_REAL (free, dealloc_me); @@ -1413,7 +1459,7 @@ __mf_adapt_cache () cache_utilization += 1.0; cache_utilization /= (1 + __mf_lc_mask); - new_mask |= 0x3ff; /* XXX: force a large cache. */ + new_mask |= 0xffff; /* XXX: force a large cache. */ new_mask &= (LOOKUP_CACHE_SIZE_MAX - 1); VERBOSE_TRACE ("adapt cache obj=%u/%u sizes=%lu/%.0f/%.0f => " diff --git a/libmudflap/mf-runtime.h.in b/libmudflap/mf-runtime.h.in index 298ed6efa8a..0f8f9e3e2b1 100644 --- a/libmudflap/mf-runtime.h.in +++ b/libmudflap/mf-runtime.h.in @@ -108,6 +108,8 @@ extern int __mf_set_options (const char *opts); #pragma redefine_extname time __mfwrap_time #pragma redefine_extname strerror __mfwrap_strerror #pragma redefine_extname fopen __mfwrap_fopen +#pragma redefine_extname fdopen __mfwrap_fdopen +#pragma redefine_extname freopen __mfwrap_freopen #pragma redefine_extname fclose __mfwrap_fclose #pragma redefine_extname fread __mfwrap_fread #pragma redefine_extname fwrite __mfwrap_fwrite @@ -146,6 +148,8 @@ extern int __mf_set_options (const char *opts); #pragma redefine_extname mkfifo __mfwrap_mkfifo #pragma redefine_extname setvbuf __mfwrap_setvbuf #pragma redefine_extname setbuf __mfwrap_setbuf +#pragma redefine_extname setbuffer __mfwrap_setbuffer +#pragma redefine_extname setlinebuf __mfwrap_setlinebuf #pragma redefine_extname opendir __mfwrap_opendir #pragma redefine_extname closedir __mfwrap_closedir #pragma redefine_extname readdir __mfwrap_readdir @@ -176,6 +180,7 @@ extern int __mf_set_options (const char *opts); #pragma redefine_extname dlsym __mfwrap_dlsym #pragma redefine_extname dlclose __mfwrap_dlclose #pragma redefine_extname fopen64 __mfwrap_fopen64 +#pragma redefine_extname freopen64 __mfwrap_freopen64 #pragma redefine_extname stat64 __mfwrap_stat64 #pragma redefine_extname fseeko64 __mfwrap_fseeko64 #pragma redefine_extname ftello64 __mfwrap_ftello64 diff --git a/libmudflap/testsuite/libmudflap.c++/ctors.exp b/libmudflap/testsuite/libmudflap.c++/ctors.exp index a160bc9d340..5d4f1efff61 100644 --- a/libmudflap/testsuite/libmudflap.c++/ctors.exp +++ b/libmudflap/testsuite/libmudflap.c++/ctors.exp @@ -8,7 +8,7 @@ global srcdir subdir foreach flags [list {} {-static} {-O2} {-O3}] { set l1 [libmudflap_target_compile "$srcdir/$subdir/ctors-1.cxx" "ctors-1.o" object {additional_flags=-fmudflap}] set test "ctors-1 compilation ${flags}" - if [string match "*mudflap cannot track lifetime of*k*" $l1] { pass $test } { fail $test } + if [string match "*mudflap cannot track unknown size extern *k*" $l1] { pass $test } { fail $test } set l2 [libmudflap_target_compile "$srcdir/$subdir/ctors-2.cxx" "ctors-2.o" object {additional_flags=-fmudflap}] set test "ctors-2 compilation ${flags}" diff --git a/libmudflap/testsuite/libmudflap.c/pass35-frag.c b/libmudflap/testsuite/libmudflap.c/pass35-frag.c index dbd9737a92e..95dafab836d 100644 --- a/libmudflap/testsuite/libmudflap.c/pass35-frag.c +++ b/libmudflap/testsuite/libmudflap.c/pass35-frag.c @@ -3,7 +3,7 @@ #include <string.h> extern char end []; /* Any old symbol we're sure will be defined. */ -/* { dg-warning "cannot track lifetime of 'end'" "cannot track lifetime" { target *-*-* } 0 } */ +/* { dg-warning "cannot track unknown size extern 'end'" "cannot track unknown size extern" { target *-*-* } 0 } */ int main () { diff --git a/libmudflap/testsuite/libmudflap.c/pass51-frag.c b/libmudflap/testsuite/libmudflap.c/pass51-frag.c new file mode 100644 index 00000000000..b830b3a869d --- /dev/null +++ b/libmudflap/testsuite/libmudflap.c/pass51-frag.c @@ -0,0 +1,41 @@ +/* Test object-spanning accesses. This is most conveniently done with + mmap, thus the config.h specificity here. */ +#include "../config.h" + +#include <unistd.h> +#include <string.h> +#ifdef HAVE_SYS_MMAN_H +#include <sys/mman.h> +#endif + +int main () +{ +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif +#ifdef HAVE_MMAP + void *p; + unsigned pg = getpagesize (); + int rc; + + p = mmap (NULL, 4 * pg, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); + if (p == NULL) + return 1; + + memset (p, 0, 4*pg); + rc = munmap (p, pg); + if (rc < 0) return 1; + memset (p+pg, 0, 3*pg); + rc = munmap (p+pg, pg); + if (rc < 0) return 1; + memset (p+2*pg, 0, 2*pg); + rc = munmap (p+2*pg, pg); + if (rc < 0) return 1; + memset (p+3*pg, 0, pg); + rc = munmap (p+3*pg, pg); + if (rc < 0) return 1; +#endif + + return 0; +} diff --git a/libmudflap/testsuite/libmudflap.c/pass52-frag.c b/libmudflap/testsuite/libmudflap.c/pass52-frag.c new file mode 100644 index 00000000000..7ff9d577ba7 --- /dev/null +++ b/libmudflap/testsuite/libmudflap.c/pass52-frag.c @@ -0,0 +1,36 @@ +#include <stdio.h> + + +void writestuff (FILE *f) +{ + fprintf (f, "hello world\n"); + fputc ('y', f); + putc ('e', f); +} + +void readstuff (FILE *f) +{ + int c, d; + char stuff[100], *s; + c = fgetc (f); + ungetc (c, f); + d = fgetc (f); + s = fgets (stuff, sizeof(stuff), f); +} + +int main () +{ + FILE *f; + writestuff (stdout); + writestuff (stderr); + f = fopen ("/dev/null", "w"); + writestuff (f); + fclose (f); + f = fopen ("/dev/zero", "r"); + readstuff (f); + f = freopen ("/dev/null", "w", f); + writestuff (f); + fclose (f); + + return 0; +} |