This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFA: libunwind basic support


Please see latest patch attached which addresses questions below. I have added a configuration option: --enable-libunwind per your suggestion.

Ok so far? I have to wait for Kevin to get through my intermediate patch before I can send you the ia64-tdep.c side of the libunwind patch.

2003-10-15  Jeff Johnston  <jjohnstn@redhat.com>
	* libunwind-frame.c: New file.
	* libunwind-frame.h: New file.
	* configure.in: Add --enable-libunwind option support.
	* configure: Regenerated.
	* Makefile.in: Add support for libunwind-frame.o.
	* config.in: Regenerated.


J. Johnston wrote:
Andrew Cagney wrote:

Jeff,

Is it possible to post (or commit to a branch) the other (work-in-progress?) parts to this change?
Ignoring a few nits, this code appears to be going in the right direction, however its hard to tell without seeing things in toto.


The attached patch adds basic libunwind frame support. I will be shortly submitting an ia64-tdep.c patch which works in conjunction with this patch. The libunwind code is protected by looking for the libunwind header files to compile. At runtime, the libunwind frame sniffer will fail if either the libunwind library cannot be dynamically loaded or the frame in question does not have proper libunwind info.



First some straight legal questions:


- from where can libunwind be obtained?


http://www.hpl.hp.com/research/linux/libunwind/


- who owns it?


Hewlitt-Packard


- what are its licence terms, and are they GPL compatible?


It has a BSD-like license. Yes, it is GPL compatible.



Copyright (c) 2002 Hewlett-Packard Co.


Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

- is it considered a "system library" (like libc, or libthread_db)?


I would have to say no. It is currently an optional library. This is one of the reasons I chose to use a dynamic load mechanism.


- have you used, or refered to David Mossberger's [sp] old libunwind patch (it was eventually contributed to the FSF).


No. Not in this code.


For configuration I have added checks for libunwind.h and libunwind-ia64.h as this is being added for ia64 support only at present. Regarding testing, I have this code working with my ia64 changes. I have tested on systems with the libunwind-0.92 library/headers installed and not installed.



I see, to make this optional, you've wrapped the code in #ifdef HAVE_LIBUNWIND_H, and then modified the Makefile so that it is unconditionally built :-(


These files should only be linked in when when needed, or at least only when there's a libunwind around. Have a look at --with-mmalloc and --with-sysroot for how to implement the option --with-libunwind which lets the user force their inclusion; and --disable-gdbcli, --enable-tui, and --enable-sim for idea's on how to make linking the object files optional.


I'll take a look. The only thing this allows a user to do is to build gdb on a system that it can legimately build libunwind support and purposely disable it at configuration. Can you disable dwarf2 cfi support? If not, why would you want to do this for libunwind which is a similar level of functionality?


2003-10-15 Jeff Johnston <jjohnstn@redhat.com>

    * libunwind-frame.c: New file.
    * libunwind-frame.h: New file.
    * configure.in: Add checks for libunwind.h and libunwind-ia64.h.
    * configure: Regenerated.
    * Makefile.in: Add support for libunwind-frame.o.
    * config.in: Regenerated.



Without seeing the rest of the code I'm really not in a position to comment on the technical design.


However, a quick glance did through up a few nits. I'm noting them now, so that, hopefully an additional round trip can be avoided later.

+ Contributed by Jeff Johnston

Legal nit. "Written by Jeff Johnston, contributed by Red Hat Inc.", you don't have an assignment on file.


Will change.



+void
+libunwind_set_descr_handle (void *handle)
+{
+  libunwind_descr_handle = handle;
+}



I don't understand this. A guess is that this is trying to implement a mechanism that lets an external module set this modules per-architecture data? If that is the case, then can you have a look at the set_gdbarch_data doco and regrroups.c's reggroup_add method for how to do this?



I did look at said functionality originally. I ran into a problem which this solved. I will have to look again to see what the problem was because I don't remember off-hand.


