GDB (API)
/home/stan/gdb/src/gdb/armobsd-tdep.c
Go to the documentation of this file.
00001 /* Target-dependent code for OpenBSD/arm.
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 "osabi.h"
00022 #include "trad-frame.h"
00023 #include "tramp-frame.h"
00024 
00025 #include "gdb_string.h"
00026 
00027 #include "obsd-tdep.h"
00028 #include "arm-tdep.h"
00029 #include "solib-svr4.h"
00030 
00031 /* Signal trampolines.  */
00032 
00033 static void
00034 armobsd_sigframe_init (const struct tramp_frame *self,
00035                        struct frame_info *this_frame,
00036                        struct trad_frame_cache *cache,
00037                        CORE_ADDR func)
00038 {
00039   CORE_ADDR sp, sigcontext_addr, addr;
00040   int regnum;
00041 
00042   /* We find the appropriate instance of `struct sigcontext' at a
00043      fixed offset in the signal frame.  */
00044   sp = get_frame_register_signed (this_frame, ARM_SP_REGNUM);
00045   sigcontext_addr = sp + 16;
00046 
00047   /* PC.  */
00048   trad_frame_set_reg_addr (cache, ARM_PC_REGNUM, sigcontext_addr + 76);
00049 
00050   /* GPRs.  */
00051   for (regnum = ARM_A1_REGNUM, addr = sigcontext_addr + 12;
00052        regnum <= ARM_LR_REGNUM; regnum++, addr += 4)
00053     trad_frame_set_reg_addr (cache, regnum, addr);
00054 
00055   trad_frame_set_id (cache, frame_id_build (sp, func));
00056 }
00057 
00058 static const struct tramp_frame armobsd_sigframe =
00059 {
00060   SIGTRAMP_FRAME,
00061   4,
00062   {
00063     { 0xe28d0010, -1 },         /* add     r0, sp, #16 */
00064     { 0xef000067, -1 },         /* swi     SYS_sigreturn */
00065     { 0xef000001, -1 },         /* swi     SYS_exit */
00066     { 0xeafffffc, -1 },         /* b       . - 8 */
00067     { TRAMP_SENTINEL_INSN, -1 }
00068   },
00069   armobsd_sigframe_init
00070 };
00071 
00072 
00073 /* Override default thumb breakpoints.  */
00074 static const gdb_byte arm_obsd_thumb_le_breakpoint[] = {0xfe, 0xdf};
00075 static const gdb_byte arm_obsd_thumb_be_breakpoint[] = {0xdf, 0xfe};
00076 
00077 static void
00078 armobsd_init_abi (struct gdbarch_info info,
00079                   struct gdbarch *gdbarch)
00080 {
00081   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
00082 
00083   if (tdep->fp_model == ARM_FLOAT_AUTO)
00084     tdep->fp_model = ARM_FLOAT_SOFT_VFP;
00085 
00086   tramp_frame_prepend_unwinder (gdbarch, &armobsd_sigframe);
00087 
00088   /* OpenBSD/arm uses SVR4-style shared libraries.  */
00089   set_solib_svr4_fetch_link_map_offsets
00090     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
00091   set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
00092 
00093   tdep->jb_pc = 24;
00094   tdep->jb_elt_size = 4;
00095 
00096   set_gdbarch_regset_from_core_section
00097     (gdbarch, armbsd_regset_from_core_section);
00098 
00099   /* OpenBSD/arm uses -fpcc-struct-return by default.  */
00100   tdep->struct_return = pcc_struct_return;
00101 
00102   /* Single stepping.  */
00103   set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
00104 
00105   /* Breakpoints.  */
00106   switch (info.byte_order)
00107     {
00108     case BFD_ENDIAN_BIG:
00109       tdep->thumb_breakpoint = arm_obsd_thumb_be_breakpoint;
00110       tdep->thumb_breakpoint_size = sizeof (arm_obsd_thumb_be_breakpoint);
00111       break;
00112 
00113     case BFD_ENDIAN_LITTLE:
00114       tdep->thumb_breakpoint = arm_obsd_thumb_le_breakpoint;
00115       tdep->thumb_breakpoint_size = sizeof (arm_obsd_thumb_le_breakpoint);
00116       break;
00117     }
00118 }
00119 
00120 
00121 static enum gdb_osabi
00122 armobsd_core_osabi_sniffer (bfd *abfd)
00123 {
00124   if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
00125     return GDB_OSABI_OPENBSD_ELF;
00126 
00127   return GDB_OSABI_UNKNOWN;
00128 }
00129 
00130 /* Provide a prototype to silence -Wmissing-prototypes.  */
00131 extern initialize_file_ftype _initialize_armobsd_tdep;
00132 
00133 void
00134 _initialize_armobsd_tdep (void)
00135 {
00136   /* BFD doesn't set a flavour for NetBSD style a.out core files.  */
00137   gdbarch_register_osabi_sniffer (bfd_arch_arm, bfd_target_unknown_flavour,
00138                                   armobsd_core_osabi_sniffer);
00139 
00140   gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_OPENBSD_ELF,
00141                           armobsd_init_abi);
00142 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines