/* 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>
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"
#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;
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))
{
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);
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. */
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))
{
(void *) freeme,
__mf_opts.crumple_zone);
}
+ BEGIN_MALLOC_PROTECT ();
CALL_REAL (free, freeme);
+ END_MALLOC_PROTECT ();
}
}
else
(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 *
__mf_0fn_mmap (void *start, size_t l, int prot, int f, int fd, off_t off)
{
+#if defined(__FreeBSD__)
+ if (f == 0x1000 && fd == -1 && prot == 0 && off == 0)
+ return 0;
+#endif /* Ignore red zone allocation request for initial thread's stack. */
+
return (void *) -1;
}
#endif
}
return result;
}
+#endif /* HAVE_MMAP */
/* This wrapper is a little different, as it's called indirectly from
{
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;
}
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