+#define STRINGIFY2(name) #name
+#define STRINGIFY(name) STRINGIFY2(name)
+
+static char *get_reg_name = STRINGIFY(UNW_OBJ(get_reg));
+static char *get_fpreg_name = STRINGIFY(UNW_OBJ(get_fpreg));
+static char *get_saveloc_name = STRINGIFY(UNW_OBJ(get_saveloc));
+static char *step_name = STRINGIFY(UNW_OBJ(step));
+static char *init_remote_name = STRINGIFY(UNW_OBJ(init_remote));
+static char *create_addr_space_name = STRINGIFY(UNW_OBJ(create_addr_space));
+static char *search_unwind_table_name = STRINGIFY(UNW_OBJ(search_unwind_table));
+static char *find_dyn_list_name = STRINGIFY(UNW_OBJ(find_dyn_list));


I don't understand this. A guess is that UNW_OBJ() is doing something evil (use "include/sym-cat.h") to those names and having the array (use "static const char <name>[] = ..." and local to libunwind_load) makes ones debugging life much easier? If this is the case, can you add some commentary?


Yes. The libunwind code is slightly ugly with respect to the fact that the function names are not aliased with generic names. They all have platform prefixes so I must spell them out. Function names are generated automatically using the UNW_OBJ macro.


+ memset (valuep, 0, DEPRECATED_REGISTER_RAW_SIZE (regnum));

? you probably want register_size().


Yes.


