1699b0f92Schristos /* Target-dependent code for OpenBSD/arm. 2699b0f92Schristos 3*6881a400Schristos Copyright (C) 2006-2023 Free Software Foundation, Inc. 4699b0f92Schristos 5699b0f92Schristos This file is part of GDB. 6699b0f92Schristos 7699b0f92Schristos This program is free software; you can redistribute it and/or modify 8699b0f92Schristos it under the terms of the GNU General Public License as published by 9699b0f92Schristos the Free Software Foundation; either version 3 of the License, or 10699b0f92Schristos (at your option) any later version. 11699b0f92Schristos 12699b0f92Schristos This program is distributed in the hope that it will be useful, 13699b0f92Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 14699b0f92Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15699b0f92Schristos GNU General Public License for more details. 16699b0f92Schristos 17699b0f92Schristos You should have received a copy of the GNU General Public License 18699b0f92Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19699b0f92Schristos 20699b0f92Schristos #include "defs.h" 21699b0f92Schristos #include "osabi.h" 22699b0f92Schristos #include "trad-frame.h" 23699b0f92Schristos #include "tramp-frame.h" 24699b0f92Schristos 25699b0f92Schristos #include "obsd-tdep.h" 26699b0f92Schristos #include "arm-tdep.h" 27699b0f92Schristos #include "solib-svr4.h" 28699b0f92Schristos 29699b0f92Schristos /* Signal trampolines. */ 30699b0f92Schristos 31699b0f92Schristos static void 32699b0f92Schristos armobsd_sigframe_init (const struct tramp_frame *self, 33*6881a400Schristos frame_info_ptr this_frame, 34699b0f92Schristos struct trad_frame_cache *cache, 35699b0f92Schristos CORE_ADDR func) 36699b0f92Schristos { 37699b0f92Schristos CORE_ADDR sp, sigcontext_addr, addr; 38699b0f92Schristos int regnum; 39699b0f92Schristos 40699b0f92Schristos /* We find the appropriate instance of `struct sigcontext' at a 41699b0f92Schristos fixed offset in the signal frame. */ 42699b0f92Schristos sp = get_frame_register_signed (this_frame, ARM_SP_REGNUM); 43699b0f92Schristos sigcontext_addr = sp + 16; 44699b0f92Schristos 45699b0f92Schristos /* PC. */ 46699b0f92Schristos trad_frame_set_reg_addr (cache, ARM_PC_REGNUM, sigcontext_addr + 76); 47699b0f92Schristos 48699b0f92Schristos /* GPRs. */ 49699b0f92Schristos for (regnum = ARM_A1_REGNUM, addr = sigcontext_addr + 12; 50699b0f92Schristos regnum <= ARM_LR_REGNUM; regnum++, addr += 4) 51699b0f92Schristos trad_frame_set_reg_addr (cache, regnum, addr); 52699b0f92Schristos 53699b0f92Schristos trad_frame_set_id (cache, frame_id_build (sp, func)); 54699b0f92Schristos } 55699b0f92Schristos 56699b0f92Schristos static const struct tramp_frame armobsd_sigframe = 57699b0f92Schristos { 58699b0f92Schristos SIGTRAMP_FRAME, 59699b0f92Schristos 4, 60699b0f92Schristos { 617f2ac410Schristos { 0xe28d0010, ULONGEST_MAX }, /* add r0, sp, #16 */ 627f2ac410Schristos { 0xef000067, ULONGEST_MAX }, /* swi SYS_sigreturn */ 637f2ac410Schristos { 0xef000001, ULONGEST_MAX }, /* swi SYS_exit */ 647f2ac410Schristos { 0xeafffffc, ULONGEST_MAX }, /* b . - 8 */ 657f2ac410Schristos { TRAMP_SENTINEL_INSN, ULONGEST_MAX } 66699b0f92Schristos }, 67699b0f92Schristos armobsd_sigframe_init 68699b0f92Schristos }; 69699b0f92Schristos 70699b0f92Schristos 71699b0f92Schristos /* Override default thumb breakpoints. */ 72699b0f92Schristos static const gdb_byte arm_obsd_thumb_le_breakpoint[] = {0xfe, 0xdf}; 73699b0f92Schristos static const gdb_byte arm_obsd_thumb_be_breakpoint[] = {0xdf, 0xfe}; 74699b0f92Schristos 75699b0f92Schristos static void 76699b0f92Schristos armobsd_init_abi (struct gdbarch_info info, 77699b0f92Schristos struct gdbarch *gdbarch) 78699b0f92Schristos { 79*6881a400Schristos arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch); 80699b0f92Schristos 81699b0f92Schristos if (tdep->fp_model == ARM_FLOAT_AUTO) 82699b0f92Schristos tdep->fp_model = ARM_FLOAT_SOFT_VFP; 83699b0f92Schristos 84699b0f92Schristos tramp_frame_prepend_unwinder (gdbarch, &armobsd_sigframe); 85699b0f92Schristos 86699b0f92Schristos /* OpenBSD/arm uses SVR4-style shared libraries. */ 87699b0f92Schristos set_solib_svr4_fetch_link_map_offsets 88699b0f92Schristos (gdbarch, svr4_ilp32_fetch_link_map_offsets); 89699b0f92Schristos set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver); 90699b0f92Schristos 91699b0f92Schristos tdep->jb_pc = 24; 92699b0f92Schristos tdep->jb_elt_size = 4; 93699b0f92Schristos 94699b0f92Schristos set_gdbarch_iterate_over_regset_sections 95699b0f92Schristos (gdbarch, armbsd_iterate_over_regset_sections); 96699b0f92Schristos 97699b0f92Schristos /* OpenBSD/arm uses -fpcc-struct-return by default. */ 98699b0f92Schristos tdep->struct_return = pcc_struct_return; 99699b0f92Schristos 100699b0f92Schristos /* Single stepping. */ 101699b0f92Schristos set_gdbarch_software_single_step (gdbarch, arm_software_single_step); 102699b0f92Schristos 103699b0f92Schristos /* Breakpoints. */ 104699b0f92Schristos switch (info.byte_order) 105699b0f92Schristos { 106699b0f92Schristos case BFD_ENDIAN_BIG: 107699b0f92Schristos tdep->thumb_breakpoint = arm_obsd_thumb_be_breakpoint; 108699b0f92Schristos tdep->thumb_breakpoint_size = sizeof (arm_obsd_thumb_be_breakpoint); 109699b0f92Schristos break; 110699b0f92Schristos 111699b0f92Schristos case BFD_ENDIAN_LITTLE: 112699b0f92Schristos tdep->thumb_breakpoint = arm_obsd_thumb_le_breakpoint; 113699b0f92Schristos tdep->thumb_breakpoint_size = sizeof (arm_obsd_thumb_le_breakpoint); 114699b0f92Schristos break; 115699b0f92Schristos } 116699b0f92Schristos } 117699b0f92Schristos 1187d62b00eSchristos void _initialize_armobsd_tdep (); 119699b0f92Schristos void 1207d62b00eSchristos _initialize_armobsd_tdep () 121699b0f92Schristos { 122699b0f92Schristos gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_OPENBSD, 123699b0f92Schristos armobsd_init_abi); 124699b0f92Schristos } 125