1 /* Target-dependent code for OpenBSD/arm. 2 3 Copyright (C) 2006-2019 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include "defs.h" 21 #include "osabi.h" 22 #include "trad-frame.h" 23 #include "tramp-frame.h" 24 25 #include "obsd-tdep.h" 26 #include "arm-tdep.h" 27 #include "solib-svr4.h" 28 29 /* Signal trampolines. */ 30 31 static void 32 armobsd_sigframe_init (const struct tramp_frame *self, 33 struct frame_info *this_frame, 34 struct trad_frame_cache *cache, 35 CORE_ADDR func) 36 { 37 CORE_ADDR sp, sigcontext_addr, addr; 38 int regnum; 39 40 /* We find the appropriate instance of `struct sigcontext' at a 41 fixed offset in the signal frame. */ 42 sp = get_frame_register_signed (this_frame, ARM_SP_REGNUM); 43 sigcontext_addr = sp + 16; 44 45 /* PC. */ 46 trad_frame_set_reg_addr (cache, ARM_PC_REGNUM, sigcontext_addr + 76); 47 48 /* GPRs. */ 49 for (regnum = ARM_A1_REGNUM, addr = sigcontext_addr + 12; 50 regnum <= ARM_LR_REGNUM; regnum++, addr += 4) 51 trad_frame_set_reg_addr (cache, regnum, addr); 52 53 trad_frame_set_id (cache, frame_id_build (sp, func)); 54 } 55 56 static const struct tramp_frame armobsd_sigframe = 57 { 58 SIGTRAMP_FRAME, 59 4, 60 { 61 { 0xe28d0010, ULONGEST_MAX }, /* add r0, sp, #16 */ 62 { 0xef000067, ULONGEST_MAX }, /* swi SYS_sigreturn */ 63 { 0xef000001, ULONGEST_MAX }, /* swi SYS_exit */ 64 { 0xeafffffc, ULONGEST_MAX }, /* b . - 8 */ 65 { TRAMP_SENTINEL_INSN, ULONGEST_MAX } 66 }, 67 armobsd_sigframe_init 68 }; 69 70 71 /* Override default thumb breakpoints. */ 72 static const gdb_byte arm_obsd_thumb_le_breakpoint[] = {0xfe, 0xdf}; 73 static const gdb_byte arm_obsd_thumb_be_breakpoint[] = {0xdf, 0xfe}; 74 75 static void 76 armobsd_init_abi (struct gdbarch_info info, 77 struct gdbarch *gdbarch) 78 { 79 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 80 81 if (tdep->fp_model == ARM_FLOAT_AUTO) 82 tdep->fp_model = ARM_FLOAT_SOFT_VFP; 83 84 tramp_frame_prepend_unwinder (gdbarch, &armobsd_sigframe); 85 86 /* OpenBSD/arm uses SVR4-style shared libraries. */ 87 set_solib_svr4_fetch_link_map_offsets 88 (gdbarch, svr4_ilp32_fetch_link_map_offsets); 89 set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver); 90 91 tdep->jb_pc = 24; 92 tdep->jb_elt_size = 4; 93 94 set_gdbarch_iterate_over_regset_sections 95 (gdbarch, armbsd_iterate_over_regset_sections); 96 97 /* OpenBSD/arm uses -fpcc-struct-return by default. */ 98 tdep->struct_return = pcc_struct_return; 99 100 /* Single stepping. */ 101 set_gdbarch_software_single_step (gdbarch, arm_software_single_step); 102 103 /* Breakpoints. */ 104 switch (info.byte_order) 105 { 106 case BFD_ENDIAN_BIG: 107 tdep->thumb_breakpoint = arm_obsd_thumb_be_breakpoint; 108 tdep->thumb_breakpoint_size = sizeof (arm_obsd_thumb_be_breakpoint); 109 break; 110 111 case BFD_ENDIAN_LITTLE: 112 tdep->thumb_breakpoint = arm_obsd_thumb_le_breakpoint; 113 tdep->thumb_breakpoint_size = sizeof (arm_obsd_thumb_le_breakpoint); 114 break; 115 } 116 } 117 118 void 119 _initialize_armobsd_tdep (void) 120 { 121 gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_OPENBSD, 122 armobsd_init_abi); 123 } 124