1130803Smarcel/* Frame unwinder for frames using the libunwind library.
2130803Smarcel
3130803Smarcel   Copyright 2003 Free Software Foundation, Inc.
4130803Smarcel
5130803Smarcel   Written by Jeff Johnston, contributed by Red Hat Inc.
6130803Smarcel
7130803Smarcel   This file is part of GDB.
8130803Smarcel
9130803Smarcel   This program is free software; you can redistribute it and/or modify
10130803Smarcel   it under the terms of the GNU General Public License as published by
11130803Smarcel   the Free Software Foundation; either version 2 of the License, or
12130803Smarcel   (at your option) any later version.
13130803Smarcel
14130803Smarcel   This program is distributed in the hope that it will be useful,
15130803Smarcel   but WITHOUT ANY WARRANTY; without even the implied warranty of
16130803Smarcel   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17130803Smarcel   GNU General Public License for more details.
18130803Smarcel
19130803Smarcel   You should have received a copy of the GNU General Public License
20130803Smarcel   along with this program; if not, write to the Free Software
21130803Smarcel   Foundation, Inc., 59 Temple Place - Suite 330,
22130803Smarcel   Boston, MA 02111-1307, USA.  */
23130803Smarcel
24130803Smarcel#include "defs.h"
25130803Smarcel
26130803Smarcel#include "inferior.h"
27130803Smarcel#include "frame.h"
28130803Smarcel#include "frame-base.h"
29130803Smarcel#include "frame-unwind.h"
30130803Smarcel#include "gdbcore.h"
31130803Smarcel#include "gdbtypes.h"
32130803Smarcel#include "symtab.h"
33130803Smarcel#include "objfiles.h"
34130803Smarcel#include "regcache.h"
35130803Smarcel
36130803Smarcel#include <dlfcn.h>
37130803Smarcel
38130803Smarcel#include "gdb_assert.h"
39130803Smarcel#include "gdb_string.h"
40130803Smarcel
41130803Smarcel#include "libunwind-frame.h"
42130803Smarcel
43130803Smarcel#include "complaints.h"
44130803Smarcel
45130803Smarcelstatic int libunwind_initialized;
46130803Smarcelstatic struct gdbarch_data *libunwind_descr_handle;
47130803Smarcel
48130803Smarcel#ifndef LIBUNWIND_SO
49130803Smarcel#define LIBUNWIND_SO "libunwind.so"
50130803Smarcel#endif
51130803Smarcel
52130803Smarcel/* Required function pointers from libunwind.  */
53130803Smarcelstatic int (*unw_get_reg_p) (unw_cursor_t *, unw_regnum_t, unw_word_t *);
54130803Smarcelstatic int (*unw_get_fpreg_p) (unw_cursor_t *, unw_regnum_t, unw_fpreg_t *);
55130803Smarcelstatic int (*unw_get_saveloc_p) (unw_cursor_t *, unw_regnum_t, unw_save_loc_t *);
56130803Smarcelstatic int (*unw_step_p) (unw_cursor_t *);
57130803Smarcelstatic int (*unw_init_remote_p) (unw_cursor_t *, unw_addr_space_t, void *);
58130803Smarcelstatic unw_addr_space_t (*unw_create_addr_space_p) (unw_accessors_t *, int);
59130803Smarcelstatic int (*unw_search_unwind_table_p) (unw_addr_space_t, unw_word_t, unw_dyn_info_t *,
60130803Smarcel					 unw_proc_info_t *, int, void *);
61130803Smarcelstatic unw_word_t (*unw_find_dyn_list_p) (unw_addr_space_t, unw_dyn_info_t *,
62130803Smarcel					  void *);
63130803Smarcel
64130803Smarcel
65130803Smarcelstruct libunwind_frame_cache
66130803Smarcel{
67130803Smarcel  CORE_ADDR base;
68130803Smarcel  CORE_ADDR func_addr;
69130803Smarcel  unw_cursor_t cursor;
70130803Smarcel};
71130803Smarcel
72130803Smarcel/* We need to qualify the function names with a platform-specific prefix to match
73130803Smarcel   the names used by the libunwind library.  The UNW_OBJ macro is provided by the
74130803Smarcel   libunwind.h header file.  */
75130803Smarcel#define STRINGIFY2(name)	#name
76130803Smarcel#define STRINGIFY(name)		STRINGIFY2(name)
77130803Smarcel
78130803Smarcelstatic char *get_reg_name = STRINGIFY(UNW_OBJ(get_reg));
79130803Smarcelstatic char *get_fpreg_name = STRINGIFY(UNW_OBJ(get_fpreg));
80130803Smarcelstatic char *get_saveloc_name = STRINGIFY(UNW_OBJ(get_save_loc));
81130803Smarcelstatic char *step_name = STRINGIFY(UNW_OBJ(step));
82130803Smarcelstatic char *init_remote_name = STRINGIFY(UNW_OBJ(init_remote));
83130803Smarcelstatic char *create_addr_space_name = STRINGIFY(UNW_OBJ(create_addr_space));
84130803Smarcelstatic char *search_unwind_table_name = STRINGIFY(UNW_OBJ(search_unwind_table));
85130803Smarcelstatic char *find_dyn_list_name = STRINGIFY(UNW_OBJ(find_dyn_list));
86130803Smarcel
87130803Smarcelstatic struct libunwind_descr *
88130803Smarcellibunwind_descr (struct gdbarch *gdbarch)
89130803Smarcel{
90130803Smarcel  return gdbarch_data (gdbarch, libunwind_descr_handle);
91130803Smarcel}
92130803Smarcel
93130803Smarcelstatic void *
94130803Smarcellibunwind_descr_init (struct gdbarch *gdbarch)
95130803Smarcel{
96130803Smarcel  struct libunwind_descr *descr = GDBARCH_OBSTACK_ZALLOC (gdbarch,
97130803Smarcel							  struct libunwind_descr);
98130803Smarcel  return descr;
99130803Smarcel}
100130803Smarcel
101130803Smarcelvoid
102130803Smarcellibunwind_frame_set_descr (struct gdbarch *gdbarch, struct libunwind_descr *descr)
103130803Smarcel{
104130803Smarcel  struct libunwind_descr *arch_descr;
105130803Smarcel
106130803Smarcel  gdb_assert (gdbarch != NULL);
107130803Smarcel
108130803Smarcel  arch_descr = gdbarch_data (gdbarch, libunwind_descr_handle);
109130803Smarcel
110130803Smarcel  if (arch_descr == NULL)
111130803Smarcel    {
112130803Smarcel      /* First time here.  Must initialize data area.  */
113130803Smarcel      arch_descr = libunwind_descr_init (gdbarch);
114130803Smarcel      set_gdbarch_data (gdbarch, libunwind_descr_handle, arch_descr);
115130803Smarcel    }
116130803Smarcel
117130803Smarcel  /* Copy new descriptor info into arch descriptor.  */
118130803Smarcel  arch_descr->gdb2uw = descr->gdb2uw;
119130803Smarcel  arch_descr->uw2gdb = descr->uw2gdb;
120130803Smarcel  arch_descr->is_fpreg = descr->is_fpreg;
121130803Smarcel  arch_descr->accessors = descr->accessors;
122130803Smarcel}
123130803Smarcel
124130803Smarcelstatic struct libunwind_frame_cache *
125130803Smarcellibunwind_frame_cache (struct frame_info *next_frame, void **this_cache)
126130803Smarcel{
127130803Smarcel  unw_accessors_t *acc;
128130803Smarcel  unw_addr_space_t as;
129130803Smarcel  unw_word_t fp;
130130803Smarcel  unw_regnum_t uw_sp_regnum;
131130803Smarcel  struct libunwind_frame_cache *cache;
132130803Smarcel  struct libunwind_descr *descr;
133130803Smarcel  int i, ret;
134130803Smarcel
135130803Smarcel  if (*this_cache)
136130803Smarcel    return *this_cache;
137130803Smarcel
138130803Smarcel  /* Allocate a new cache.  */
139130803Smarcel  cache = FRAME_OBSTACK_ZALLOC (struct libunwind_frame_cache);
140130803Smarcel
141130803Smarcel  cache->func_addr = frame_func_unwind (next_frame);
142130803Smarcel
143130803Smarcel  /* Get a libunwind cursor to the previous frame.  We do this by initializing
144130803Smarcel     a cursor.  Libunwind treats a new cursor as the top of stack and will get
145130803Smarcel     the current register set via the libunwind register accessor.  Now, we
146130803Smarcel     provide the platform-specific accessors and we set up the register accessor to use
147130803Smarcel     the frame register unwinding interfaces so that we properly get the registers for
148130803Smarcel     the current frame rather than the top.  We then use the  unw_step function to
149130803Smarcel     move the libunwind cursor back one frame.  We can later use this cursor to find previous
150130803Smarcel     registers via the unw_get_reg interface which will invoke libunwind's special logic.  */
151130803Smarcel  descr = libunwind_descr (get_frame_arch (next_frame));
152130803Smarcel  acc = descr->accessors;
153130803Smarcel  as =  unw_create_addr_space_p (acc,
154130803Smarcel				 TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
155130803Smarcel				 ? __BIG_ENDIAN
156130803Smarcel				 : __LITTLE_ENDIAN);
157130803Smarcel
158130803Smarcel  unw_init_remote_p (&cache->cursor, as, next_frame);
159130803Smarcel  unw_step_p (&cache->cursor);
160130803Smarcel
161130803Smarcel  /* To get base address, get sp from previous frame.  */
162130803Smarcel  uw_sp_regnum = descr->gdb2uw (SP_REGNUM);
163130803Smarcel  ret = unw_get_reg_p (&cache->cursor, uw_sp_regnum, &fp);
164130803Smarcel  if (ret < 0)
165130803Smarcel    error ("Can't get libunwind sp register.");
166130803Smarcel
167130803Smarcel  cache->base = (CORE_ADDR)fp;
168130803Smarcel
169130803Smarcel  *this_cache = cache;
170130803Smarcel  return cache;
171130803Smarcel}
172130803Smarcel
173130803Smarcelunw_word_t
174130803Smarcellibunwind_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg)
175130803Smarcel{
176130803Smarcel  return unw_find_dyn_list_p (as, di, arg);
177130803Smarcel}
178130803Smarcel
179130803Smarcelstatic const struct frame_unwind libunwind_frame_unwind =
180130803Smarcel{
181130803Smarcel  NORMAL_FRAME,
182130803Smarcel  libunwind_frame_this_id,
183130803Smarcel  libunwind_frame_prev_register
184130803Smarcel};
185130803Smarcel
186130803Smarcel/* Verify if there is sufficient libunwind information for the frame to use
187130803Smarcel   libunwind frame unwinding.  */
188130803Smarcelconst struct frame_unwind *
189130803Smarcellibunwind_frame_sniffer (struct frame_info *next_frame)
190130803Smarcel{
191130803Smarcel  unw_cursor_t cursor;
192130803Smarcel  unw_accessors_t *acc;
193130803Smarcel  unw_addr_space_t as;
194130803Smarcel  struct libunwind_descr *descr;
195130803Smarcel  int i, ret;
196130803Smarcel
197130803Smarcel  /* To test for libunwind unwind support, initialize a cursor to the current frame and try to back
198130803Smarcel     up.  We use this same method when setting up the frame cache (see libunwind_frame_cache()).
199130803Smarcel     If libunwind returns success for this operation, it means that it has found sufficient
200130803Smarcel     libunwind unwinding information to do so.  */
201130803Smarcel
202130803Smarcel  descr = libunwind_descr (get_frame_arch (next_frame));
203130803Smarcel  acc = descr->accessors;
204130803Smarcel  as =  unw_create_addr_space_p (acc,
205130803Smarcel				 TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
206130803Smarcel				 ? __BIG_ENDIAN
207130803Smarcel				 : __LITTLE_ENDIAN);
208130803Smarcel
209130803Smarcel  ret = unw_init_remote_p (&cursor, as, next_frame);
210130803Smarcel
211130803Smarcel  if (ret >= 0)
212130803Smarcel    ret = unw_step_p (&cursor);
213130803Smarcel
214130803Smarcel  if (ret < 0)
215130803Smarcel    return NULL;
216130803Smarcel
217130803Smarcel  return &libunwind_frame_unwind;
218130803Smarcel}
219130803Smarcel
220130803Smarcelvoid
221130803Smarcellibunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
222130803Smarcel		      struct frame_id *this_id)
223130803Smarcel{
224130803Smarcel  struct libunwind_frame_cache *cache =
225130803Smarcel    libunwind_frame_cache (next_frame, this_cache);
226130803Smarcel
227130803Smarcel  (*this_id) = frame_id_build (cache->base, cache->func_addr);
228130803Smarcel}
229130803Smarcel
230130803Smarcelvoid
231130803Smarcellibunwind_frame_prev_register (struct frame_info *next_frame, void **this_cache,
232130803Smarcel			       int regnum, int *optimizedp,
233130803Smarcel			       enum lval_type *lvalp, CORE_ADDR *addrp,
234130803Smarcel			       int *realnump, void *valuep)
235130803Smarcel{
236130803Smarcel  struct libunwind_frame_cache *cache =
237130803Smarcel    libunwind_frame_cache (next_frame, this_cache);
238130803Smarcel
239130803Smarcel  void *ptr;
240130803Smarcel  unw_cursor_t *c;
241130803Smarcel  unw_save_loc_t sl;
242130803Smarcel  int i, ret;
243130803Smarcel  unw_word_t intval;
244130803Smarcel  unw_fpreg_t fpval;
245130803Smarcel  unw_regnum_t uw_regnum;
246130803Smarcel  struct libunwind_descr *descr;
247130803Smarcel
248130803Smarcel  /* Convert from gdb register number to libunwind register number.  */
249130803Smarcel  descr = libunwind_descr (get_frame_arch (next_frame));
250130803Smarcel  uw_regnum = descr->gdb2uw (regnum);
251130803Smarcel
252130803Smarcel  gdb_assert (regnum >= 0);
253130803Smarcel
254130803Smarcel  if (!target_has_registers)
255130803Smarcel    error ("No registers.");
256130803Smarcel
257130803Smarcel  *optimizedp = 0;
258130803Smarcel  *addrp = 0;
259130803Smarcel  *lvalp = not_lval;
260130803Smarcel  *realnump = -1;
261130803Smarcel
262130803Smarcel  memset (valuep, 0, register_size (current_gdbarch, regnum));
263130803Smarcel
264130803Smarcel  if (uw_regnum < 0)
265130803Smarcel    return;
266130803Smarcel
267130803Smarcel  /* To get the previous register, we use the libunwind register APIs with
268130803Smarcel     the cursor we have already pushed back to the previous frame.  */
269130803Smarcel
270130803Smarcel  if (descr->is_fpreg (uw_regnum))
271130803Smarcel    {
272130803Smarcel      ret = unw_get_fpreg_p (&cache->cursor, uw_regnum, &fpval);
273130803Smarcel      ptr = &fpval;
274130803Smarcel    }
275130803Smarcel  else
276130803Smarcel    {
277130803Smarcel      ret = unw_get_reg_p (&cache->cursor, uw_regnum, &intval);
278130803Smarcel      ptr = &intval;
279130803Smarcel    }
280130803Smarcel
281130803Smarcel  if (ret < 0)
282130803Smarcel    return;
283130803Smarcel
284130803Smarcel  memcpy (valuep, ptr, register_size (current_gdbarch, regnum));
285130803Smarcel
286130803Smarcel  if (unw_get_saveloc_p (&cache->cursor, uw_regnum, &sl) < 0)
287130803Smarcel    return;
288130803Smarcel
289130803Smarcel  switch (sl.type)
290130803Smarcel    {
291130803Smarcel    case UNW_SLT_NONE:
292130803Smarcel      *optimizedp = 1;
293130803Smarcel      break;
294130803Smarcel
295130803Smarcel    case UNW_SLT_MEMORY:
296130803Smarcel      *lvalp = lval_memory;
297130803Smarcel      *addrp = sl.u.addr;
298130803Smarcel      break;
299130803Smarcel
300130803Smarcel    case UNW_SLT_REG:
301130803Smarcel      *lvalp = lval_register;
302130803Smarcel      *realnump = regnum;
303130803Smarcel      break;
304130803Smarcel    }
305130803Smarcel}
306130803Smarcel
307130803SmarcelCORE_ADDR
308130803Smarcellibunwind_frame_base_address (struct frame_info *next_frame, void **this_cache)
309130803Smarcel{
310130803Smarcel  struct libunwind_frame_cache *cache =
311130803Smarcel    libunwind_frame_cache (next_frame, this_cache);
312130803Smarcel
313130803Smarcel  return cache->base;
314130803Smarcel}
315130803Smarcel
316130803Smarcel/* The following is a glue routine to call the libunwind unwind table
317130803Smarcel   search function to get unwind information for a specified ip address.  */
318130803Smarcelint
319130803Smarcellibunwind_search_unwind_table (void *as, long ip, void *di,
320130803Smarcel			       void *pi, int need_unwind_info, void *args)
321130803Smarcel{
322130803Smarcel  return unw_search_unwind_table_p (*(unw_addr_space_t *)as, (unw_word_t )ip,
323130803Smarcel				    di, pi, need_unwind_info, args);
324130803Smarcel}
325130803Smarcel
326130803Smarcelstatic int
327130803Smarcellibunwind_load (void)
328130803Smarcel{
329130803Smarcel  void *handle;
330130803Smarcel
331130803Smarcel  handle = dlopen (LIBUNWIND_SO, RTLD_NOW);
332130803Smarcel  if (handle == NULL)
333130803Smarcel    return 0;
334130803Smarcel
335130803Smarcel  /* Initialize pointers to the dynamic library functions we will use.  */
336130803Smarcel
337130803Smarcel  unw_get_reg_p = dlsym (handle, get_reg_name);
338130803Smarcel  if (unw_get_reg_p == NULL)
339130803Smarcel    return 0;
340130803Smarcel
341130803Smarcel  unw_get_fpreg_p = dlsym (handle, get_fpreg_name);
342130803Smarcel  if (unw_get_fpreg_p == NULL)
343130803Smarcel    return 0;
344130803Smarcel
345130803Smarcel  unw_get_saveloc_p = dlsym (handle, get_saveloc_name);
346130803Smarcel  if (unw_get_saveloc_p == NULL)
347130803Smarcel    return 0;
348130803Smarcel
349130803Smarcel  unw_step_p = dlsym (handle, step_name);
350130803Smarcel  if (unw_step_p == NULL)
351130803Smarcel    return 0;
352130803Smarcel
353130803Smarcel  unw_init_remote_p = dlsym (handle, init_remote_name);
354130803Smarcel  if (unw_init_remote_p == NULL)
355130803Smarcel    return 0;
356130803Smarcel
357130803Smarcel  unw_create_addr_space_p = dlsym (handle, create_addr_space_name);
358130803Smarcel  if (unw_create_addr_space_p == NULL)
359130803Smarcel    return 0;
360130803Smarcel
361130803Smarcel  unw_search_unwind_table_p = dlsym (handle, search_unwind_table_name);
362130803Smarcel  if (unw_search_unwind_table_p == NULL)
363130803Smarcel    return 0;
364130803Smarcel
365130803Smarcel  unw_find_dyn_list_p = dlsym (handle, find_dyn_list_name);
366130803Smarcel  if (unw_find_dyn_list_p == NULL)
367130803Smarcel    return 0;
368130803Smarcel
369130803Smarcel  return 1;
370130803Smarcel}
371130803Smarcel
372130803Smarcelint
373130803Smarcellibunwind_is_initialized (void)
374130803Smarcel{
375130803Smarcel  return libunwind_initialized;
376130803Smarcel}
377130803Smarcel
378130803Smarcel/* Provide a prototype to silence -Wmissing-prototypes.  */
379130803Smarcelvoid _initialize_libunwind_frame (void);
380130803Smarcel
381130803Smarcelvoid
382130803Smarcel_initialize_libunwind_frame (void)
383130803Smarcel{
384130803Smarcel  libunwind_descr_handle = register_gdbarch_data (libunwind_descr_init);
385130803Smarcel
386130803Smarcel  libunwind_initialized = libunwind_load ();
387130803Smarcel}
388