unwind-dw2-fde-darwin.c revision 117395
1117395Skan/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
2117395Skan
3117395Skan   This file is part of GNU CC.
4117395Skan
5117395Skan   GNU CC is free software; you can redistribute it and/or modify
6117395Skan   it under the terms of the GNU General Public License as published by
7117395Skan   the Free Software Foundation; either version 2, or (at your option)
8117395Skan   any later version.
9117395Skan
10117395Skan   GNU CC is distributed in the hope that it will be useful,
11117395Skan   but WITHOUT ANY WARRANTY; without even the implied warranty of
12117395Skan   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13117395Skan   GNU General Public License for more details.
14117395Skan
15117395Skan   You should have received a copy of the GNU General Public License
16117395Skan   along with GNU CC; see the file COPYING.  If not, write to
17117395Skan   the Free Software Foundation, 59 Temple Place - Suite 330,
18117395Skan   Boston, MA 02111-1307, USA.  */
19117395Skan
20117395Skan/* As a special exception, if you link this library with other files,
21117395Skan   some of which are compiled with GCC, to produce an executable,
22117395Skan   this library does not by itself cause the resulting executable
23117395Skan   to be covered by the GNU General Public License.
24117395Skan   This exception does not however invalidate any other reasons why
25117395Skan   the executable file might be covered by the GNU General Public License.  */
26117395Skan
27117395Skan/* Locate the FDE entry for a given address, using Darwin's keymgr support.  */
28117395Skan
29117395Skan#include "tconfig.h"
30117395Skan#include <string.h>
31117395Skan#include <stdlib.h>
32117395Skan#include "dwarf2.h"
33117395Skan#include "unwind.h"
34117395Skan#define NO_BASE_OF_ENCODED_VALUE
35117395Skan#define DWARF2_OBJECT_END_PTR_EXTENSION
36117395Skan#include "unwind-pe.h"
37117395Skan#include "unwind-dw2-fde.h"
38117395Skan/* Carefully don't include gthr.h.  */
39117395Skan
40117395Skantypedef int __gthread_mutex_t;
41117395Skan#define __gthread_mutex_lock(x)  (void)(x)
42117395Skan#define __gthread_mutex_unlock(x) (void)(x)
43117395Skan
44117395Skanstatic fde * _Unwind_Find_registered_FDE (void *pc,
45117395Skan					  struct dwarf_eh_bases *bases);
46117395Skan
47117395Skan#define _Unwind_Find_FDE _Unwind_Find_registered_FDE
48117395Skan#include "unwind-dw2-fde.c"
49117395Skan#undef _Unwind_Find_FDE
50117395Skan
51117395Skan/* KeyMgr stuff.  */
52117395Skan#define KEYMGR_GCC3_LIVE_IMAGE_LIST     301     /* loaded images  */
53117395Skan#define KEYMGR_GCC3_DW2_OBJ_LIST        302     /* Dwarf2 object list  */
54117395Skan
55117395Skanextern void *_keymgr_get_and_lock_processwide_ptr (int);
56117395Skanextern void _keymgr_set_and_unlock_processwide_ptr (int, void *);
57117395Skanextern void _keymgr_unlock_processwide_ptr (int);
58117395Skan
59117395Skanstruct mach_header;
60117395Skanextern char *getsectdatafromheader (struct mach_header*, const char*,
61117395Skan			const char *, unsigned long *);
62117395Skan
63117395Skan/* This is referenced from KEYMGR_GCC3_DW2_OBJ_LIST.  */
64117395Skanstruct km_object_info {
65117395Skan  struct object *seen_objects;
66117395Skan  struct object *unseen_objects;
67117395Skan  unsigned spare[2];
68117395Skan};
69117395Skan
70117395Skan/* Node of KEYMGR_GCC3_LIVE_IMAGE_LIST.  Info about each resident image.  */
71117395Skanstruct live_images {
72117395Skan  unsigned long this_size;                      /* sizeof (live_images)  */
73117395Skan  struct mach_header *mh;                       /* the image info  */
74117395Skan  unsigned long vm_slide;
75117395Skan  void (*destructor)(struct live_images *);     /* destructor for this  */
76117395Skan  struct live_images *next;
77117395Skan  unsigned int examined_p;
78117395Skan  void *fde;
79117395Skan  void *object_info;
80117395Skan  unsigned long info[2];                        /* Future use.  */
81117395Skan};
82117395Skan
83117395Skan/* Bits in the examined_p field of struct live_images.  */
84117395Skanenum {
85117395Skan  EXAMINED_IMAGE_MASK = 1,	/* We've seen this one.  */
86117395Skan  ALLOCED_IMAGE_MASK = 2,	/* The FDE entries were allocated by
87117395Skan				   malloc, and must be freed.  This isn't
88117395Skan				   used by newer libgcc versions.  */
89117395Skan  IMAGE_IS_TEXT_MASK = 4,	/* This image is in the TEXT segment.  */
90117395Skan  DESTRUCTOR_MAY_BE_CALLED_LIVE = 8  /* The destructor may be called on an
91117395Skan					object that's part of the live
92117395Skan					image list.  */
93117395Skan};
94117395Skan
95117395Skan/* Delete any data we allocated on a live_images structure.  Either
96117395Skan   IMAGE has already been removed from the
97117395Skan   KEYMGR_GCC3_LIVE_IMAGE_LIST and the struct will be deleted
98117395Skan   after we return, or that list is locked and we're being called
99117395Skan   because this object might be about to be unloaded.  Called by
100117395Skan   KeyMgr.  */
101117395Skan
102117395Skanstatic void
103117395Skanlive_image_destructor (struct live_images *image)
104117395Skan{
105117395Skan  if (image->object_info)
106117395Skan    {
107117395Skan      /* Free any sorted arrays.  */
108117395Skan      __deregister_frame_info_bases (image->fde);
109117395Skan
110117395Skan      free (image->object_info);
111117395Skan      image->object_info = NULL;
112117395Skan      if (image->examined_p & ALLOCED_IMAGE_MASK)
113117395Skan	free (image->fde);
114117395Skan      image->fde = NULL;
115117395Skan    }
116117395Skan  image->examined_p = 0;
117117395Skan  image->destructor = NULL;
118117395Skan}
119117395Skan
120117395Skan/* Run through the list of live images.  If we can allocate memory,
121117395Skan   give each unseen image a new `struct object'.  Even if we can't,
122117395Skan   check whether the PC is inside the FDE of each unseen image.
123117395Skan */
124117395Skan
125117395Skanstatic inline fde *
126117395Skanexamine_objects (void *pc, struct dwarf_eh_bases *bases, int dont_alloc)
127117395Skan{
128117395Skan  fde *result = NULL;
129117395Skan  struct live_images *image;
130117395Skan
131117395Skan  image = _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
132117395Skan
133117395Skan  for (; image != NULL; image = image->next)
134117395Skan    if ((image->examined_p & EXAMINED_IMAGE_MASK) == 0)
135117395Skan      {
136117395Skan	char *fde;
137117395Skan	unsigned long sz;
138117395Skan
139117395Skan	fde = getsectdatafromheader (image->mh, "__DATA", "__eh_frame", &sz);
140117395Skan	if (fde == NULL)
141117395Skan	  {
142117395Skan	    fde = getsectdatafromheader (image->mh, "__TEXT",
143117395Skan					 "__eh_frame", &sz);
144117395Skan	    if (fde != NULL)
145117395Skan	      image->examined_p |= IMAGE_IS_TEXT_MASK;
146117395Skan	  }
147117395Skan
148117395Skan	/* If .eh_frame is empty, don't register at all.  */
149117395Skan	if (fde != NULL && sz > 0)
150117395Skan	  {
151117395Skan	    char *real_fde = (fde + image->vm_slide);
152117395Skan	    struct object *ob = NULL;
153117395Skan	    struct object panicob;
154117395Skan
155117395Skan	    if (! dont_alloc)
156117395Skan	      ob = calloc (1, sizeof (struct object));
157117395Skan	    dont_alloc |= ob == NULL;
158117395Skan	    if (dont_alloc)
159117395Skan	      ob = &panicob;
160117395Skan
161117395Skan	    ob->pc_begin = (void *)-1;
162117395Skan	    ob->tbase = 0;
163117395Skan	    ob->dbase = 0;
164117395Skan	    ob->u.single = (struct dwarf_fde *)real_fde;
165117395Skan	    ob->s.i = 0;
166117395Skan	    ob->s.b.encoding = DW_EH_PE_omit;
167117395Skan	    ob->fde_end = real_fde + sz;
168117395Skan
169117395Skan	    if (! dont_alloc)
170117395Skan	      {
171117395Skan		ob->next = unseen_objects;
172117395Skan		unseen_objects = ob;
173117395Skan
174117395Skan		image->destructor = live_image_destructor;
175117395Skan		image->object_info = ob;
176117395Skan
177117395Skan		image->examined_p |= (EXAMINED_IMAGE_MASK
178117395Skan				      | DESTRUCTOR_MAY_BE_CALLED_LIVE);
179117395Skan	      }
180117395Skan	    image->fde = real_fde;
181117395Skan
182117395Skan	    result = search_object (ob, pc);
183117395Skan	    if (result)
184117395Skan	      {
185117395Skan		int encoding;
186117395Skan
187117395Skan		bases->tbase = ob->tbase;
188117395Skan		bases->dbase = ob->dbase;
189117395Skan
190117395Skan		encoding = ob->s.b.encoding;
191117395Skan		if (ob->s.b.mixed_encoding)
192117395Skan		  encoding = get_fde_encoding (result);
193117395Skan		read_encoded_value_with_base (encoding,
194117395Skan					      base_from_object (encoding, ob),
195117395Skan					      result->pc_begin,
196117395Skan					      (_Unwind_Ptr *)&bases->func);
197117395Skan		break;
198117395Skan	      }
199117395Skan	  }
200117395Skan	else
201117395Skan	  image->examined_p |= EXAMINED_IMAGE_MASK;
202117395Skan      }
203117395Skan
204117395Skan  _keymgr_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
205117395Skan
206117395Skan  return result;
207117395Skan}
208117395Skan
209117395Skanfde *
210117395Skan_Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
211117395Skan{
212117395Skan  struct km_object_info *the_obj_info;
213117395Skan  fde *ret = NULL;
214117395Skan
215117395Skan  the_obj_info =
216117395Skan    _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST);
217117395Skan  if (! the_obj_info)
218117395Skan    the_obj_info = calloc (1, sizeof (*the_obj_info));
219117395Skan
220117395Skan  if (the_obj_info != NULL)
221117395Skan    {
222117395Skan      seen_objects = the_obj_info->seen_objects;
223117395Skan      unseen_objects = the_obj_info->unseen_objects;
224117395Skan
225117395Skan      ret = _Unwind_Find_registered_FDE (pc, bases);
226117395Skan    }
227117395Skan
228117395Skan  /* OK, didn't find it in the list of FDEs we've seen before,
229117395Skan     so go through and look at the new ones.  */
230117395Skan  if (ret == NULL)
231117395Skan    ret = examine_objects (pc, bases, the_obj_info == NULL);
232117395Skan
233117395Skan  if (the_obj_info != NULL)
234117395Skan    {
235117395Skan      the_obj_info->seen_objects = seen_objects;
236117395Skan      the_obj_info->unseen_objects = unseen_objects;
237117395Skan      _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST,
238117395Skan					      the_obj_info);
239117395Skan    }
240117395Skan  return ret;
241117395Skan}
242