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