1b725ae77Skettenis /* Frame unwinder for frames using the libunwind library.
2b725ae77Skettenis
3*11efff7fSkettenis Copyright 2003, 2004 Free Software Foundation, Inc.
4b725ae77Skettenis
5b725ae77Skettenis Written by Jeff Johnston, contributed by Red Hat Inc.
6b725ae77Skettenis
7b725ae77Skettenis This file is part of GDB.
8b725ae77Skettenis
9b725ae77Skettenis This program is free software; you can redistribute it and/or modify
10b725ae77Skettenis it under the terms of the GNU General Public License as published by
11b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
12b725ae77Skettenis (at your option) any later version.
13b725ae77Skettenis
14b725ae77Skettenis This program is distributed in the hope that it will be useful,
15b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
16b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17b725ae77Skettenis GNU General Public License for more details.
18b725ae77Skettenis
19b725ae77Skettenis You should have received a copy of the GNU General Public License
20b725ae77Skettenis along with this program; if not, write to the Free Software
21b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
22b725ae77Skettenis Boston, MA 02111-1307, USA. */
23b725ae77Skettenis
24b725ae77Skettenis #include "defs.h"
25b725ae77Skettenis
26b725ae77Skettenis #include "inferior.h"
27b725ae77Skettenis #include "frame.h"
28b725ae77Skettenis #include "frame-base.h"
29b725ae77Skettenis #include "frame-unwind.h"
30b725ae77Skettenis #include "gdbcore.h"
31b725ae77Skettenis #include "gdbtypes.h"
32b725ae77Skettenis #include "symtab.h"
33b725ae77Skettenis #include "objfiles.h"
34b725ae77Skettenis #include "regcache.h"
35b725ae77Skettenis
36b725ae77Skettenis #include <dlfcn.h>
37b725ae77Skettenis
38b725ae77Skettenis #include "gdb_assert.h"
39b725ae77Skettenis #include "gdb_string.h"
40b725ae77Skettenis
41b725ae77Skettenis #include "libunwind-frame.h"
42b725ae77Skettenis
43b725ae77Skettenis #include "complaints.h"
44b725ae77Skettenis
45b725ae77Skettenis static int libunwind_initialized;
46b725ae77Skettenis static struct gdbarch_data *libunwind_descr_handle;
47b725ae77Skettenis
48b725ae77Skettenis /* Required function pointers from libunwind. */
49b725ae77Skettenis static int (*unw_get_reg_p) (unw_cursor_t *, unw_regnum_t, unw_word_t *);
50b725ae77Skettenis static int (*unw_get_fpreg_p) (unw_cursor_t *, unw_regnum_t, unw_fpreg_t *);
51b725ae77Skettenis static int (*unw_get_saveloc_p) (unw_cursor_t *, unw_regnum_t, unw_save_loc_t *);
52b725ae77Skettenis static int (*unw_step_p) (unw_cursor_t *);
53b725ae77Skettenis static int (*unw_init_remote_p) (unw_cursor_t *, unw_addr_space_t, void *);
54b725ae77Skettenis static unw_addr_space_t (*unw_create_addr_space_p) (unw_accessors_t *, int);
55b725ae77Skettenis static int (*unw_search_unwind_table_p) (unw_addr_space_t, unw_word_t, unw_dyn_info_t *,
56b725ae77Skettenis unw_proc_info_t *, int, void *);
57b725ae77Skettenis static unw_word_t (*unw_find_dyn_list_p) (unw_addr_space_t, unw_dyn_info_t *,
58b725ae77Skettenis void *);
59b725ae77Skettenis
60b725ae77Skettenis
61b725ae77Skettenis struct libunwind_frame_cache
62b725ae77Skettenis {
63b725ae77Skettenis CORE_ADDR base;
64b725ae77Skettenis CORE_ADDR func_addr;
65b725ae77Skettenis unw_cursor_t cursor;
66b725ae77Skettenis };
67b725ae77Skettenis
68b725ae77Skettenis /* We need to qualify the function names with a platform-specific prefix to match
69b725ae77Skettenis the names used by the libunwind library. The UNW_OBJ macro is provided by the
70b725ae77Skettenis libunwind.h header file. */
71b725ae77Skettenis #define STRINGIFY2(name) #name
72b725ae77Skettenis #define STRINGIFY(name) STRINGIFY2(name)
73b725ae77Skettenis
74*11efff7fSkettenis #ifndef LIBUNWIND_SO
75*11efff7fSkettenis #define LIBUNWIND_SO "libunwind-" STRINGIFY(UNW_TARGET) ".so"
76*11efff7fSkettenis #endif
77*11efff7fSkettenis
78b725ae77Skettenis static char *get_reg_name = STRINGIFY(UNW_OBJ(get_reg));
79b725ae77Skettenis static char *get_fpreg_name = STRINGIFY(UNW_OBJ(get_fpreg));
80b725ae77Skettenis static char *get_saveloc_name = STRINGIFY(UNW_OBJ(get_save_loc));
81b725ae77Skettenis static char *step_name = STRINGIFY(UNW_OBJ(step));
82b725ae77Skettenis static char *init_remote_name = STRINGIFY(UNW_OBJ(init_remote));
83b725ae77Skettenis static char *create_addr_space_name = STRINGIFY(UNW_OBJ(create_addr_space));
84b725ae77Skettenis static char *search_unwind_table_name = STRINGIFY(UNW_OBJ(search_unwind_table));
85b725ae77Skettenis static char *find_dyn_list_name = STRINGIFY(UNW_OBJ(find_dyn_list));
86b725ae77Skettenis
87b725ae77Skettenis static struct libunwind_descr *
libunwind_descr(struct gdbarch * gdbarch)88b725ae77Skettenis libunwind_descr (struct gdbarch *gdbarch)
89b725ae77Skettenis {
90b725ae77Skettenis return gdbarch_data (gdbarch, libunwind_descr_handle);
91b725ae77Skettenis }
92b725ae77Skettenis
93b725ae77Skettenis static void *
libunwind_descr_init(struct gdbarch * gdbarch)94b725ae77Skettenis libunwind_descr_init (struct gdbarch *gdbarch)
95b725ae77Skettenis {
96b725ae77Skettenis struct libunwind_descr *descr = GDBARCH_OBSTACK_ZALLOC (gdbarch,
97b725ae77Skettenis struct libunwind_descr);
98b725ae77Skettenis return descr;
99b725ae77Skettenis }
100b725ae77Skettenis
101b725ae77Skettenis void
libunwind_frame_set_descr(struct gdbarch * gdbarch,struct libunwind_descr * descr)102b725ae77Skettenis libunwind_frame_set_descr (struct gdbarch *gdbarch, struct libunwind_descr *descr)
103b725ae77Skettenis {
104b725ae77Skettenis struct libunwind_descr *arch_descr;
105b725ae77Skettenis
106b725ae77Skettenis gdb_assert (gdbarch != NULL);
107b725ae77Skettenis
108b725ae77Skettenis arch_descr = gdbarch_data (gdbarch, libunwind_descr_handle);
109b725ae77Skettenis
110b725ae77Skettenis if (arch_descr == NULL)
111b725ae77Skettenis {
112b725ae77Skettenis /* First time here. Must initialize data area. */
113b725ae77Skettenis arch_descr = libunwind_descr_init (gdbarch);
114*11efff7fSkettenis deprecated_set_gdbarch_data (gdbarch, libunwind_descr_handle, arch_descr);
115b725ae77Skettenis }
116b725ae77Skettenis
117b725ae77Skettenis /* Copy new descriptor info into arch descriptor. */
118b725ae77Skettenis arch_descr->gdb2uw = descr->gdb2uw;
119b725ae77Skettenis arch_descr->uw2gdb = descr->uw2gdb;
120b725ae77Skettenis arch_descr->is_fpreg = descr->is_fpreg;
121b725ae77Skettenis arch_descr->accessors = descr->accessors;
122b725ae77Skettenis }
123b725ae77Skettenis
124b725ae77Skettenis static struct libunwind_frame_cache *
libunwind_frame_cache(struct frame_info * next_frame,void ** this_cache)125b725ae77Skettenis libunwind_frame_cache (struct frame_info *next_frame, void **this_cache)
126b725ae77Skettenis {
127b725ae77Skettenis unw_accessors_t *acc;
128b725ae77Skettenis unw_addr_space_t as;
129b725ae77Skettenis unw_word_t fp;
130b725ae77Skettenis unw_regnum_t uw_sp_regnum;
131b725ae77Skettenis struct libunwind_frame_cache *cache;
132b725ae77Skettenis struct libunwind_descr *descr;
133b725ae77Skettenis int i, ret;
134b725ae77Skettenis
135b725ae77Skettenis if (*this_cache)
136b725ae77Skettenis return *this_cache;
137b725ae77Skettenis
138b725ae77Skettenis /* Allocate a new cache. */
139b725ae77Skettenis cache = FRAME_OBSTACK_ZALLOC (struct libunwind_frame_cache);
140b725ae77Skettenis
141b725ae77Skettenis cache->func_addr = frame_func_unwind (next_frame);
142b725ae77Skettenis
143b725ae77Skettenis /* Get a libunwind cursor to the previous frame. We do this by initializing
144b725ae77Skettenis a cursor. Libunwind treats a new cursor as the top of stack and will get
145b725ae77Skettenis the current register set via the libunwind register accessor. Now, we
146b725ae77Skettenis provide the platform-specific accessors and we set up the register accessor to use
147b725ae77Skettenis the frame register unwinding interfaces so that we properly get the registers for
148b725ae77Skettenis the current frame rather than the top. We then use the unw_step function to
149b725ae77Skettenis move the libunwind cursor back one frame. We can later use this cursor to find previous
150b725ae77Skettenis registers via the unw_get_reg interface which will invoke libunwind's special logic. */
151b725ae77Skettenis descr = libunwind_descr (get_frame_arch (next_frame));
152b725ae77Skettenis acc = descr->accessors;
153b725ae77Skettenis as = unw_create_addr_space_p (acc,
154b725ae77Skettenis TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
155b725ae77Skettenis ? __BIG_ENDIAN
156b725ae77Skettenis : __LITTLE_ENDIAN);
157b725ae77Skettenis
158b725ae77Skettenis unw_init_remote_p (&cache->cursor, as, next_frame);
159b725ae77Skettenis unw_step_p (&cache->cursor);
160b725ae77Skettenis
161b725ae77Skettenis /* To get base address, get sp from previous frame. */
162b725ae77Skettenis uw_sp_regnum = descr->gdb2uw (SP_REGNUM);
163b725ae77Skettenis ret = unw_get_reg_p (&cache->cursor, uw_sp_regnum, &fp);
164b725ae77Skettenis if (ret < 0)
165b725ae77Skettenis error ("Can't get libunwind sp register.");
166b725ae77Skettenis
167b725ae77Skettenis cache->base = (CORE_ADDR)fp;
168b725ae77Skettenis
169b725ae77Skettenis *this_cache = cache;
170b725ae77Skettenis return cache;
171b725ae77Skettenis }
172b725ae77Skettenis
173b725ae77Skettenis unw_word_t
libunwind_find_dyn_list(unw_addr_space_t as,unw_dyn_info_t * di,void * arg)174b725ae77Skettenis libunwind_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg)
175b725ae77Skettenis {
176b725ae77Skettenis return unw_find_dyn_list_p (as, di, arg);
177b725ae77Skettenis }
178b725ae77Skettenis
179b725ae77Skettenis static const struct frame_unwind libunwind_frame_unwind =
180b725ae77Skettenis {
181b725ae77Skettenis NORMAL_FRAME,
182b725ae77Skettenis libunwind_frame_this_id,
183b725ae77Skettenis libunwind_frame_prev_register
184b725ae77Skettenis };
185b725ae77Skettenis
186b725ae77Skettenis /* Verify if there is sufficient libunwind information for the frame to use
187b725ae77Skettenis libunwind frame unwinding. */
188b725ae77Skettenis const struct frame_unwind *
libunwind_frame_sniffer(struct frame_info * next_frame)189b725ae77Skettenis libunwind_frame_sniffer (struct frame_info *next_frame)
190b725ae77Skettenis {
191b725ae77Skettenis unw_cursor_t cursor;
192b725ae77Skettenis unw_accessors_t *acc;
193b725ae77Skettenis unw_addr_space_t as;
194b725ae77Skettenis struct libunwind_descr *descr;
195b725ae77Skettenis int i, ret;
196b725ae77Skettenis
197b725ae77Skettenis /* To test for libunwind unwind support, initialize a cursor to the current frame and try to back
198b725ae77Skettenis up. We use this same method when setting up the frame cache (see libunwind_frame_cache()).
199b725ae77Skettenis If libunwind returns success for this operation, it means that it has found sufficient
200b725ae77Skettenis libunwind unwinding information to do so. */
201b725ae77Skettenis
202b725ae77Skettenis descr = libunwind_descr (get_frame_arch (next_frame));
203b725ae77Skettenis acc = descr->accessors;
204b725ae77Skettenis as = unw_create_addr_space_p (acc,
205b725ae77Skettenis TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
206b725ae77Skettenis ? __BIG_ENDIAN
207b725ae77Skettenis : __LITTLE_ENDIAN);
208b725ae77Skettenis
209b725ae77Skettenis ret = unw_init_remote_p (&cursor, as, next_frame);
210b725ae77Skettenis
211b725ae77Skettenis if (ret >= 0)
212b725ae77Skettenis ret = unw_step_p (&cursor);
213b725ae77Skettenis
214b725ae77Skettenis if (ret < 0)
215b725ae77Skettenis return NULL;
216b725ae77Skettenis
217b725ae77Skettenis return &libunwind_frame_unwind;
218b725ae77Skettenis }
219b725ae77Skettenis
220b725ae77Skettenis void
libunwind_frame_this_id(struct frame_info * next_frame,void ** this_cache,struct frame_id * this_id)221b725ae77Skettenis libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
222b725ae77Skettenis struct frame_id *this_id)
223b725ae77Skettenis {
224b725ae77Skettenis struct libunwind_frame_cache *cache =
225b725ae77Skettenis libunwind_frame_cache (next_frame, this_cache);
226b725ae77Skettenis
227b725ae77Skettenis (*this_id) = frame_id_build (cache->base, cache->func_addr);
228b725ae77Skettenis }
229b725ae77Skettenis
230b725ae77Skettenis void
libunwind_frame_prev_register(struct frame_info * next_frame,void ** this_cache,int regnum,int * optimizedp,enum lval_type * lvalp,CORE_ADDR * addrp,int * realnump,void * valuep)231b725ae77Skettenis libunwind_frame_prev_register (struct frame_info *next_frame, void **this_cache,
232b725ae77Skettenis int regnum, int *optimizedp,
233b725ae77Skettenis enum lval_type *lvalp, CORE_ADDR *addrp,
234b725ae77Skettenis int *realnump, void *valuep)
235b725ae77Skettenis {
236b725ae77Skettenis struct libunwind_frame_cache *cache =
237b725ae77Skettenis libunwind_frame_cache (next_frame, this_cache);
238b725ae77Skettenis
239b725ae77Skettenis void *ptr;
240b725ae77Skettenis unw_cursor_t *c;
241b725ae77Skettenis unw_save_loc_t sl;
242b725ae77Skettenis int i, ret;
243b725ae77Skettenis unw_word_t intval;
244b725ae77Skettenis unw_fpreg_t fpval;
245b725ae77Skettenis unw_regnum_t uw_regnum;
246b725ae77Skettenis struct libunwind_descr *descr;
247b725ae77Skettenis
248b725ae77Skettenis /* Convert from gdb register number to libunwind register number. */
249b725ae77Skettenis descr = libunwind_descr (get_frame_arch (next_frame));
250b725ae77Skettenis uw_regnum = descr->gdb2uw (regnum);
251b725ae77Skettenis
252b725ae77Skettenis gdb_assert (regnum >= 0);
253b725ae77Skettenis
254b725ae77Skettenis if (!target_has_registers)
255b725ae77Skettenis error ("No registers.");
256b725ae77Skettenis
257b725ae77Skettenis *optimizedp = 0;
258b725ae77Skettenis *addrp = 0;
259b725ae77Skettenis *lvalp = not_lval;
260b725ae77Skettenis *realnump = -1;
261b725ae77Skettenis
262*11efff7fSkettenis if (valuep)
263b725ae77Skettenis memset (valuep, 0, register_size (current_gdbarch, regnum));
264b725ae77Skettenis
265b725ae77Skettenis if (uw_regnum < 0)
266b725ae77Skettenis return;
267b725ae77Skettenis
268b725ae77Skettenis /* To get the previous register, we use the libunwind register APIs with
269b725ae77Skettenis the cursor we have already pushed back to the previous frame. */
270b725ae77Skettenis
271b725ae77Skettenis if (descr->is_fpreg (uw_regnum))
272b725ae77Skettenis {
273b725ae77Skettenis ret = unw_get_fpreg_p (&cache->cursor, uw_regnum, &fpval);
274b725ae77Skettenis ptr = &fpval;
275b725ae77Skettenis }
276b725ae77Skettenis else
277b725ae77Skettenis {
278b725ae77Skettenis ret = unw_get_reg_p (&cache->cursor, uw_regnum, &intval);
279b725ae77Skettenis ptr = &intval;
280b725ae77Skettenis }
281b725ae77Skettenis
282b725ae77Skettenis if (ret < 0)
283b725ae77Skettenis return;
284b725ae77Skettenis
285*11efff7fSkettenis if (valuep)
286b725ae77Skettenis memcpy (valuep, ptr, register_size (current_gdbarch, regnum));
287b725ae77Skettenis
288b725ae77Skettenis if (unw_get_saveloc_p (&cache->cursor, uw_regnum, &sl) < 0)
289b725ae77Skettenis return;
290b725ae77Skettenis
291b725ae77Skettenis switch (sl.type)
292b725ae77Skettenis {
293b725ae77Skettenis case UNW_SLT_NONE:
294b725ae77Skettenis *optimizedp = 1;
295b725ae77Skettenis break;
296b725ae77Skettenis
297b725ae77Skettenis case UNW_SLT_MEMORY:
298b725ae77Skettenis *lvalp = lval_memory;
299b725ae77Skettenis *addrp = sl.u.addr;
300b725ae77Skettenis break;
301b725ae77Skettenis
302b725ae77Skettenis case UNW_SLT_REG:
303b725ae77Skettenis *lvalp = lval_register;
304b725ae77Skettenis *realnump = regnum;
305b725ae77Skettenis break;
306b725ae77Skettenis }
307b725ae77Skettenis }
308b725ae77Skettenis
309b725ae77Skettenis CORE_ADDR
libunwind_frame_base_address(struct frame_info * next_frame,void ** this_cache)310b725ae77Skettenis libunwind_frame_base_address (struct frame_info *next_frame, void **this_cache)
311b725ae77Skettenis {
312b725ae77Skettenis struct libunwind_frame_cache *cache =
313b725ae77Skettenis libunwind_frame_cache (next_frame, this_cache);
314b725ae77Skettenis
315b725ae77Skettenis return cache->base;
316b725ae77Skettenis }
317b725ae77Skettenis
318b725ae77Skettenis /* The following is a glue routine to call the libunwind unwind table
319b725ae77Skettenis search function to get unwind information for a specified ip address. */
320b725ae77Skettenis int
libunwind_search_unwind_table(void * as,long ip,void * di,void * pi,int need_unwind_info,void * args)321b725ae77Skettenis libunwind_search_unwind_table (void *as, long ip, void *di,
322b725ae77Skettenis void *pi, int need_unwind_info, void *args)
323b725ae77Skettenis {
324b725ae77Skettenis return unw_search_unwind_table_p (*(unw_addr_space_t *)as, (unw_word_t )ip,
325b725ae77Skettenis di, pi, need_unwind_info, args);
326b725ae77Skettenis }
327b725ae77Skettenis
328b725ae77Skettenis static int
libunwind_load(void)329b725ae77Skettenis libunwind_load (void)
330b725ae77Skettenis {
331b725ae77Skettenis void *handle;
332b725ae77Skettenis
333b725ae77Skettenis handle = dlopen (LIBUNWIND_SO, RTLD_NOW);
334b725ae77Skettenis if (handle == NULL)
335b725ae77Skettenis return 0;
336b725ae77Skettenis
337b725ae77Skettenis /* Initialize pointers to the dynamic library functions we will use. */
338b725ae77Skettenis
339b725ae77Skettenis unw_get_reg_p = dlsym (handle, get_reg_name);
340b725ae77Skettenis if (unw_get_reg_p == NULL)
341b725ae77Skettenis return 0;
342b725ae77Skettenis
343b725ae77Skettenis unw_get_fpreg_p = dlsym (handle, get_fpreg_name);
344b725ae77Skettenis if (unw_get_fpreg_p == NULL)
345b725ae77Skettenis return 0;
346b725ae77Skettenis
347b725ae77Skettenis unw_get_saveloc_p = dlsym (handle, get_saveloc_name);
348b725ae77Skettenis if (unw_get_saveloc_p == NULL)
349b725ae77Skettenis return 0;
350b725ae77Skettenis
351b725ae77Skettenis unw_step_p = dlsym (handle, step_name);
352b725ae77Skettenis if (unw_step_p == NULL)
353b725ae77Skettenis return 0;
354b725ae77Skettenis
355b725ae77Skettenis unw_init_remote_p = dlsym (handle, init_remote_name);
356b725ae77Skettenis if (unw_init_remote_p == NULL)
357b725ae77Skettenis return 0;
358b725ae77Skettenis
359b725ae77Skettenis unw_create_addr_space_p = dlsym (handle, create_addr_space_name);
360b725ae77Skettenis if (unw_create_addr_space_p == NULL)
361b725ae77Skettenis return 0;
362b725ae77Skettenis
363b725ae77Skettenis unw_search_unwind_table_p = dlsym (handle, search_unwind_table_name);
364b725ae77Skettenis if (unw_search_unwind_table_p == NULL)
365b725ae77Skettenis return 0;
366b725ae77Skettenis
367b725ae77Skettenis unw_find_dyn_list_p = dlsym (handle, find_dyn_list_name);
368b725ae77Skettenis if (unw_find_dyn_list_p == NULL)
369b725ae77Skettenis return 0;
370b725ae77Skettenis
371b725ae77Skettenis return 1;
372b725ae77Skettenis }
373b725ae77Skettenis
374b725ae77Skettenis int
libunwind_is_initialized(void)375b725ae77Skettenis libunwind_is_initialized (void)
376b725ae77Skettenis {
377b725ae77Skettenis return libunwind_initialized;
378b725ae77Skettenis }
379b725ae77Skettenis
380b725ae77Skettenis /* Provide a prototype to silence -Wmissing-prototypes. */
381b725ae77Skettenis void _initialize_libunwind_frame (void);
382b725ae77Skettenis
383b725ae77Skettenis void
_initialize_libunwind_frame(void)384b725ae77Skettenis _initialize_libunwind_frame (void)
385b725ae77Skettenis {
386*11efff7fSkettenis libunwind_descr_handle = gdbarch_data_register_post_init (libunwind_descr_init);
387b725ae77Skettenis
388b725ae77Skettenis libunwind_initialized = libunwind_load ();
389b725ae77Skettenis }
390