+static int
+libunwind_load (void)
+{
+  void *handle;
+
+  handle = dlopen (LIBUNWIND_SO, RTLD_NOW);
+  if (handle == NULL)
+    return 0;

For thread-db.c I added code that printed out the library that was loaded. Should the same be done here? Note that, due to querks with the way GDB starts up, the message needs to be delayed - see thread-db.c for more details.


IMO, there is little value-add. There are architecture messages that will print out whether libunwind is being used or not. The problems with libthread-db don't exist in this case.


+const struct frame_unwind *
+libunwind_frame_sniffer (struct frame_info *next_frame);

can you please write the declaration thus:

const struct frame_unwind *libunwind_frame_sniffer (....

so that it is consistent with the rest of GDB.


Ok. I copied the declaration from below and forget to rejoin the lines.


-- Jeff J.


Index: libunwind-frame.c
===================================================================
RCS file: libunwind-frame.c
diff -N libunwind-frame.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libunwind-frame.c	22 Oct 2003 23:36:21 -0000
@@ -0,0 +1,376 @@
+/* Frame unwinder for frames using the libunwind library.
+
+   Copyright 2003 Free Software Foundation, Inc.
+
+   Written by Jeff Johnston, contributed by Red Hat Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+
+#ifdef HAVE_LIBUNWIND_H
+
+#include "inferior.h"
+#include "frame.h"
+#include "frame-base.h"
+#include "frame-unwind.h"
+#include "gdbcore.h"
+#include "gdbtypes.h"
+#include "symtab.h"
+#include "objfiles.h"
+#include "regcache.h"
+
+#include <dlfcn.h>
+
+#include "gdb_assert.h"
+#include "gdb_string.h"
+
+#include "libunwind-frame.h"
+
+#include "complaints.h"
+
+static int libunwind_initialized;
+static struct gdbarch_data *libunwind_descr_handle;
+
+#ifndef LIBUNWIND_SO
+#define LIBUNWIND_SO "libunwind.so"
+#endif
+
+/* Required function pointers from libunwind.  */
+static int (*unw_get_reg_p) (unw_cursor_t *, unw_regnum_t, unw_word_t *);
+static int (*unw_get_fpreg_p) (unw_cursor_t *, unw_regnum_t, unw_fpreg_t *);
+static int (*unw_get_saveloc_p) (unw_cursor_t *, unw_regnum_t, unw_save_loc_t *);
+static int (*unw_step_p) (unw_cursor_t *);
+static int (*unw_init_remote_p) (unw_cursor_t *, unw_addr_space_t, void *);
+static unw_addr_space_t (*unw_create_addr_space_p) (unw_accessors_t *, int);
+static int (*unw_search_unwind_table_p) (unw_addr_space_t, unw_word_t, unw_dyn_info_t *,
+					 unw_proc_info_t *, int, void *);
+static unw_word_t (*unw_find_dyn_list_p) (unw_addr_space_t, void *, size_t,
+					  unw_word_t, unw_word_t, void *);
+
+
+struct libunwind_frame_cache
+{
+  CORE_ADDR base;
+  CORE_ADDR func_addr;
+  unw_cursor_t cursor;
+};
+
+#define STRINGIFY2(name)	#name
+#define STRINGIFY(name)		STRINGIFY2(name)
+
+static char *get_reg_name = STRINGIFY(UNW_OBJ(get_reg));
+static char *get_fpreg_name = STRINGIFY(UNW_OBJ(get_fpreg));
+static char *get_saveloc_name = STRINGIFY(UNW_OBJ(get_saveloc));
+static char *step_name = STRINGIFY(UNW_OBJ(step));
+static char *init_remote_name = STRINGIFY(UNW_OBJ(init_remote));
+static char *create_addr_space_name = STRINGIFY(UNW_OBJ(create_addr_space));
+static char *search_unwind_table_name = STRINGIFY(UNW_OBJ(search_unwind_table));
+static char *find_dyn_list_name = STRINGIFY(UNW_OBJ(find_dyn_list));
+
+static struct libunwind_descr *
+libunwind_descr (struct gdbarch *gdbarch)
+{
+  return gdbarch_data (gdbarch, libunwind_descr_handle);
+}
+
+static void *
+libunwind_descr_init (struct gdbarch *gdbarch)
+{
+  struct libunwind_descr *descr = GDBARCH_OBSTACK_ZALLOC (gdbarch,
+							  struct libunwind_descr);
+  return descr;
+}
+
+void
+libunwind_frame_set_descr (struct gdbarch *gdbarch, struct libunwind_descr *descr)
+{
+  struct libunwind_descr *arch_descr;
+
+  gdb_assert (gdbarch != NULL);
+
+  arch_descr = gdbarch_data (gdbarch, libunwind_descr_handle);
+
+  if (arch_descr == NULL)
+    {
+      /* First time here.  Must initialize data area.  */
+      arch_descr = libunwind_descr_init (gdbarch);
+      set_gdbarch_data (gdbarch, libunwind_descr_handle, arch_descr);
+    }
+
+  /* Copy new descriptor info into arch descriptor.  */
+  arch_descr->gdb2uw = descr->gdb2uw;
+  arch_descr->uw2gdb = descr->uw2gdb;
+  arch_descr->is_fpreg = descr->is_fpreg;
+  arch_descr->accessors = descr->accessors;
+}
+
+static struct libunwind_frame_cache *
+libunwind_frame_cache (struct frame_info *next_frame, void **this_cache)
+{
+  unw_accessors_t *acc;
+  unw_addr_space_t as;
+  unw_word_t fp;
+  unw_regnum_t uw_sp_regnum;
+  struct libunwind_frame_cache *cache;
+  struct libunwind_descr *descr;
+  int i, ret;
+
+  if (*this_cache)
+    return *this_cache;
+
+  /* Allocate a new cache.  */
+  cache = FRAME_OBSTACK_ZALLOC (struct libunwind_frame_cache);
+
+  cache->func_addr = frame_func_unwind (next_frame);
+
+  /* Get a cursor to the previous frame.  We do this by initializing
+     a cursor and stepping back to the frame level prior to the one we are 
+     currently in.  */
+  descr = libunwind_descr (get_frame_arch (next_frame));
+  acc = descr->accessors;
+  as =  unw_create_addr_space_p (acc,
+				 TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+				 ? __BIG_ENDIAN
+				 : __LITTLE_ENDIAN);
+
+  unw_init_remote_p (&cache->cursor, as, next_frame);
+  unw_step_p (&cache->cursor);
+
+  /* To get base address, get sp from previous frame.  */
+  uw_sp_regnum = descr->gdb2uw (SP_REGNUM);
+  ret = unw_get_reg_p (&cache->cursor, uw_sp_regnum, &fp);
+  if (ret < 0)
+    error ("Can't get libunwind sp register.");
+
+  cache->base = (CORE_ADDR)fp;
+
+  *this_cache = cache;
+  return cache;
+}
+
+unw_word_t 
+libunwind_find_dyn_list (unw_addr_space_t as, void *table, size_t table_size,
+			 unw_word_t segbase, unw_word_t gp, void *arg)
+{
+  return unw_find_dyn_list_p (as, table, table_size, segbase, gp, arg);
+}
+
+static const struct frame_unwind libunwind_frame_unwind =
+{
+  NORMAL_FRAME,
+  libunwind_frame_this_id,
+  libunwind_frame_prev_register
+};
+
+const struct frame_unwind *
+libunwind_frame_sniffer (struct frame_info *next_frame)
+{
+  unw_cursor_t cursor;
+  unw_accessors_t *acc;
+  unw_addr_space_t as;
+  struct libunwind_descr *descr;
+  int i, ret;
+
+  /* Get a cursor to the previous frame.  We do this by initializing
+     a cursor and stepping back to the frame level prior to the one we are 
+     currently in.  */
+  descr = libunwind_descr (get_frame_arch (next_frame));
+  acc = descr->accessors;
+  as =  unw_create_addr_space_p (acc,
+				 TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+				 ? __BIG_ENDIAN
+				 : __LITTLE_ENDIAN);
+
+  ret = unw_init_remote_p (&cursor, as, next_frame);
+
+  if (ret >= 0)
+    ret = unw_step_p (&cursor);
+
+  if (ret < 0)
+    return NULL;
+
+  return &libunwind_frame_unwind;
+}
+
+void
+libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
+		      struct frame_id *this_id)
+{
+  struct libunwind_frame_cache *cache =
+    libunwind_frame_cache (next_frame, this_cache);
+
+  (*this_id) = frame_id_build (cache->base, cache->func_addr);
+}
+
+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)
+{
+  struct libunwind_frame_cache *cache =
+    libunwind_frame_cache (next_frame, this_cache);
+
+  void *ptr;
+  unw_cursor_t *c;
+  unw_save_loc_t sl;
+  int i, ret;
+  unw_word_t intval;
+  unw_fpreg_t fpval;
+  unw_regnum_t uw_regnum;
+  struct libunwind_descr *descr;
+
+  descr = libunwind_descr (get_frame_arch (next_frame));
+  uw_regnum = descr->gdb2uw (regnum);
+
+  gdb_assert (regnum >= 0);
+
+  if (!target_has_registers)
+    error ("No registers.");
+
+  *optimizedp = 0;
+  *addrp = 0;
+  *lvalp = not_lval;
+  *realnump = -1;
+
+  memset (valuep, 0, register_size (current_gdbarch, regnum));
+
+  if (uw_regnum < 0)
+    return;
+
+  if (descr->is_fpreg (uw_regnum))
+    {
+      ret = unw_get_fpreg_p (&cache->cursor, uw_regnum, &fpval);
+      ptr = &fpval;
+    }
+  else
+    {
+      ret = unw_get_reg_p (&cache->cursor, uw_regnum, &intval);
+      ptr = &intval;
+    }
+
+  if (ret < 0)
+    return;
+
+  memcpy (valuep, ptr, register_size (current_gdbarch, regnum));
+
+  if (unw_get_saveloc_p (&cache->cursor, uw_regnum, &sl) < 0)
+    return;
+
+  switch (sl.type)
+    {
+    case UNW_SLT_NONE:
+      *optimizedp = 1;
+      break;
+
+    case UNW_SLT_MEMORY:
+      *lvalp = lval_memory;
+      *addrp = sl.u.addr;
+      break;
+
+    case UNW_SLT_REG:
+      *lvalp = lval_register;
+      *realnump = regnum;
+      break;
+    }
+} 
+
+CORE_ADDR
+libunwind_frame_base_address (struct frame_info *next_frame, void **this_cache)
+{
+  struct libunwind_frame_cache *cache =
+    libunwind_frame_cache (next_frame, this_cache);
+
+  return cache->base;
+}
+
+int
+libunwind_search_unwind_table (void *as, long ip, void *di,
+			       void *pi, int need_unwind_info, void *args)
+{
+  return unw_search_unwind_table_p (*(unw_addr_space_t *)as, (unw_word_t )ip, 
+				    di, pi, need_unwind_info, args);
+}
+
+static int
+libunwind_load (void)
+{
+  void *handle;
+
+  handle = dlopen (LIBUNWIND_SO, RTLD_NOW);
+  if (handle == NULL)
+    return 0;
+
+  /* Initialize pointers to the dynamic library functions we will use.  */
+
+  unw_get_reg_p = dlsym (handle, get_reg_name);
+  if (unw_get_reg_p == NULL)
+    return 0;
+
+  unw_get_fpreg_p = dlsym (handle, get_fpreg_name);
+  if (unw_get_fpreg_p == NULL)
+    return 0;
+
+  unw_get_saveloc_p = dlsym (handle, get_saveloc_name);
+  if (unw_get_saveloc_p == NULL)
+    return 0;
+
+  unw_step_p = dlsym (handle, step_name);
+  if (unw_step_p == NULL)
+    return 0;
+
+  unw_init_remote_p = dlsym (handle, init_remote_name);
+  if (unw_init_remote_p == NULL)
+    return 0;
+
+  unw_create_addr_space_p = dlsym (handle, create_addr_space_name);
+  if (unw_create_addr_space_p == NULL)
+    return 0;
+
+  unw_search_unwind_table_p = dlsym (handle, search_unwind_table_name);
+  if (unw_search_unwind_table_p == NULL)
+    return 0;
+
+  unw_find_dyn_list_p = dlsym (handle, find_dyn_list_name);
+  if (unw_find_dyn_list_p == NULL)
+    return 0;
+   
+  return 1;
+}
+
+int
+libunwind_is_initialized (void)
+{
+  return libunwind_initialized;
+}
+
+#endif /* HAVE_LIBUNWIND_H  */
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+void _initialize_libunwind_frame (void);
+
+void
+_initialize_libunwind_frame (void)
+{
+#ifdef HAVE_LIBUNWIND_H
+  libunwind_descr_handle = register_gdbarch_data (libunwind_descr_init);
+
+  libunwind_initialized = libunwind_load ();
+#endif  
+}
Index: libunwind-frame.h
===================================================================
RCS file: libunwind-frame.h
diff -N libunwind-frame.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libunwind-frame.h	22 Oct 2003 23:36:21 -0000
@@ -0,0 +1,63 @@
+/* Frame unwinder for frames with libunwind frame information.
+
+   Copyright 2003 Free Software Foundation, Inc.
+
+   Contributed by Jeff Johnston.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_LIBUNWIND_H
+
+#ifndef LIBUNWIND_FRAME_H
+#define LIBUNWIND_FRAME_H 1
+
+#include "libunwind.h"
+
+struct frame_info;
+
+struct libunwind_descr
+{
+  int (*gdb2uw) (int);
+  int (*uw2gdb) (int);
+  int (*is_fpreg) (int);
+  void *accessors;
+};
+
+const struct frame_unwind *libunwind_frame_sniffer (struct frame_info *next_frame);
+
+void libunwind_frame_set_descr (struct gdbarch *arch, struct libunwind_descr *descr);
+
+void libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
+			      struct frame_id *this_id);
+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);
+CORE_ADDR libunwind_frame_base_address (struct frame_info *next_frame, void **this_cache);
+
+int libunwind_is_initialized (void);
+
+int libunwind_search_unwind_table (void *as, long ip, void *di,
+				   void *pi, int need_unwind_info, void *args);
+
+unw_word_t libunwind_find_dyn_list (unw_addr_space_t, void *, size_t,
+				    unw_word_t, unw_word_t, void *);
+     
+#endif /* libunwind-frame.h */
+
+#endif /* HAVE_LIBUNWIND_H  */
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.458
diff -u -r1.458 Makefile.in
--- Makefile.in	18 Oct 2003 18:41:22 -0000	1.458
+++ Makefile.in	22 Oct 2003 23:36:21 -0000
@@ -701,6 +701,7 @@
 jv_lang_h = jv-lang.h
 kod_h = kod.h
 language_h = language.h
