X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=libmudflap%2Fmf-hooks1.c;fp=libmudflap%2Fmf-hooks1.c;h=e74c13afcced4e1f819920607c4cad32b11e645e;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=0000000000000000000000000000000000000000;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/libmudflap/mf-hooks1.c b/libmudflap/mf-hooks1.c new file mode 100644 index 00000000..e74c13af --- /dev/null +++ b/libmudflap/mf-hooks1.c @@ -0,0 +1,495 @@ +/* Mudflap: narrow-pointer bounds-checking by tree rewriting. + Copyright (C) 2002, 2003, 2004, 2009 Free Software Foundation, Inc. + Contributed by Frank Ch. Eigler + and Graydon Hoare + +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 3, or (at your option) any later +version. + +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. + +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" + +#ifndef HAVE_SOCKLEN_T +#define socklen_t int +#endif + + +/* These attempt to coax various unix flavours to declare all our + needed tidbits in the system headers. */ +#if !defined(__FreeBSD__) && !defined(__APPLE__) +#define _POSIX_SOURCE +#endif /* Some BSDs break if this is defined. */ +#define _GNU_SOURCE +#define _XOPEN_SOURCE +#define _BSD_TYPES +#define __EXTENSIONS__ +#define _ALL_SOURCE +#define _LARGE_FILE_API +#define _XOPEN_SOURCE_EXTENDED 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mf-runtime.h" +#include "mf-impl.h" + +#ifdef _MUDFLAP +#error "Do not compile this file with -fmudflap!" +#endif + + +/* Memory allocation related hook functions. Some of these are + intercepted via linker wrapping or symbol interposition. Others + use plain macros in mf-runtime.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) +{ + unsigned i; + + for (i=0; i= (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)) + { + memset (free_queue, 0, + __MF_FREEQ_MAX * sizeof (void *)); + freeq_initialized = 1; + } + UNLOCKTH (); + + __mf_unregister (buf, 0, __MF_TYPE_HEAP_I); + /* NB: underlying region may have been __MF_TYPE_HEAP. */ + + if (UNLIKELY(__mf_opts.free_queue_length > 0)) + { + char *freeme = NULL; + LOCKTH (); + if (free_queue [free_ptr] != NULL) + { + freeme = free_queue [free_ptr]; + freeme -= __mf_opts.crumple_zone; + } + free_queue [free_ptr] = buf; + free_ptr = (free_ptr == (__mf_opts.free_queue_length-1) ? 0 : free_ptr + 1); + UNLOCKTH (); + if (freeme) + { + if (__mf_opts.trace_mf_calls) + { + VERBOSE_TRACE ("freeing deferred pointer %p (crumple %u)\n", + (void *) freeme, + __mf_opts.crumple_zone); + } + BEGIN_MALLOC_PROTECT (); + CALL_REAL (free, freeme); + END_MALLOC_PROTECT (); + } + } + else + { + /* back pointer up a bit to the beginning of crumple zone */ + char *base = (char *)buf; + base -= __mf_opts.crumple_zone; + if (__mf_opts.trace_mf_calls) + { + VERBOSE_TRACE ("freeing pointer %p = %p - %u\n", + (void *) base, + (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) +{ + return (void *) -1; +} +#endif + + +#undef mmap +WRAPPER(void *, mmap, + void *start, size_t length, int prot, + int flags, int fd, off_t offset) +{ + DECLARE(void *, mmap, void *, size_t, int, + int, int, off_t); + void *result; + BEGIN_PROTECT (mmap, start, length, prot, flags, fd, offset); + + result = CALL_REAL (mmap, start, length, prot, + flags, fd, offset); + + /* + VERBOSE_TRACE ("mmap (%08lx, %08lx, ...) => %08lx\n", + (uintptr_t) start, (uintptr_t) length, + (uintptr_t) result); + */ + + if (result != (void *)-1) + { + /* Register each page as a heap object. Why not register it all + as a single segment? That's so that a later munmap() call + can unmap individual pages. XXX: would __MF_TYPE_GUESS make + this more automatic? */ + size_t ps = getpagesize (); + uintptr_t base = (uintptr_t) result; + uintptr_t offset; + + for (offset=0; offset %08lx\n", + (uintptr_t) start, (uintptr_t) length, + (uintptr_t) result); + */ + + if (result == 0) + { + /* Unregister each page as a heap object. */ + size_t ps = getpagesize (); + uintptr_t base = (uintptr_t) start & (~ (ps - 1)); /* page align */ + uintptr_t offset; + + for (offset=0; offsetstack DEEPER_THAN (uintptr_t) stack)) + { + 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; + } + + /* Allocate new block. */ + 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 + { + __mf_register (result, c, __MF_TYPE_HEAP, "alloca region"); + track->ptr = result; + track->stack = stack; + track->next = alloca_history; + alloca_history = track; + } + } + } + + return result; +} + + +#undef alloca +WRAPPER(void *, alloca, size_t c) +{ + return __mf_wrap_alloca_indirect (c); +} +