1169695Skan/* Mudflap: narrow-pointer bounds-checking by tree rewriting. 2169695Skan Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 3169695Skan Contributed by Frank Ch. Eigler <fche@redhat.com> 4169695Skan and Graydon Hoare <graydon@redhat.com> 5169695Skan 6169695SkanThis file is part of GCC. 7169695Skan 8169695SkanGCC is free software; you can redistribute it and/or modify it under 9169695Skanthe terms of the GNU General Public License as published by the Free 10169695SkanSoftware Foundation; either version 2, or (at your option) any later 11169695Skanversion. 12169695Skan 13169695SkanIn addition to the permissions in the GNU General Public License, the 14169695SkanFree Software Foundation gives you unlimited permission to link the 15169695Skancompiled version of this file into combinations with other programs, 16169695Skanand to distribute those combinations without any restriction coming 17169695Skanfrom the use of this file. (The General Public License restrictions 18169695Skando apply in other respects; for example, they cover modification of 19169695Skanthe file, and distribution when not linked into a combine 20169695Skanexecutable.) 21169695Skan 22169695SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY 23169695SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or 24169695SkanFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 25169695Skanfor more details. 26169695Skan 27169695SkanYou should have received a copy of the GNU General Public License 28169695Skanalong with GCC; see the file COPYING. If not, write to the Free 29169695SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 30169695Skan02110-1301, USA. */ 31169695Skan 32169695Skan 33169695Skan#include "config.h" 34169695Skan 35169695Skan#ifndef HAVE_SOCKLEN_T 36169695Skan#define socklen_t int 37169695Skan#endif 38169695Skan 39169695Skan/* These attempt to coax various unix flavours to declare all our 40169695Skan needed tidbits in the system headers. */ 41169695Skan#if !defined(__FreeBSD__) && !defined(__APPLE__) 42169695Skan#define _POSIX_SOURCE 43169695Skan#endif /* Some BSDs break <sys/socket.h> if this is defined. */ 44169695Skan#define _GNU_SOURCE 45169695Skan#define _XOPEN_SOURCE 46169695Skan#define _BSD_TYPES 47169695Skan#define __EXTENSIONS__ 48169695Skan#define _ALL_SOURCE 49169695Skan#define _LARGE_FILE_API 50169695Skan#define _XOPEN_SOURCE_EXTENDED 1 51169695Skan 52169695Skan#include <string.h> 53169695Skan#include <stdio.h> 54169695Skan#include <stdlib.h> 55169695Skan#include <unistd.h> 56169695Skan#include <assert.h> 57169695Skan#include <errno.h> 58169695Skan#include <stdbool.h> 59169695Skan 60169695Skan#include "mf-runtime.h" 61169695Skan#include "mf-impl.h" 62169695Skan 63169695Skan#ifdef _MUDFLAP 64169695Skan#error "Do not compile this file with -fmudflap!" 65169695Skan#endif 66169695Skan 67169695Skan#ifndef LIBMUDFLAPTH 68169695Skan#error "pthreadstuff is to be included only in libmudflapth" 69169695Skan#endif 70169695Skan 71169695Skan/* ??? Why isn't this done once in the header files. */ 72169695SkanDECLARE(void *, malloc, size_t sz); 73169695SkanDECLARE(void, free, void *ptr); 74169695SkanDECLARE(int, pthread_create, pthread_t *thr, const pthread_attr_t *attr, 75169695Skan void * (*start) (void *), void *arg); 76169695Skan 77169695Skan 78169695Skan/* Multithreading support hooks. */ 79169695Skan 80169695Skan 81169695Skan#ifndef HAVE_TLS 82169695Skan/* We don't have TLS. Ordinarily we could use pthread keys, but since we're 83169695Skan commandeering malloc/free that presents a few problems. The first is that 84169695Skan we'll recurse from __mf_get_state to pthread_setspecific to malloc back to 85169695Skan __mf_get_state during thread startup. This can be solved with clever uses 86169695Skan of a mutex. The second problem is that thread shutdown is indistinguishable 87169695Skan from thread startup, since libpthread is deallocating our state variable. 88169695Skan I've no good solution for this. 89169695Skan 90169695Skan Which leaves us to handle this mess by totally by hand. */ 91169695Skan 92169695Skan/* Yes, we want this prime. If pthread_t is a pointer, it's almost always 93169695Skan page aligned, and if we use a smaller power of 2, this results in "%N" 94169695Skan being the worst possible hash -- all threads hash to zero. */ 95169695Skan#define LIBMUDFLAPTH_THREADS_MAX 1021 96169695Skan 97169695Skanstruct mf_thread_data 98169695Skan{ 99169695Skan pthread_t self; 100169695Skan unsigned char used_p; 101169695Skan unsigned char state; 102169695Skan}; 103169695Skan 104169695Skanstatic struct mf_thread_data mf_thread_data[LIBMUDFLAPTH_THREADS_MAX]; 105169695Skanstatic pthread_mutex_t mf_thread_data_lock = PTHREAD_MUTEX_INITIALIZER; 106169695Skan 107169695Skan#define PTHREAD_HASH(p) ((unsigned long) (p) % LIBMUDFLAPTH_THREADS_MAX) 108169695Skan 109169695Skanstatic struct mf_thread_data * 110169695Skan__mf_find_threadinfo (int alloc) 111169695Skan{ 112169695Skan pthread_t self = pthread_self (); 113169695Skan unsigned long hash = PTHREAD_HASH (self); 114169695Skan unsigned long rehash; 115169695Skan 116169695Skan#ifdef __alpha__ 117169695Skan /* Alpha has the loosest memory ordering rules of all. We need a memory 118169695Skan barrier to flush the reorder buffer before considering a *read* of a 119169695Skan shared variable. Since we're not always taking a lock, we have to do 120169695Skan this by hand. */ 121169695Skan __sync_synchronize (); 122169695Skan#endif 123169695Skan 124169695Skan rehash = hash; 125169695Skan while (1) 126169695Skan { 127169695Skan if (mf_thread_data[rehash].used_p && mf_thread_data[rehash].self == self) 128169695Skan return &mf_thread_data[rehash]; 129169695Skan 130169695Skan rehash += 7; 131169695Skan if (rehash >= LIBMUDFLAPTH_THREADS_MAX) 132169695Skan rehash -= LIBMUDFLAPTH_THREADS_MAX; 133169695Skan if (rehash == hash) 134169695Skan break; 135169695Skan } 136169695Skan 137169695Skan if (alloc) 138169695Skan { 139169695Skan pthread_mutex_lock (&mf_thread_data_lock); 140169695Skan 141169695Skan rehash = hash; 142169695Skan while (1) 143169695Skan { 144169695Skan if (!mf_thread_data[rehash].used_p) 145169695Skan { 146169695Skan mf_thread_data[rehash].self = self; 147169695Skan __sync_synchronize (); 148169695Skan mf_thread_data[rehash].used_p = 1; 149169695Skan 150169695Skan pthread_mutex_unlock (&mf_thread_data_lock); 151169695Skan return &mf_thread_data[rehash]; 152169695Skan } 153169695Skan 154169695Skan rehash += 7; 155169695Skan if (rehash >= LIBMUDFLAPTH_THREADS_MAX) 156169695Skan rehash -= LIBMUDFLAPTH_THREADS_MAX; 157169695Skan if (rehash == hash) 158169695Skan break; 159169695Skan } 160169695Skan 161169695Skan pthread_mutex_unlock (&mf_thread_data_lock); 162169695Skan } 163169695Skan 164169695Skan return NULL; 165169695Skan} 166169695Skan 167169695Skanenum __mf_state_enum 168169695Skan__mf_get_state (void) 169169695Skan{ 170169695Skan struct mf_thread_data *data = __mf_find_threadinfo (0); 171169695Skan if (data) 172169695Skan return data->state; 173169695Skan 174169695Skan /* If we've never seen this thread before, consider it to be in the 175169695Skan reentrant state. The state gets reset to active for the main thread 176169695Skan in __mf_init, and for child threads in __mf_pthread_spawner. 177169695Skan 178169695Skan The trickiest bit here is that the LinuxThreads pthread_manager thread 179169695Skan should *always* be considered to be reentrant, so that none of our 180169695Skan hooks actually do anything. Why? Because that thread isn't a real 181169695Skan thread from the point of view of the thread library, and so lots of 182169695Skan stuff isn't initialized, leading to SEGV very quickly. Even calling 183169695Skan pthread_self is a bit suspect, but it happens to work. */ 184169695Skan 185169695Skan return reentrant; 186169695Skan} 187169695Skan 188169695Skanvoid 189169695Skan__mf_set_state (enum __mf_state_enum new_state) 190169695Skan{ 191169695Skan struct mf_thread_data *data = __mf_find_threadinfo (1); 192169695Skan data->state = new_state; 193169695Skan} 194169695Skan#endif 195169695Skan 196169695Skan/* The following two functions are used only with __mf_opts.heur_std_data. 197169695Skan We're interested in recording the location of the thread-local errno 198169695Skan variable. 199169695Skan 200169695Skan Note that this doesn't handle TLS references in general; we have no 201169695Skan visibility into __tls_get_data for when that memory is allocated at 202169695Skan runtime. Hopefully we get to see the malloc or mmap operation that 203169695Skan eventually allocates the backing store. */ 204169695Skan 205169695Skan/* Describe the startup information for a new user thread. */ 206169695Skanstruct mf_thread_start_info 207169695Skan{ 208169695Skan /* The user's thread entry point and argument. */ 209169695Skan void * (*user_fn)(void *); 210169695Skan void *user_arg; 211169695Skan}; 212169695Skan 213169695Skan 214169695Skanstatic void 215169695Skan__mf_pthread_cleanup (void *arg) 216169695Skan{ 217169695Skan if (__mf_opts.heur_std_data) 218169695Skan __mf_unregister (&errno, sizeof (errno), __MF_TYPE_GUESS); 219169695Skan 220169695Skan#ifndef HAVE_TLS 221169695Skan struct mf_thread_data *data = __mf_find_threadinfo (0); 222169695Skan if (data) 223169695Skan data->used_p = 0; 224169695Skan#endif 225169695Skan} 226169695Skan 227169695Skan 228169695Skanstatic void * 229169695Skan__mf_pthread_spawner (void *arg) 230169695Skan{ 231169695Skan void *result = NULL; 232169695Skan 233169695Skan __mf_set_state (active); 234169695Skan 235169695Skan /* NB: We could use __MF_TYPE_STATIC here, but we guess that the thread 236169695Skan errno is coming out of some dynamically allocated pool that we already 237169695Skan know of as __MF_TYPE_HEAP. */ 238169695Skan if (__mf_opts.heur_std_data) 239169695Skan __mf_register (&errno, sizeof (errno), __MF_TYPE_GUESS, 240169695Skan "errno area (thread)"); 241169695Skan 242169695Skan /* We considered using pthread_key_t objects instead of these 243169695Skan cleanup stacks, but they were less cooperative with the 244169695Skan interposed malloc hooks in libmudflap. */ 245169695Skan /* ??? The pthread_key_t problem is solved above... */ 246169695Skan pthread_cleanup_push (__mf_pthread_cleanup, NULL); 247169695Skan 248169695Skan /* Extract given entry point and argument. */ 249169695Skan struct mf_thread_start_info *psi = arg; 250169695Skan void * (*user_fn)(void *) = psi->user_fn; 251169695Skan void *user_arg = psi->user_arg; 252169695Skan CALL_REAL (free, arg); 253169695Skan 254169695Skan result = (*user_fn)(user_arg); 255169695Skan 256169695Skan pthread_cleanup_pop (1 /* execute */); 257169695Skan 258169695Skan return result; 259169695Skan} 260169695Skan 261169695Skan 262169695Skan#if PIC 263169695Skan/* A special bootstrap variant. */ 264169695Skanint 265169695Skan__mf_0fn_pthread_create (pthread_t *thr, const pthread_attr_t *attr, 266169695Skan void * (*start) (void *), void *arg) 267169695Skan{ 268169695Skan return -1; 269169695Skan} 270169695Skan#endif 271169695Skan 272169695Skan 273169695Skan#undef pthread_create 274169695SkanWRAPPER(int, pthread_create, pthread_t *thr, const pthread_attr_t *attr, 275169695Skan void * (*start) (void *), void *arg) 276169695Skan{ 277169695Skan struct mf_thread_start_info *si; 278169695Skan 279169695Skan TRACE ("pthread_create\n"); 280169695Skan 281169695Skan /* Fill in startup-control fields. */ 282169695Skan si = CALL_REAL (malloc, sizeof (*si)); 283169695Skan si->user_fn = start; 284169695Skan si->user_arg = arg; 285169695Skan 286169695Skan /* Actually create the thread. */ 287169695Skan return CALL_REAL (pthread_create, thr, attr, __mf_pthread_spawner, si); 288169695Skan} 289