+libunwind_frame_h = libunwind-frame.h
 linespec_h = linespec.h
 linux_nat_h = linux-nat.h
 m2_lang_h = m2-lang.h
@@ -1271,6 +1272,7 @@
 	i386gnu-nat.c i386gnu-tdep.c \
 	ia64-linux-nat.c ia64-linux-tdep.c ia64-tdep.c \
 	infptrace.c inftarg.c irix4-nat.c irix5-nat.c \
+	libunwind-frame.c \
 	lynx-nat.c m3-nat.c \
 	m68hc11-tdep.c \
 	m68k-tdep.c \
@@ -1897,7 +1899,7 @@
 	$(arch_utils_h) $(floatformat_h) $(regcache_h) $(reggroups_h) \
 	$(frame_h) $(frame_base_h) $(frame_unwind_h) $(doublest_h) \
 	$(value_h) $(gdb_assert_h) $(objfiles_h) $(elf_common_h) \
-	$(elf_bfd_h) $(dis_asm_h)
+	$(elf_bfd_h) $(dis_asm_h) $(libunwind_frame_h)
 infcall.o: infcall.c $(defs_h) $(breakpoint_h) $(target_h) $(regcache_h) \
 	$(inferior_h) $(gdb_assert_h) $(block_h) $(gdbcore_h) $(language_h) \
 	$(symfile_h) $(gdbcmd_h) $(command_h) $(gdb_string_h) $(infcall_h)
