X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=libmudflap%2Fmf-runtime.c;h=25e49ba9d997554ee6d100f5eb6e29fc82a8c518;hb=fc95ed714b3eaebb5a4080d29e01776d5b3927e8;hp=e6901650975735fa257fb62726070ab37d5d96b5;hpb=55e575c08fe16651b986fb3dbb03441d3b638ffc;p=pf3gnuchains%2Fgcc-fork.git diff --git a/libmudflap/mf-runtime.c b/libmudflap/mf-runtime.c index e6901650975..25e49ba9d99 100644 --- a/libmudflap/mf-runtime.c +++ b/libmudflap/mf-runtime.c @@ -1,5 +1,6 @@ /* Mudflap: narrow-pointer bounds-checking by tree rewriting. - Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 + Free Software Foundation, Inc. Contributed by Frank Ch. Eigler and Graydon Hoare Splay Tree code originally by Mark Mitchell , @@ -9,27 +10,22 @@ This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later +Software Foundation; either version 3, or (at your option) any later version. -In addition to the permissions in the GNU General Public License, the -Free Software Foundation gives you unlimited permission to link the -compiled version of this file into combinations with other programs, -and to distribute those combinations without any restriction coming -from the use of this file. (The General Public License restrictions -do apply in other respects; for example, they cover modification of -the file, and distribution when not linked into a combine -executable.) - GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ #include "config.h" @@ -177,7 +173,7 @@ struct __mf_options __mf_opts; int __mf_starting_p = 1; #ifdef LIBMUDFLAPTH -#ifdef HAVE_TLS +#if defined(HAVE_TLS) && !defined(USE_EMUTLS) __thread enum __mf_state_enum __mf_state_1 = reentrant; #endif #else @@ -300,13 +296,24 @@ __mf_set_default_options () __mf_opts.timestamps = 1; __mf_opts.mudflap_mode = mode_check; __mf_opts.violation_mode = viol_nop; +#ifdef HAVE___LIBC_FREERES + __mf_opts.call_libc_freeres = 1; +#endif __mf_opts.heur_std_data = 1; #ifdef LIBMUDFLAPTH __mf_opts.thread_stack = 0; #endif + + /* PR41443: Beware that the above flags will be applied to + setuid/setgid binaries, and cannot be overriden with + $MUDFLAP_OPTIONS. So the defaults must be non-exploitable. + + Should we consider making the default violation_mode something + harsher than viol_nop? OTOH, glibc's MALLOC_CHECK_ is disabled + by default for these same programs. */ } -static struct option +static struct mudoption { char *name; char *description; @@ -365,6 +372,11 @@ options [] = {"print-leaks", "print any memory leaks at program shutdown", set_option, 1, &__mf_opts.print_leaks}, +#ifdef HAVE___LIBC_FREERES + {"libc-freeres", + "call glibc __libc_freeres at shutdown for better leak data", + set_option, 1, &__mf_opts.call_libc_freeres}, +#endif {"check-initialization", "detect uninitialized object reads", set_option, 1, &__mf_opts.check_initialization}, @@ -432,13 +444,13 @@ options [] = static void __mf_usage () { - struct option *opt; + struct mudoption *opt; fprintf (stderr, "This is a %s%sGCC \"mudflap\" memory-checked binary.\n" - "Mudflap is Copyright (C) 2002-2004 Free Software Foundation, Inc.\n" + "Mudflap is Copyright (C) 2002-2010 Free Software Foundation, Inc.\n" "\n" - "The mudflap code can be controlled by an environment variable:\n" + "Unless setuid, a program's mudflap options be set by an environment variable:\n" "\n" "$ export MUDFLAP_OPTIONS=''\n" "$ \n" @@ -506,7 +518,7 @@ __mf_set_options (const char *optstr) int __mfu_set_options (const char *optstr) { - struct option *opts = 0; + struct mudoption *opts = 0; char *nxt = 0; long tmp = 0; int rc = 0; @@ -691,6 +703,12 @@ __mf_init () if (LIKELY (__mf_starting_p == 0)) return; +#if defined(__FreeBSD__) && defined(LIBMUDFLAPTH) + pthread_self(); + LOCKTH (); + UNLOCKTH (); +#endif /* Prime mutex which calls calloc upon first lock to avoid deadlock. */ + /* This initial bootstrap phase requires that __mf_starting_p = 1. */ #ifdef PIC __mf_resolve_dynamics (); @@ -701,7 +719,8 @@ __mf_init () __mf_set_default_options (); - ov = getenv ("MUDFLAP_OPTIONS"); + if (getuid () == geteuid () && getgid () == getegid ()) /* PR41433, not setuid */ + ov = getenv ("MUDFLAP_OPTIONS"); if (ov) { int rc = __mfu_set_options (ov); @@ -1071,24 +1090,80 @@ __mf_uncache_object (__mf_object_t *old_obj) /* Can it possibly exist in the cache? */ if (LIKELY (old_obj->read_count + old_obj->write_count)) { - /* As reported by Herman ten Brugge, we need to scan the entire - cache for entries that may hit this object. */ uintptr_t low = old_obj->low; uintptr_t high = old_obj->high; - struct __mf_cache *entry = & __mf_lookup_cache [0]; + struct __mf_cache *entry; unsigned i; - for (i = 0; i <= __mf_lc_mask; i++, entry++) - { - /* NB: the "||" in the following test permits this code to - tolerate the situation introduced by __mf_check over - contiguous objects, where a cache entry spans several - objects. */ - if (entry->low == low || entry->high == high) + if ((high - low) >= (__mf_lc_mask << __mf_lc_shift)) + { + /* For large objects (>= cache size - 1) check the whole cache. */ + entry = & __mf_lookup_cache [0]; + for (i = 0; i <= __mf_lc_mask; i++, entry++) { - entry->low = MAXPTR; - entry->high = MINPTR; + /* NB: the "||" in the following test permits this code to + tolerate the situation introduced by __mf_check over + contiguous objects, where a cache entry spans several + objects. */ + if (entry->low == low || entry->high == high) + { + entry->low = MAXPTR; + entry->high = MINPTR; + } } } + else + { + /* Object is now smaller then cache size. */ + unsigned entry_low_idx = __MF_CACHE_INDEX (low); + unsigned entry_high_idx = __MF_CACHE_INDEX (high); + if (entry_low_idx <= entry_high_idx) + { + entry = & __mf_lookup_cache [entry_low_idx]; + for (i = entry_low_idx; i <= entry_high_idx; i++, entry++) + { + /* NB: the "||" in the following test permits this code to + tolerate the situation introduced by __mf_check over + contiguous objects, where a cache entry spans several + objects. */ + if (entry->low == low || entry->high == high) + { + entry->low = MAXPTR; + entry->high = MINPTR; + } + } + } + else + { + /* Object wrapped around the end of the cache. First search + from low to end of cache and then from 0 to high. */ + entry = & __mf_lookup_cache [entry_low_idx]; + for (i = entry_low_idx; i <= __mf_lc_mask; i++, entry++) + { + /* NB: the "||" in the following test permits this code to + tolerate the situation introduced by __mf_check over + contiguous objects, where a cache entry spans several + objects. */ + if (entry->low == low || entry->high == high) + { + entry->low = MAXPTR; + entry->high = MINPTR; + } + } + entry = & __mf_lookup_cache [0]; + for (i = 0; i <= entry_high_idx; i++, entry++) + { + /* NB: the "||" in the following test permits this code to + tolerate the situation introduced by __mf_check over + contiguous objects, where a cache entry spans several + objects. */ + if (entry->low == low || entry->high == high) + { + entry->low = MAXPTR; + entry->high = MINPTR; + } + } + } + } } } @@ -1323,10 +1398,15 @@ __mfu_unregister (void *ptr, size_t sz, int type) (old_obj->type == __MF_TYPE_HEAP || old_obj->type == __MF_TYPE_HEAP_I)) { + /* The problem with a warning message here is that we may not + be privy to accesses to such objects that occur within + uninstrumented libraries. */ +#if 0 fprintf (stderr, "*******\n" "mudflap warning: unaccessed registered object:\n"); __mf_describe_object (old_obj); +#endif } } @@ -1855,6 +1935,14 @@ __mfu_report () /* Free up any remaining alloca()'d blocks. */ __mf_wrap_alloca_indirect (0); +#ifdef HAVE___LIBC_FREERES + if (__mf_opts.call_libc_freeres) + { + extern void __libc_freeres (void); + __libc_freeres (); + } +#endif + __mf_describe_object (NULL); /* Reset description epoch. */ l = __mf_report_leaks (); fprintf (stderr, "number of leaked objects: %u\n", l);