From 696759ad10c791600443c81e1416d0a2b61c1b3a Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Mon, 5 Mar 2012 11:41:51 +0000 Subject: [PATCH] 2012-03-05 Tristan Gingold * ia64-tdep.h: Include libunwind-frame.h and libunwind-ia64.h. (ia64_unw_accessors, ia64_unw_rse_accessors) (ia64_libunwind_descr): Declare. * ia64-vms-tdep.c: New file. * ia64-tdep.c (ia64_unw_accessors, ia64_unw_rse_accessors) (ia64_libunwind_descr): Make them public. * configure.tgt: Add ia64-*-*vms*. * Makefile.in (ALL_64_TARGET_OBS): Add ia64-vms-tdep.o (ALLDEPFILES): Add ia64-vms-tdep.c --- gdb/ChangeLog | 12 ++++ gdb/Makefile.in | 4 +- gdb/configure.tgt | 4 ++ gdb/ia64-tdep.c | 6 +- gdb/ia64-tdep.h | 11 +++ gdb/ia64-vms-tdep.c | 165 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 197 insertions(+), 5 deletions(-) create mode 100644 gdb/ia64-vms-tdep.c diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f3e90134bc..b652b87374 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2012-03-05 Tristan Gingold + + * ia64-tdep.h: Include libunwind-frame.h and libunwind-ia64.h. + (ia64_unw_accessors, ia64_unw_rse_accessors) + (ia64_libunwind_descr): Declare. + * ia64-vms-tdep.c: New file. + * ia64-tdep.c (ia64_unw_accessors, ia64_unw_rse_accessors) + (ia64_libunwind_descr): Make them public. + * configure.tgt: Add ia64-*-*vms*. + * Makefile.in (ALL_64_TARGET_OBS): Add ia64-vms-tdep.o + (ALLDEPFILES): Add ia64-vms-tdep.c + 2012-03-05 Tristan Gingold * target.h (target_object): Add TARGET_OBJECT_OPENVMS_UIB. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index dc473da838..1846c74d57 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -516,7 +516,7 @@ ALL_64_TARGET_OBS = \ amd64fbsd-tdep.o amd64-darwin-tdep.o amd64-dicos-tdep.o \ amd64-linux-tdep.o amd64nbsd-tdep.o \ amd64obsd-tdep.o amd64-sol2-tdep.o amd64-tdep.o amd64-windows-tdep.o \ - ia64-hpux-tdep.o ia64-linux-tdep.o ia64-tdep.o \ + ia64-hpux-tdep.o ia64-linux-tdep.o ia64-vms-tdep.o ia64-tdep.o \ mips64obsd-tdep.o \ sparc64fbsd-tdep.o sparc64-linux-tdep.o sparc64nbsd-tdep.o \ sparc64obsd-tdep.o sparc64-sol2-tdep.o sparc64-tdep.o @@ -1460,7 +1460,7 @@ ALLDEPFILES = \ i386-sol2-nat.c i386-sol2-tdep.c \ i386gnu-nat.c i386gnu-tdep.c \ ia64-hpux-nat.c ia64-hpux-tdep.c \ - ia64-linux-nat.c ia64-linux-tdep.c ia64-tdep.c \ + ia64-linux-nat.c ia64-linux-tdep.c ia64-tdep.c ia64-vms-tdep.c \ inf-ptrace.c inf-ttrace.c \ irix5-nat.c \ libunwind-frame.c \ diff --git a/gdb/configure.tgt b/gdb/configure.tgt index 5e97ab4e70..6b4a504a24 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -246,6 +246,10 @@ ia64-*-linux*) solib-svr4.o symfile-mem.o" build_gdbserver=yes ;; +ia64-*-*vms*) + # Target: Intel IA-64 running OpenVMS + gdb_target_obs="ia64-tdep.o ia64-vms-tdep.o" + ;; ia64*-*-*) # Target: Intel IA-64 gdb_target_obs="ia64-tdep.o" diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c index a36dc223af..1c4fa8f67c 100644 --- a/gdb/ia64-tdep.c +++ b/gdb/ia64-tdep.c @@ -3148,7 +3148,7 @@ static const struct frame_unwind ia64_libunwind_sigtramp_frame_unwind = }; /* Set of libunwind callback acccessor functions. */ -static unw_accessors_t ia64_unw_accessors = +unw_accessors_t ia64_unw_accessors = { ia64_find_proc_info_x, ia64_put_unwind_info, @@ -3164,7 +3164,7 @@ static unw_accessors_t ia64_unw_accessors = the rse registers. At the top of the stack, we want libunwind to figure out how to read r32 - r127. Though usually they are found sequentially in memory starting from $bof, this is not always true. */ -static unw_accessors_t ia64_unw_rse_accessors = +unw_accessors_t ia64_unw_rse_accessors = { ia64_find_proc_info_x, ia64_put_unwind_info, @@ -3178,7 +3178,7 @@ static unw_accessors_t ia64_unw_rse_accessors = /* Set of ia64 gdb libunwind-frame callbacks and data for generic libunwind-frame code to use. */ -static struct libunwind_descr ia64_libunwind_descr = +struct libunwind_descr ia64_libunwind_descr = { ia64_gdb2uw_regnum, ia64_uw2gdb_regnum, diff --git a/gdb/ia64-tdep.h b/gdb/ia64-tdep.h index 48cc3e0f4d..7501eb417b 100644 --- a/gdb/ia64-tdep.h +++ b/gdb/ia64-tdep.h @@ -20,6 +20,11 @@ #ifndef IA64_TDEP_H #define IA64_TDEP_H +#ifdef HAVE_LIBUNWIND_IA64_H +#include "libunwind-ia64.h" +#include "libunwind-frame.h" +#endif + /* Register numbers of various important registers. */ /* General registers; there are 128 of these 64 bit wide registers. @@ -250,4 +255,10 @@ struct gdbarch_tdep extern void ia64_write_pc (struct regcache *, CORE_ADDR); +#ifdef HAVE_LIBUNWIND_IA64_H +extern unw_accessors_t ia64_unw_accessors; +extern unw_accessors_t ia64_unw_rse_accessors; +extern struct libunwind_descr ia64_libunwind_descr; +#endif + #endif /* ia64-tdep.h */ diff --git a/gdb/ia64-vms-tdep.c b/gdb/ia64-vms-tdep.c new file mode 100644 index 0000000000..859c0b46bf --- /dev/null +++ b/gdb/ia64-vms-tdep.c @@ -0,0 +1,165 @@ +/* Target-dependent code for OpenVMS IA-64. + + Copyright (C) 2012 Free Software Foundation, 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 3 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, see . */ + +#include "defs.h" +#include "frame-unwind.h" +#include "ia64-tdep.h" +#include "osabi.h" +#include "gdbtypes.h" +#include "gdbcore.h" + +#ifdef HAVE_LIBUNWIND_IA64_H + +/* Libunwind callback accessor function to acquire procedure unwind-info. */ + +static int +ia64_vms_find_proc_info_x (unw_addr_space_t as, unw_word_t ip, + unw_proc_info_t *pi, + int need_unwind_info, void *arg) +{ + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); + unw_dyn_info_t di; + int ret; + gdb_byte buf[32]; + const char *annex = core_addr_to_string (ip); + LONGEST res; + CORE_ADDR table_addr; + unsigned int info_len; + + res = target_read (¤t_target, TARGET_OBJECT_OPENVMS_UIB, + annex + 2, buf, 0, sizeof (buf)); + + if (res != sizeof (buf)) + return -UNW_ENOINFO; + + pi->format = UNW_INFO_FORMAT_REMOTE_TABLE; + pi->start_ip = extract_unsigned_integer (buf + 0, 8, byte_order); + pi->end_ip = extract_unsigned_integer (buf + 8, 8, byte_order); + pi->gp = extract_unsigned_integer (buf + 24, 8, byte_order); + table_addr = extract_unsigned_integer (buf + 16, 8, byte_order); + + if (table_addr == 0) + { + /* No unwind data. */ + pi->unwind_info = NULL; + pi->unwind_info_size = 0; + return 0; + } + + res = target_read_memory (table_addr, buf, 8); + if (res != 0) + return -UNW_ENOINFO; + + /* Check version. */ + if (extract_unsigned_integer (buf + 6, 2, byte_order) != 1) + return -UNW_EBADVERSION; + info_len = extract_unsigned_integer (buf + 0, 4, byte_order); + pi->unwind_info_size = 8 * info_len; + + /* Read info. */ + pi->unwind_info = xmalloc (pi->unwind_info_size); + + res = target_read_memory (table_addr + 8, + pi->unwind_info, pi->unwind_info_size); + if (res != 0) + { + xfree (pi->unwind_info); + pi->unwind_info = NULL; + return -UNW_ENOINFO; + } + + /* FIXME: Handle OSSD (OS Specific Data). This extension to ia64 unwind + information by OpenVMS is currently not handled by libunwind, but + looks to be used only in very specific context, and is not generated by + GCC. */ + + pi->lsda = table_addr + 8 + pi->unwind_info_size; + if (extract_unsigned_integer (buf + 4, 2, byte_order) & 3) + { + pi->lsda += 8; + /* There might be an handler, but this is not used for unwinding. */ + pi->handler = 0; + } + + return 0; +} + +/* Libunwind callback accessor function for cleanup. */ + +static void +ia64_vms_put_unwind_info (unw_addr_space_t as, + unw_proc_info_t *pip, void *arg) +{ + /* Nothing required for now. */ +} + +/* Libunwind callback accessor function to get head of the dynamic + unwind-info registration list. */ + +static int +ia64_vms_get_dyn_info_list (unw_addr_space_t as, + unw_word_t *dilap, void *arg) +{ + return -UNW_ENOINFO; +} + +/* Set of libunwind callback acccessor functions. */ +static unw_accessors_t ia64_vms_unw_accessors; +static unw_accessors_t ia64_vms_unw_rse_accessors; + +/* Set of ia64 gdb libunwind-frame callbacks and data for generic + libunwind-frame code to use. */ +static struct libunwind_descr ia64_vms_libunwind_descr; + +#endif /* HAVE_LIBUNWIND_IA64_H */ + +static void +ia64_openvms_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + set_gdbarch_long_double_format (gdbarch, floatformats_ia64_quad); + +#ifdef HAVE_LIBUNWIND_IA64_H + /* Override the default descriptor. */ + ia64_vms_unw_accessors = ia64_unw_accessors; + ia64_vms_unw_accessors.find_proc_info = ia64_vms_find_proc_info_x; + ia64_vms_unw_accessors.put_unwind_info = ia64_vms_put_unwind_info; + ia64_vms_unw_accessors.get_dyn_info_list_addr = ia64_vms_get_dyn_info_list; + + ia64_vms_unw_rse_accessors = ia64_unw_rse_accessors; + ia64_vms_unw_rse_accessors.find_proc_info = ia64_vms_find_proc_info_x; + ia64_vms_unw_rse_accessors.put_unwind_info = ia64_vms_put_unwind_info; + ia64_vms_unw_rse_accessors.get_dyn_info_list_addr = ia64_vms_get_dyn_info_list; + + ia64_vms_libunwind_descr = ia64_libunwind_descr; + ia64_vms_libunwind_descr.accessors = &ia64_vms_unw_accessors; + ia64_vms_libunwind_descr.special_accessors = &ia64_vms_unw_rse_accessors; + + libunwind_frame_set_descr (gdbarch, &ia64_vms_libunwind_descr); +#endif +} + +/* Provide a prototype to silence -Wmissing-prototypes. */ +extern initialize_file_ftype _initialize_ia64_hpux_tdep; + +void +_initialize_ia64_hpux_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_ia64, 0, GDB_OSABI_OPENVMS, + ia64_openvms_init_abi); +} -- 2.34.1