GDB (API)
|
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 (¤t_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 }