@@ -1945,6 +1947,10 @@
 language.o: language.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
 	$(value_h) $(gdbcmd_h) $(expression_h) $(language_h) $(target_h) \
 	$(parser_defs_h) $(jv_lang_h) $(demangle_h)
+libunwind-frame.o: libunwind-frame.c $(defs_h) \
+	$(frame_h) $(frame_base_h) $(frame_unwind_h) $(gdbcore_h) \
+	$(gdbtypes_h) $(symtab_h) $(objfiles_h) $(regcache_h) \
+	$(gdb_assert_h) $(gdb_string_h) $(complaints_h) $(libunwind_frame_h)
 linespec.o: linespec.c $(defs_h) $(symtab_h) $(frame_h) $(command_h) \
 	$(symfile_h) $(objfiles_h) $(source_h) $(demangle_h) $(value_h) \
 	$(completer_h) $(cp_abi_h) $(parser_defs_h) $(block_h) \
Index: configure.in
===================================================================
RCS file: /cvs/src/src/gdb/configure.in,v
retrieving revision 1.132
diff -u -r1.132 configure.in
--- configure.in	3 Sep 2003 15:02:48 -0000	1.132
+++ configure.in	22 Oct 2003 23:36:21 -0000
@@ -192,6 +192,33 @@
     enable_gdbtk=no ;;
 esac
 
+# Enable libunwind support.
+AC_ARG_ENABLE(libunwind,
+[  --enable-libunwind          enable libunwind frame unwinding support],
+  [case $enableval in
+    yes | no)
+      ;;
+    *)
+      AC_MSG_ERROR([bad value $enableval for --enable-libunwind]) ;;
+  esac])
+if test x"$enable_libunwind" = xyes; then
+  # We currently only support libunwind on selected platforms.
+  case $host in
+    ia64*)
+      ;;
+    *)
+      AC_MSG_WARN([libunwind isn't supported on $host; disabling])
+      enable_libunwind=no ;;
+  esac
+  if test x"$enable_libunwind" = xyes; then
+    AC_CHECK_HEADERS(libunwind.h)
+    AC_CHECK_HEADERS(libunwind-ia64.h)
+    CONFIG_OBS="$CONFIG_OBS libunwind-frame.o"
+    CONFIG_DEPS="$CONFIG_DEPS libunwind-frame.o"
+    CONFIG_SRCS="$CONFIG_SRCS libunwind-frame.c"
+  fi
+fi
+
 # Profiling support.
 AC_ARG_ENABLE(profiling,
 [  --enable-profiling      enable profiling of GDB],

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]