OSDN Git Service

libiberty/:
[pf3gnuchains/gcc-fork.git] / libmudflap / mf-hooks1.c
index 0700d9a..e74c13a 100644 (file)
@@ -1,5 +1,5 @@
 /* Mudflap: narrow-pointer bounds-checking by tree rewriting.
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2009 Free Software Foundation, Inc.
    Contributed by Frank Ch. Eigler <fche@redhat.com>
    and Graydon Hoare <graydon@redhat.com>
 
@@ -7,28 +7,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, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, 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
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 
@@ -75,21 +69,24 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 
 
 #if PIC
+
+enum { BS = 4096, NB=10 };
+static char __mf_0fn_bufs[NB][BS];
+static unsigned __mf_0fn_bufs_used[NB];
+
+
 /* A special bootstrap variant. */
 void *
 __mf_0fn_malloc (size_t c)
 {
-  enum foo { BS = 4096, NB=10 };
-  static char bufs[NB][BS];
-  static unsigned bufs_used[NB];
   unsigned i;
 
   for (i=0; i<NB; i++)
     {
-      if (! bufs_used[i] && c < BS)
+      if (! __mf_0fn_bufs_used[i] && c < BS)
        {
-         bufs_used[i] = 1;
-         return & bufs[i][0];
+         __mf_0fn_bufs_used[i] = 1;
+         return & __mf_0fn_bufs[i][0];
        }
     }
   return NULL;
@@ -108,7 +105,9 @@ WRAPPER(void *, malloc, size_t c)
   size_with_crumple_zones =
     CLAMPADD(c,CLAMPADD(__mf_opts.crumple_zone,
                        __mf_opts.crumple_zone));
+  BEGIN_MALLOC_PROTECT ();
   result = (char *) CALL_REAL (malloc, size_with_crumple_zones);
+  END_MALLOC_PROTECT ();
 
   if (LIKELY(result))
     {
@@ -145,7 +144,9 @@ WRAPPER(void *, calloc, size_t c, size_t n)
     CLAMPADD((c * n), /* XXX: CLAMPMUL */
             CLAMPADD(__mf_opts.crumple_zone,
                      __mf_opts.crumple_zone));
+  BEGIN_MALLOC_PROTECT ();
   result = (char *) CALL_REAL (malloc, size_with_crumple_zones);
+  END_MALLOC_PROTECT ();
 
   if (LIKELY(result))
     memset (result, 0, size_with_crumple_zones);
@@ -187,7 +188,9 @@ WRAPPER(void *, realloc, void *buf, size_t c)
   size_with_crumple_zones =
     CLAMPADD(c, CLAMPADD(__mf_opts.crumple_zone,
                         __mf_opts.crumple_zone));
+  BEGIN_MALLOC_PROTECT ();
   result = (char *) CALL_REAL (realloc, base, size_with_crumple_zones);
+  END_MALLOC_PROTECT ();
 
   /* Ensure heap wiping doesn't occur during this peculiar
      unregister/reregister pair.  */
@@ -240,6 +243,19 @@ WRAPPER(void, free, void *buf)
   if (UNLIKELY(buf == NULL))
     return;
 
+#if PIC
+  /* Check whether the given buffer might have come from a
+     __mf_0fn_malloc/calloc call that for whatever reason was not
+     redirected back to __mf_0fn_free.  If so, we just ignore the
+     call. */
+  if (UNLIKELY((uintptr_t) buf >= (uintptr_t) __mf_0fn_bufs &&
+               (uintptr_t) buf < ((uintptr_t) __mf_0fn_bufs + sizeof(__mf_0fn_bufs))))
+  {
+    VERBOSE_TRACE ("skipping free of boot (0fn) alloc buffer %p\n", buf);
+    return;
+  }
+#endif
+
   LOCKTH ();
   if (UNLIKELY(!freeq_initialized))
     {
@@ -272,7 +288,9 @@ WRAPPER(void, free, void *buf)
                             (void *) freeme,
                             __mf_opts.crumple_zone);
            }
+         BEGIN_MALLOC_PROTECT ();
          CALL_REAL (free, freeme);
+         END_MALLOC_PROTECT ();
        }
     }
   else
@@ -287,11 +305,17 @@ WRAPPER(void, free, void *buf)
                         (void *) buf,
                         __mf_opts.crumple_zone);
        }
+      BEGIN_MALLOC_PROTECT ();
       CALL_REAL (free, base);
+      END_MALLOC_PROTECT ();
     }
 }
 
 
+/* We can only wrap mmap if the target supports it.  Likewise for munmap.
+   We assume we have both if we have mmap.  */
+#ifdef HAVE_MMAP
+
 #if PIC
 /* A special bootstrap variant. */
 void *
@@ -382,6 +406,7 @@ WRAPPER(int , munmap, void *start, size_t length)
     }
   return result;
 }
+#endif /* HAVE_MMAP */
 
 
 /* This wrapper is a little different, as it's called indirectly from
@@ -420,8 +445,10 @@ __mf_wrap_alloca_indirect (size_t c)
     {
       struct alloca_tracking *next = alloca_history->next;
       __mf_unregister (alloca_history->ptr, 0, __MF_TYPE_HEAP);
+      BEGIN_MALLOC_PROTECT ();
       CALL_REAL (free, alloca_history->ptr);
       CALL_REAL (free, alloca_history);
+      END_MALLOC_PROTECT ();
       alloca_history = next;
     }
 
@@ -429,14 +456,20 @@ __mf_wrap_alloca_indirect (size_t c)
   result = NULL;
   if (LIKELY (c > 0)) /* alloca(0) causes no allocation.  */
     {
+      BEGIN_MALLOC_PROTECT ();
       track = (struct alloca_tracking *) CALL_REAL (malloc,
                                                    sizeof (struct alloca_tracking));
+      END_MALLOC_PROTECT ();
       if (LIKELY (track != NULL))
        {
+         BEGIN_MALLOC_PROTECT ();
          result = CALL_REAL (malloc, c);
+         END_MALLOC_PROTECT ();
          if (UNLIKELY (result == NULL))
            {
+             BEGIN_MALLOC_PROTECT ();
              CALL_REAL (free, track);
+             END_MALLOC_PROTECT ();
              /* Too bad.  XXX: What about errno?  */
            }
          else