GDB (API)
|
00001 /* Target-dependent code for OpenBSD/alpha. 00002 00003 Copyright (C) 2006-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.h" 00022 #include "gdbcore.h" 00023 #include "osabi.h" 00024 00025 #include "obsd-tdep.h" 00026 #include "alpha-tdep.h" 00027 #include "alphabsd-tdep.h" 00028 #include "solib-svr4.h" 00029 00030 /* Signal trampolines. */ 00031 00032 /* The OpenBSD kernel maps the signal trampoline at some random 00033 location in user space, which means that the traditional BSD way of 00034 detecting it won't work. 00035 00036 The signal trampoline will be mapped at an address that is page 00037 aligned. We recognize the signal trampoline by looking for the 00038 sigreturn system call. */ 00039 00040 static const int alphaobsd_page_size = 8192; 00041 00042 static LONGEST 00043 alphaobsd_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc) 00044 { 00045 return (pc & (alphaobsd_page_size - 1)); 00046 } 00047 00048 static int 00049 alphaobsd_pc_in_sigtramp (struct gdbarch *gdbarch, 00050 CORE_ADDR pc, const char *name) 00051 { 00052 CORE_ADDR start_pc = (pc & ~(alphaobsd_page_size - 1)); 00053 unsigned insn; 00054 00055 if (name) 00056 return 0; 00057 00058 /* Check for "". */ 00059 insn = alpha_read_insn (gdbarch, start_pc + 5 * ALPHA_INSN_SIZE); 00060 if (insn != 0x201f0067) 00061 return 0; 00062 00063 /* Check for "". */ 00064 insn = alpha_read_insn (gdbarch, start_pc + 6 * ALPHA_INSN_SIZE); 00065 if (insn != 0x00000083) 00066 return 0; 00067 00068 return 1; 00069 } 00070 00071 static CORE_ADDR 00072 alphaobsd_sigcontext_addr (struct frame_info *this_frame) 00073 { 00074 struct gdbarch *gdbarch = get_frame_arch (this_frame); 00075 CORE_ADDR pc = get_frame_pc (this_frame); 00076 00077 if (alphaobsd_sigtramp_offset (gdbarch, pc) < 3 * ALPHA_INSN_SIZE) 00078 { 00079 /* On entry, a pointer the `struct sigcontext' is passed in %a2. */ 00080 return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM + 2); 00081 } 00082 else if (alphaobsd_sigtramp_offset (gdbarch, pc) < 4 * ALPHA_INSN_SIZE) 00083 { 00084 /* It is stored on the stack Before calling the signal handler. */ 00085 CORE_ADDR sp; 00086 sp = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM); 00087 return get_frame_memory_unsigned (this_frame, sp, 8); 00088 } 00089 else 00090 { 00091 /* It is reloaded into %a0 for the sigreturn(2) call. */ 00092 return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM); 00093 } 00094 } 00095 00096 00097 static void 00098 alphaobsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) 00099 { 00100 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 00101 00102 /* Hook into the DWARF CFI frame unwinder. */ 00103 alpha_dwarf2_init_abi (info, gdbarch); 00104 00105 /* Hook into the MDEBUG frame unwinder. */ 00106 alpha_mdebug_init_abi (info, gdbarch); 00107 00108 /* OpenBSD/alpha 3.0 and earlier does not provide single step 00109 support via ptrace(2); use software single-stepping for now. */ 00110 set_gdbarch_software_single_step (gdbarch, alpha_software_single_step); 00111 00112 /* OpenBSD/alpha has SVR4-style shared libraries. */ 00113 set_solib_svr4_fetch_link_map_offsets 00114 (gdbarch, svr4_lp64_fetch_link_map_offsets); 00115 set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver); 00116 00117 tdep->dynamic_sigtramp_offset = alphaobsd_sigtramp_offset; 00118 tdep->pc_in_sigtramp = alphaobsd_pc_in_sigtramp; 00119 tdep->sigcontext_addr = alphaobsd_sigcontext_addr; 00120 00121 tdep->jb_pc = 2; 00122 tdep->jb_elt_size = 8; 00123 00124 set_gdbarch_regset_from_core_section 00125 (gdbarch, alphanbsd_regset_from_core_section); 00126 } 00127 00128 00129 /* Provide a prototype to silence -Wmissing-prototypes. */ 00130 void _initialize_alphaobsd_tdep (void); 00131 00132 void 00133 _initialize_alphaobsd_tdep (void) 00134 { 00135 gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_OPENBSD_ELF, 00136 alphaobsd_init_abi); 00137 }