Home | History | Annotate | Line # | Download | only in gdb
alpha-obsd-tdep.c revision 1.1
      1  1.1  christos /* Target-dependent code for OpenBSD/alpha.
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 2006-2017 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    This file is part of GDB.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify
      8  1.1  christos    it under the terms of the GNU General Public License as published by
      9  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10  1.1  christos    (at your option) any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  christos    GNU General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19  1.1  christos 
     20  1.1  christos #include "defs.h"
     21  1.1  christos #include "frame.h"
     22  1.1  christos #include "gdbcore.h"
     23  1.1  christos #include "osabi.h"
     24  1.1  christos 
     25  1.1  christos #include "obsd-tdep.h"
     26  1.1  christos #include "alpha-tdep.h"
     27  1.1  christos #include "alpha-bsd-tdep.h"
     28  1.1  christos #include "solib-svr4.h"
     29  1.1  christos 
     30  1.1  christos /* Signal trampolines.  */
     31  1.1  christos 
     32  1.1  christos /* The OpenBSD kernel maps the signal trampoline at some random
     33  1.1  christos    location in user space, which means that the traditional BSD way of
     34  1.1  christos    detecting it won't work.
     35  1.1  christos 
     36  1.1  christos    The signal trampoline will be mapped at an address that is page
     37  1.1  christos    aligned.  We recognize the signal trampoline by looking for the
     38  1.1  christos    sigreturn system call.  */
     39  1.1  christos 
     40  1.1  christos static const int alphaobsd_page_size = 8192;
     41  1.1  christos 
     42  1.1  christos static LONGEST
     43  1.1  christos alphaobsd_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
     44  1.1  christos {
     45  1.1  christos   return (pc & (alphaobsd_page_size - 1));
     46  1.1  christos }
     47  1.1  christos 
     48  1.1  christos static int
     49  1.1  christos alphaobsd_pc_in_sigtramp (struct gdbarch *gdbarch,
     50  1.1  christos 			  CORE_ADDR pc, const char *name)
     51  1.1  christos {
     52  1.1  christos   CORE_ADDR start_pc = (pc & ~(alphaobsd_page_size - 1));
     53  1.1  christos   unsigned insn;
     54  1.1  christos 
     55  1.1  christos   if (name)
     56  1.1  christos     return 0;
     57  1.1  christos 
     58  1.1  christos   /* Check for "".  */
     59  1.1  christos   insn = alpha_read_insn (gdbarch, start_pc + 5 * ALPHA_INSN_SIZE);
     60  1.1  christos   if (insn != 0x201f0067)
     61  1.1  christos     return 0;
     62  1.1  christos 
     63  1.1  christos   /* Check for "".  */
     64  1.1  christos   insn = alpha_read_insn (gdbarch, start_pc + 6 * ALPHA_INSN_SIZE);
     65  1.1  christos   if (insn != 0x00000083)
     66  1.1  christos     return 0;
     67  1.1  christos 
     68  1.1  christos   return 1;
     69  1.1  christos }
     70  1.1  christos 
     71  1.1  christos static CORE_ADDR
     72  1.1  christos alphaobsd_sigcontext_addr (struct frame_info *this_frame)
     73  1.1  christos {
     74  1.1  christos   struct gdbarch *gdbarch = get_frame_arch (this_frame);
     75  1.1  christos   CORE_ADDR pc = get_frame_pc (this_frame);
     76  1.1  christos 
     77  1.1  christos   if (alphaobsd_sigtramp_offset (gdbarch, pc) < 3 * ALPHA_INSN_SIZE)
     78  1.1  christos     {
     79  1.1  christos       /* On entry, a pointer the `struct sigcontext' is passed in %a2.  */
     80  1.1  christos       return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM + 2);
     81  1.1  christos     }
     82  1.1  christos   else if (alphaobsd_sigtramp_offset (gdbarch, pc) < 4 * ALPHA_INSN_SIZE)
     83  1.1  christos     {
     84  1.1  christos       /* It is stored on the stack Before calling the signal handler.  */
     85  1.1  christos       CORE_ADDR sp;
     86  1.1  christos       sp = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM);
     87  1.1  christos       return get_frame_memory_unsigned (this_frame, sp, 8);
     88  1.1  christos     }
     89  1.1  christos   else
     90  1.1  christos     {
     91  1.1  christos       /* It is reloaded into %a0 for the sigreturn(2) call.  */
     92  1.1  christos       return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM);
     93  1.1  christos     }
     94  1.1  christos }
     95  1.1  christos 
     96  1.1  christos 
     98  1.1  christos static void
     99  1.1  christos alphaobsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
    100  1.1  christos {
    101  1.1  christos   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
    102  1.1  christos 
    103  1.1  christos   /* Hook into the DWARF CFI frame unwinder.  */
    104  1.1  christos   alpha_dwarf2_init_abi (info, gdbarch);
    105  1.1  christos 
    106  1.1  christos   /* Hook into the MDEBUG frame unwinder.  */
    107  1.1  christos   alpha_mdebug_init_abi (info, gdbarch);
    108  1.1  christos 
    109  1.1  christos   /* OpenBSD/alpha 3.0 and earlier does not provide single step
    110  1.1  christos      support via ptrace(2); use software single-stepping for now.  */
    111  1.1  christos   set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
    112  1.1  christos 
    113  1.1  christos   /* OpenBSD/alpha has SVR4-style shared libraries.  */
    114  1.1  christos   set_solib_svr4_fetch_link_map_offsets
    115  1.1  christos     (gdbarch, svr4_lp64_fetch_link_map_offsets);
    116  1.1  christos   set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
    117  1.1  christos 
    118  1.1  christos   tdep->dynamic_sigtramp_offset = alphaobsd_sigtramp_offset;
    119  1.1  christos   tdep->pc_in_sigtramp = alphaobsd_pc_in_sigtramp;
    120  1.1  christos   tdep->sigcontext_addr = alphaobsd_sigcontext_addr;
    121  1.1  christos 
    122  1.1  christos   tdep->jb_pc = 2;
    123  1.1  christos   tdep->jb_elt_size = 8;
    124  1.1  christos 
    125  1.1  christos   set_gdbarch_iterate_over_regset_sections
    126  1.1  christos     (gdbarch, alphanbsd_iterate_over_regset_sections);
    127  1.1  christos }
    128  1.1  christos 
    129  1.1  christos 
    131  1.1  christos /* Provide a prototype to silence -Wmissing-prototypes.  */
    132  1.1  christos void _initialize_alphaobsd_tdep (void);
    133  1.1  christos 
    134  1.1  christos void
    135  1.1  christos _initialize_alphaobsd_tdep (void)
    136  1.1  christos {
    137  1.1  christos   gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_OPENBSD,
    138                                          alphaobsd_init_abi);
    139                }
    140