GDB (API)
/home/stan/gdb/src/gdb/alphaobsd-tdep.c
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines