1*c87b03e5Sespie /* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
2*c87b03e5Sespie
3*c87b03e5Sespie This file is part of GNU CC.
4*c87b03e5Sespie
5*c87b03e5Sespie GNU CC is free software; you can redistribute it and/or modify
6*c87b03e5Sespie it under the terms of the GNU General Public License as published by
7*c87b03e5Sespie the Free Software Foundation; either version 2, or (at your option)
8*c87b03e5Sespie any later version.
9*c87b03e5Sespie
10*c87b03e5Sespie GNU CC is distributed in the hope that it will be useful,
11*c87b03e5Sespie but WITHOUT ANY WARRANTY; without even the implied warranty of
12*c87b03e5Sespie MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13*c87b03e5Sespie GNU General Public License for more details.
14*c87b03e5Sespie
15*c87b03e5Sespie You should have received a copy of the GNU General Public License
16*c87b03e5Sespie along with GNU CC; see the file COPYING. If not, write to
17*c87b03e5Sespie the Free Software Foundation, 59 Temple Place - Suite 330,
18*c87b03e5Sespie Boston, MA 02111-1307, USA. */
19*c87b03e5Sespie
20*c87b03e5Sespie /* As a special exception, if you link this library with other files,
21*c87b03e5Sespie some of which are compiled with GCC, to produce an executable,
22*c87b03e5Sespie this library does not by itself cause the resulting executable
23*c87b03e5Sespie to be covered by the GNU General Public License.
24*c87b03e5Sespie This exception does not however invalidate any other reasons why
25*c87b03e5Sespie the executable file might be covered by the GNU General Public License. */
26*c87b03e5Sespie
27*c87b03e5Sespie /* Locate the FDE entry for a given address, using Darwin's keymgr support. */
28*c87b03e5Sespie
29*c87b03e5Sespie #include "tconfig.h"
30*c87b03e5Sespie #include <string.h>
31*c87b03e5Sespie #include <stdlib.h>
32*c87b03e5Sespie #include "dwarf2.h"
33*c87b03e5Sespie #include "unwind.h"
34*c87b03e5Sespie #define NO_BASE_OF_ENCODED_VALUE
35*c87b03e5Sespie #define DWARF2_OBJECT_END_PTR_EXTENSION
36*c87b03e5Sespie #include "unwind-pe.h"
37*c87b03e5Sespie #include "unwind-dw2-fde.h"
38*c87b03e5Sespie /* Carefully don't include gthr.h. */
39*c87b03e5Sespie
40*c87b03e5Sespie typedef int __gthread_mutex_t;
41*c87b03e5Sespie #define __gthread_mutex_lock(x) (void)(x)
42*c87b03e5Sespie #define __gthread_mutex_unlock(x) (void)(x)
43*c87b03e5Sespie
44*c87b03e5Sespie static fde * _Unwind_Find_registered_FDE (void *pc,
45*c87b03e5Sespie struct dwarf_eh_bases *bases);
46*c87b03e5Sespie
47*c87b03e5Sespie #define _Unwind_Find_FDE _Unwind_Find_registered_FDE
48*c87b03e5Sespie #include "unwind-dw2-fde.c"
49*c87b03e5Sespie #undef _Unwind_Find_FDE
50*c87b03e5Sespie
51*c87b03e5Sespie /* KeyMgr stuff. */
52*c87b03e5Sespie #define KEYMGR_GCC3_LIVE_IMAGE_LIST 301 /* loaded images */
53*c87b03e5Sespie #define KEYMGR_GCC3_DW2_OBJ_LIST 302 /* Dwarf2 object list */
54*c87b03e5Sespie
55*c87b03e5Sespie extern void *_keymgr_get_and_lock_processwide_ptr (int);
56*c87b03e5Sespie extern void _keymgr_set_and_unlock_processwide_ptr (int, void *);
57*c87b03e5Sespie extern void _keymgr_unlock_processwide_ptr (int);
58*c87b03e5Sespie
59*c87b03e5Sespie struct mach_header;
60*c87b03e5Sespie extern char *getsectdatafromheader (struct mach_header*, const char*,
61*c87b03e5Sespie const char *, unsigned long *);
62*c87b03e5Sespie
63*c87b03e5Sespie /* This is referenced from KEYMGR_GCC3_DW2_OBJ_LIST. */
64*c87b03e5Sespie struct km_object_info {
65*c87b03e5Sespie struct object *seen_objects;
66*c87b03e5Sespie struct object *unseen_objects;
67*c87b03e5Sespie unsigned spare[2];
68*c87b03e5Sespie };
69*c87b03e5Sespie
70*c87b03e5Sespie /* Node of KEYMGR_GCC3_LIVE_IMAGE_LIST. Info about each resident image. */
71*c87b03e5Sespie struct live_images {
72*c87b03e5Sespie unsigned long this_size; /* sizeof (live_images) */
73*c87b03e5Sespie struct mach_header *mh; /* the image info */
74*c87b03e5Sespie unsigned long vm_slide;
75*c87b03e5Sespie void (*destructor)(struct live_images *); /* destructor for this */
76*c87b03e5Sespie struct live_images *next;
77*c87b03e5Sespie unsigned int examined_p;
78*c87b03e5Sespie void *fde;
79*c87b03e5Sespie void *object_info;
80*c87b03e5Sespie unsigned long info[2]; /* Future use. */
81*c87b03e5Sespie };
82*c87b03e5Sespie
83*c87b03e5Sespie /* Bits in the examined_p field of struct live_images. */
84*c87b03e5Sespie enum {
85*c87b03e5Sespie EXAMINED_IMAGE_MASK = 1, /* We've seen this one. */
86*c87b03e5Sespie ALLOCED_IMAGE_MASK = 2, /* The FDE entries were allocated by
87*c87b03e5Sespie malloc, and must be freed. This isn't
88*c87b03e5Sespie used by newer libgcc versions. */
89*c87b03e5Sespie IMAGE_IS_TEXT_MASK = 4, /* This image is in the TEXT segment. */
90*c87b03e5Sespie DESTRUCTOR_MAY_BE_CALLED_LIVE = 8 /* The destructor may be called on an
91*c87b03e5Sespie object that's part of the live
92*c87b03e5Sespie image list. */
93*c87b03e5Sespie };
94*c87b03e5Sespie
95*c87b03e5Sespie /* Delete any data we allocated on a live_images structure. Either
96*c87b03e5Sespie IMAGE has already been removed from the
97*c87b03e5Sespie KEYMGR_GCC3_LIVE_IMAGE_LIST and the struct will be deleted
98*c87b03e5Sespie after we return, or that list is locked and we're being called
99*c87b03e5Sespie because this object might be about to be unloaded. Called by
100*c87b03e5Sespie KeyMgr. */
101*c87b03e5Sespie
102*c87b03e5Sespie static void
live_image_destructor(struct live_images * image)103*c87b03e5Sespie live_image_destructor (struct live_images *image)
104*c87b03e5Sespie {
105*c87b03e5Sespie if (image->object_info)
106*c87b03e5Sespie {
107*c87b03e5Sespie /* Free any sorted arrays. */
108*c87b03e5Sespie __deregister_frame_info_bases (image->fde);
109*c87b03e5Sespie
110*c87b03e5Sespie free (image->object_info);
111*c87b03e5Sespie image->object_info = NULL;
112*c87b03e5Sespie if (image->examined_p & ALLOCED_IMAGE_MASK)
113*c87b03e5Sespie free (image->fde);
114*c87b03e5Sespie image->fde = NULL;
115*c87b03e5Sespie }
116*c87b03e5Sespie image->examined_p = 0;
117*c87b03e5Sespie image->destructor = NULL;
118*c87b03e5Sespie }
119*c87b03e5Sespie
120*c87b03e5Sespie /* Run through the list of live images. If we can allocate memory,
121*c87b03e5Sespie give each unseen image a new `struct object'. Even if we can't,
122*c87b03e5Sespie check whether the PC is inside the FDE of each unseen image.
123*c87b03e5Sespie */
124*c87b03e5Sespie
125*c87b03e5Sespie static inline fde *
examine_objects(void * pc,struct dwarf_eh_bases * bases,int dont_alloc)126*c87b03e5Sespie examine_objects (void *pc, struct dwarf_eh_bases *bases, int dont_alloc)
127*c87b03e5Sespie {
128*c87b03e5Sespie fde *result = NULL;
129*c87b03e5Sespie struct live_images *image;
130*c87b03e5Sespie
131*c87b03e5Sespie image = _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
132*c87b03e5Sespie
133*c87b03e5Sespie for (; image != NULL; image = image->next)
134*c87b03e5Sespie if ((image->examined_p & EXAMINED_IMAGE_MASK) == 0)
135*c87b03e5Sespie {
136*c87b03e5Sespie char *fde;
137*c87b03e5Sespie unsigned long sz;
138*c87b03e5Sespie
139*c87b03e5Sespie fde = getsectdatafromheader (image->mh, "__DATA", "__eh_frame", &sz);
140*c87b03e5Sespie if (fde == NULL)
141*c87b03e5Sespie {
142*c87b03e5Sespie fde = getsectdatafromheader (image->mh, "__TEXT",
143*c87b03e5Sespie "__eh_frame", &sz);
144*c87b03e5Sespie if (fde != NULL)
145*c87b03e5Sespie image->examined_p |= IMAGE_IS_TEXT_MASK;
146*c87b03e5Sespie }
147*c87b03e5Sespie
148*c87b03e5Sespie /* If .eh_frame is empty, don't register at all. */
149*c87b03e5Sespie if (fde != NULL && sz > 0)
150*c87b03e5Sespie {
151*c87b03e5Sespie char *real_fde = (fde + image->vm_slide);
152*c87b03e5Sespie struct object *ob = NULL;
153*c87b03e5Sespie struct object panicob;
154*c87b03e5Sespie
155*c87b03e5Sespie if (! dont_alloc)
156*c87b03e5Sespie ob = calloc (1, sizeof (struct object));
157*c87b03e5Sespie dont_alloc |= ob == NULL;
158*c87b03e5Sespie if (dont_alloc)
159*c87b03e5Sespie ob = &panicob;
160*c87b03e5Sespie
161*c87b03e5Sespie ob->pc_begin = (void *)-1;
162*c87b03e5Sespie ob->tbase = 0;
163*c87b03e5Sespie ob->dbase = 0;
164*c87b03e5Sespie ob->u.single = (struct dwarf_fde *)real_fde;
165*c87b03e5Sespie ob->s.i = 0;
166*c87b03e5Sespie ob->s.b.encoding = DW_EH_PE_omit;
167*c87b03e5Sespie ob->fde_end = real_fde + sz;
168*c87b03e5Sespie
169*c87b03e5Sespie if (! dont_alloc)
170*c87b03e5Sespie {
171*c87b03e5Sespie ob->next = unseen_objects;
172*c87b03e5Sespie unseen_objects = ob;
173*c87b03e5Sespie
174*c87b03e5Sespie image->destructor = live_image_destructor;
175*c87b03e5Sespie image->object_info = ob;
176*c87b03e5Sespie
177*c87b03e5Sespie image->examined_p |= (EXAMINED_IMAGE_MASK
178*c87b03e5Sespie | DESTRUCTOR_MAY_BE_CALLED_LIVE);
179*c87b03e5Sespie }
180*c87b03e5Sespie image->fde = real_fde;
181*c87b03e5Sespie
182*c87b03e5Sespie result = search_object (ob, pc);
183*c87b03e5Sespie if (result)
184*c87b03e5Sespie {
185*c87b03e5Sespie int encoding;
186*c87b03e5Sespie
187*c87b03e5Sespie bases->tbase = ob->tbase;
188*c87b03e5Sespie bases->dbase = ob->dbase;
189*c87b03e5Sespie
190*c87b03e5Sespie encoding = ob->s.b.encoding;
191*c87b03e5Sespie if (ob->s.b.mixed_encoding)
192*c87b03e5Sespie encoding = get_fde_encoding (result);
193*c87b03e5Sespie read_encoded_value_with_base (encoding,
194*c87b03e5Sespie base_from_object (encoding, ob),
195*c87b03e5Sespie result->pc_begin,
196*c87b03e5Sespie (_Unwind_Ptr *)&bases->func);
197*c87b03e5Sespie break;
198*c87b03e5Sespie }
199*c87b03e5Sespie }
200*c87b03e5Sespie else
201*c87b03e5Sespie image->examined_p |= EXAMINED_IMAGE_MASK;
202*c87b03e5Sespie }
203*c87b03e5Sespie
204*c87b03e5Sespie _keymgr_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
205*c87b03e5Sespie
206*c87b03e5Sespie return result;
207*c87b03e5Sespie }
208*c87b03e5Sespie
209*c87b03e5Sespie fde *
_Unwind_Find_FDE(void * pc,struct dwarf_eh_bases * bases)210*c87b03e5Sespie _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
211*c87b03e5Sespie {
212*c87b03e5Sespie struct km_object_info *the_obj_info;
213*c87b03e5Sespie fde *ret = NULL;
214*c87b03e5Sespie
215*c87b03e5Sespie the_obj_info =
216*c87b03e5Sespie _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST);
217*c87b03e5Sespie if (! the_obj_info)
218*c87b03e5Sespie the_obj_info = calloc (1, sizeof (*the_obj_info));
219*c87b03e5Sespie
220*c87b03e5Sespie if (the_obj_info != NULL)
221*c87b03e5Sespie {
222*c87b03e5Sespie seen_objects = the_obj_info->seen_objects;
223*c87b03e5Sespie unseen_objects = the_obj_info->unseen_objects;
224*c87b03e5Sespie
225*c87b03e5Sespie ret = _Unwind_Find_registered_FDE (pc, bases);
226*c87b03e5Sespie }
227*c87b03e5Sespie
228*c87b03e5Sespie /* OK, didn't find it in the list of FDEs we've seen before,
229*c87b03e5Sespie so go through and look at the new ones. */
230*c87b03e5Sespie if (ret == NULL)
231*c87b03e5Sespie ret = examine_objects (pc, bases, the_obj_info == NULL);
232*c87b03e5Sespie
233*c87b03e5Sespie if (the_obj_info != NULL)
234*c87b03e5Sespie {
235*c87b03e5Sespie the_obj_info->seen_objects = seen_objects;
236*c87b03e5Sespie the_obj_info->unseen_objects = unseen_objects;
237*c87b03e5Sespie _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST,
238*c87b03e5Sespie the_obj_info);
239*c87b03e5Sespie }
240*c87b03e5Sespie return ret;
241*c87b03e5Sespie }
242