GDB (API)
|
00001 /* Target-dependent code for OpenBSD/vax. 00002 00003 Copyright (C) 2005-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 "arch-utils.h" 00022 #include "frame.h" 00023 #include "frame-unwind.h" 00024 #include "osabi.h" 00025 #include "symtab.h" 00026 #include "trad-frame.h" 00027 00028 #include "vax-tdep.h" 00029 00030 #include "gdb_string.h" 00031 00032 /* Signal trampolines. */ 00033 00034 /* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page 00035 in virtual memory. The randomness makes it somewhat tricky to 00036 detect it, but fortunately we can rely on the fact that the start 00037 of the sigtramp routine is page-aligned. We recognize the 00038 trampoline by looking for the code that invokes the sigreturn 00039 system call. The offset where we can find that code varies from 00040 release to release. 00041 00042 By the way, the mapping mentioned above is read-only, so you cannot 00043 place a breakpoint in the signal trampoline. */ 00044 00045 /* Default page size. */ 00046 static const int vaxobsd_page_size = 4096; 00047 00048 /* Offset for sigreturn(2). */ 00049 static const int vaxobsd_sigreturn_offset = 0x11; 00050 00051 /* Instruction sequence for sigreturn(2). VAX doesn't have 00052 fixed-length instructions so we include the ensuing exit(2) to 00053 reduce the chance of spurious matches. */ 00054 static const gdb_byte vaxobsd_sigreturn[] = { 00055 0xbc, 0x8f, 0x67, 0x00, /* chmk $SYS_sigreturn */ 00056 0xbc, 0x01 /* chmk $SYS_exit */ 00057 }; 00058 00059 static int 00060 vaxobsd_sigtramp_sniffer (const struct frame_unwind *self, 00061 struct frame_info *this_frame, 00062 void **this_cache) 00063 { 00064 CORE_ADDR pc = get_frame_pc (this_frame); 00065 CORE_ADDR start_pc = (pc & ~(vaxobsd_page_size - 1)); 00066 CORE_ADDR sigreturn_addr = start_pc + vaxobsd_sigreturn_offset; 00067 gdb_byte *buf; 00068 const char *name; 00069 00070 find_pc_partial_function (pc, &name, NULL, NULL); 00071 if (name) 00072 return 0; 00073 00074 buf = alloca(sizeof vaxobsd_sigreturn); 00075 if (!safe_frame_unwind_memory (this_frame, sigreturn_addr, 00076 buf, sizeof vaxobsd_sigreturn)) 00077 return 0; 00078 00079 if (memcmp(buf, vaxobsd_sigreturn, sizeof vaxobsd_sigreturn) == 0) 00080 return 1; 00081 00082 return 0; 00083 } 00084 00085 static struct trad_frame_cache * 00086 vaxobsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache) 00087 { 00088 struct trad_frame_cache *cache; 00089 CORE_ADDR addr, base, func; 00090 00091 if (*this_cache) 00092 return *this_cache; 00093 00094 cache = trad_frame_cache_zalloc (this_frame); 00095 *this_cache = cache; 00096 00097 func = get_frame_pc (this_frame); 00098 func &= ~(vaxobsd_page_size - 1); 00099 00100 base = get_frame_register_unsigned (this_frame, VAX_SP_REGNUM); 00101 addr = get_frame_memory_unsigned (this_frame, base - 4, 4); 00102 00103 trad_frame_set_reg_addr (cache, VAX_SP_REGNUM, addr + 8); 00104 trad_frame_set_reg_addr (cache, VAX_FP_REGNUM, addr + 12); 00105 trad_frame_set_reg_addr (cache, VAX_AP_REGNUM, addr + 16); 00106 trad_frame_set_reg_addr (cache, VAX_PC_REGNUM, addr + 20); 00107 trad_frame_set_reg_addr (cache, VAX_PS_REGNUM, addr + 24); 00108 00109 /* Construct the frame ID using the function start. */ 00110 trad_frame_set_id (cache, frame_id_build (base, func)); 00111 00112 return cache; 00113 } 00114 00115 static void 00116 vaxobsd_sigtramp_frame_this_id (struct frame_info *this_frame, 00117 void **this_cache, struct frame_id *this_id) 00118 { 00119 struct trad_frame_cache *cache = 00120 vaxobsd_sigtramp_frame_cache (this_frame, this_cache); 00121 00122 trad_frame_get_id (cache, this_id); 00123 } 00124 00125 static struct value * 00126 vaxobsd_sigtramp_frame_prev_register (struct frame_info *this_frame, 00127 void **this_cache, int regnum) 00128 { 00129 struct trad_frame_cache *cache = 00130 vaxobsd_sigtramp_frame_cache (this_frame, this_cache); 00131 00132 return trad_frame_get_register (cache, this_frame, regnum); 00133 } 00134 00135 static const struct frame_unwind vaxobsd_sigtramp_frame_unwind = { 00136 SIGTRAMP_FRAME, 00137 default_frame_unwind_stop_reason, 00138 vaxobsd_sigtramp_frame_this_id, 00139 vaxobsd_sigtramp_frame_prev_register, 00140 NULL, 00141 vaxobsd_sigtramp_sniffer 00142 }; 00143 00144 00145 /* OpenBSD a.out. */ 00146 00147 static void 00148 vaxobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 00149 { 00150 frame_unwind_append_unwinder (gdbarch, &vaxobsd_sigtramp_frame_unwind); 00151 } 00152 00153 /* FIXME: kettenis/20050821: Since OpenBSD/vax binaries are 00154 indistingushable from NetBSD/vax a.out binaries, building a GDB 00155 that should support both these targets will probably not work as 00156 expected. */ 00157 #define GDB_OSABI_OPENBSD_AOUT GDB_OSABI_NETBSD_AOUT 00158 00159 static enum gdb_osabi 00160 vaxobsd_aout_osabi_sniffer (bfd *abfd) 00161 { 00162 if (strcmp (bfd_get_target (abfd), "a.out-vax-netbsd") == 0) 00163 return GDB_OSABI_OPENBSD_AOUT; 00164 00165 return GDB_OSABI_UNKNOWN; 00166 } 00167 00168 00169 /* Provide a prototype to silence -Wmissing-prototypes. */ 00170 void _initialize_vaxobsd_tdep (void); 00171 00172 void 00173 _initialize_vaxobsd_tdep (void) 00174 { 00175 gdbarch_register_osabi_sniffer (bfd_arch_vax, bfd_target_aout_flavour, 00176 vaxobsd_aout_osabi_sniffer); 00177 00178 gdbarch_register_osabi (bfd_arch_vax, 0, GDB_OSABI_OPENBSD_AOUT, 00179 vaxobsd_init_abi); 00180 }