GDB (API)
/home/stan/gdb/src/gdb/ia64-vms-tdep.c
Go to the documentation of this file.
00001 /* Target-dependent code for OpenVMS IA-64.
00002 
00003    Copyright (C) 2012-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "frame-unwind.h"
00022 #include "ia64-tdep.h"
00023 #include "osabi.h"
00024 #include "gdbtypes.h"
00025 #include "gdbcore.h"
00026 
00027 #ifdef HAVE_LIBUNWIND_IA64_H
00028 
00029 /* Libunwind callback accessor function to acquire procedure unwind-info.  */
00030 
00031 static int
00032 ia64_vms_find_proc_info_x (unw_addr_space_t as, unw_word_t ip,
00033                            unw_proc_info_t *pi,
00034                            int need_unwind_info, void *arg)
00035 {
00036   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
00037   unw_dyn_info_t di;
00038   int ret;
00039   gdb_byte buf[32];
00040   const char *annex = core_addr_to_string (ip);
00041   LONGEST res;
00042   CORE_ADDR table_addr;
00043   unsigned int info_len;
00044 
00045   res = target_read (&current_target, TARGET_OBJECT_OPENVMS_UIB,
00046                      annex + 2, buf, 0, sizeof (buf));
00047 
00048   if (res != sizeof (buf))
00049     return -UNW_ENOINFO;
00050 
00051   pi->format = UNW_INFO_FORMAT_REMOTE_TABLE;
00052   pi->start_ip = extract_unsigned_integer (buf + 0, 8, byte_order);
00053   pi->end_ip = extract_unsigned_integer (buf + 8, 8, byte_order);
00054   pi->gp = extract_unsigned_integer (buf + 24, 8, byte_order);
00055   table_addr = extract_unsigned_integer (buf + 16, 8, byte_order);
00056 
00057   if (table_addr == 0)
00058     {
00059       /* No unwind data.  */
00060       pi->unwind_info = NULL;
00061       pi->unwind_info_size = 0;
00062       return 0;
00063     }
00064 
00065   res = target_read_memory (table_addr, buf, 8);
00066   if (res != 0)
00067     return -UNW_ENOINFO;
00068 
00069   /* Check version.  */
00070   if (extract_unsigned_integer (buf + 6, 2, byte_order) != 1)
00071     return -UNW_EBADVERSION;
00072   info_len = extract_unsigned_integer (buf + 0, 4, byte_order);
00073   pi->unwind_info_size = 8 * info_len;
00074 
00075   /* Read info.  */
00076   pi->unwind_info = xmalloc (pi->unwind_info_size);
00077 
00078   res = target_read_memory (table_addr + 8,
00079                             pi->unwind_info, pi->unwind_info_size);
00080   if (res != 0)
00081     {
00082       xfree (pi->unwind_info);
00083       pi->unwind_info = NULL;
00084       return -UNW_ENOINFO;
00085     }
00086 
00087   /* FIXME: Handle OSSD (OS Specific Data).  This extension to ia64 unwind
00088      information by OpenVMS is currently not handled by libunwind, but
00089      looks to be used only in very specific context, and is not generated by
00090      GCC.  */
00091 
00092   pi->lsda = table_addr + 8 + pi->unwind_info_size;
00093   if (extract_unsigned_integer (buf + 4, 2, byte_order) & 3)
00094     {
00095       pi->lsda += 8;
00096       /* There might be an handler, but this is not used for unwinding.  */
00097       pi->handler = 0;
00098     }
00099 
00100   return 0;
00101 }
00102 
00103 /* Libunwind callback accessor function for cleanup.  */
00104 
00105 static void
00106 ia64_vms_put_unwind_info (unw_addr_space_t as,
00107                           unw_proc_info_t *pip, void *arg)
00108 {
00109   /* Nothing required for now.  */
00110 }
00111 
00112 /* Libunwind callback accessor function to get head of the dynamic
00113    unwind-info registration list.  */
00114 
00115 static int
00116 ia64_vms_get_dyn_info_list (unw_addr_space_t as,
00117                             unw_word_t *dilap, void *arg)
00118 {
00119   return -UNW_ENOINFO;
00120 }
00121 
00122 /* Set of libunwind callback acccessor functions.  */
00123 static unw_accessors_t ia64_vms_unw_accessors;
00124 static unw_accessors_t ia64_vms_unw_rse_accessors;
00125 
00126 /* Set of ia64-libunwind-tdep gdb callbacks and data for generic
00127    ia64-libunwind-tdep code to use.  */
00128 static struct libunwind_descr ia64_vms_libunwind_descr;
00129 
00130 #endif /* HAVE_LIBUNWIND_IA64_H */
00131 
00132 static void
00133 ia64_openvms_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
00134 {
00135   set_gdbarch_long_double_format (gdbarch, floatformats_ia64_quad);
00136 
00137 #ifdef HAVE_LIBUNWIND_IA64_H
00138   /* Override the default descriptor.  */
00139   ia64_vms_unw_accessors = ia64_unw_accessors;
00140   ia64_vms_unw_accessors.find_proc_info = ia64_vms_find_proc_info_x;
00141   ia64_vms_unw_accessors.put_unwind_info = ia64_vms_put_unwind_info;
00142   ia64_vms_unw_accessors.get_dyn_info_list_addr = ia64_vms_get_dyn_info_list;
00143 
00144   ia64_vms_unw_rse_accessors = ia64_unw_rse_accessors;
00145   ia64_vms_unw_rse_accessors.find_proc_info = ia64_vms_find_proc_info_x;
00146   ia64_vms_unw_rse_accessors.put_unwind_info = ia64_vms_put_unwind_info;
00147   ia64_vms_unw_rse_accessors.get_dyn_info_list_addr = ia64_vms_get_dyn_info_list;
00148 
00149   ia64_vms_libunwind_descr = ia64_libunwind_descr;
00150   ia64_vms_libunwind_descr.accessors = &ia64_vms_unw_accessors;
00151   ia64_vms_libunwind_descr.special_accessors = &ia64_vms_unw_rse_accessors;
00152 
00153   libunwind_frame_set_descr (gdbarch, &ia64_vms_libunwind_descr);
00154 #endif
00155 }
00156 
00157 /* Provide a prototype to silence -Wmissing-prototypes.  */
00158 extern initialize_file_ftype _initialize_ia64_vms_tdep;
00159 
00160 void
00161 _initialize_ia64_vms_tdep (void)
00162 {
00163   gdbarch_register_osabi (bfd_arch_ia64, 0, GDB_OSABI_OPENVMS,
00164                           ia64_openvms_init_abi);
00165 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines