1130803Smarcel/* Target-dependent code for OpenBSD/sparc. 2130803Smarcel 3130803Smarcel Copyright 2004 Free Software Foundation, Inc. 4130803Smarcel 5130803Smarcel This file is part of GDB. 6130803Smarcel 7130803Smarcel This program is free software; you can redistribute it and/or modify 8130803Smarcel it under the terms of the GNU General Public License as published by 9130803Smarcel the Free Software Foundation; either version 2 of the License, or 10130803Smarcel (at your option) any later version. 11130803Smarcel 12130803Smarcel This program is distributed in the hope that it will be useful, 13130803Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 14130803Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15130803Smarcel GNU General Public License for more details. 16130803Smarcel 17130803Smarcel You should have received a copy of the GNU General Public License 18130803Smarcel along with this program; if not, write to the Free Software 19130803Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 20130803Smarcel Boston, MA 02111-1307, USA. */ 21130803Smarcel 22130803Smarcel#include "defs.h" 23130803Smarcel#include "floatformat.h" 24130803Smarcel#include "frame.h" 25130803Smarcel#include "frame-unwind.h" 26130803Smarcel#include "osabi.h" 27130803Smarcel#include "solib-svr4.h" 28130803Smarcel#include "symtab.h" 29130803Smarcel#include "trad-frame.h" 30130803Smarcel 31130803Smarcel#include "gdb_assert.h" 32130803Smarcel 33130803Smarcel#include "sparc-tdep.h" 34130803Smarcel#include "nbsd-tdep.h" 35130803Smarcel 36130803Smarcel/* Signal trampolines. */ 37130803Smarcel 38130803Smarcel/* The OpenBSD kernel maps the signal trampoline at some random 39130803Smarcel location in user space, which means that the traditional BSD way of 40130803Smarcel detecting it won't work. 41130803Smarcel 42130803Smarcel The signal trampoline will be mapped at an address that is page 43130803Smarcel aligned. We recognize the signal trampoline by the looking for the 44130803Smarcel sigreturn system call. */ 45130803Smarcel 46130803Smarcelstatic const int sparc32obsd_page_size = 4096; 47130803Smarcel 48130803Smarcelstatic int 49130803Smarcelsparc32obsd_pc_in_sigtramp (CORE_ADDR pc, char *name) 50130803Smarcel{ 51130803Smarcel CORE_ADDR start_pc = (pc & ~(sparc32obsd_page_size - 1)); 52130803Smarcel unsigned long insn; 53130803Smarcel 54130803Smarcel if (name) 55130803Smarcel return 0; 56130803Smarcel 57130803Smarcel /* Check for "restore %g0, SYS_sigreturn, %g1". */ 58130803Smarcel insn = sparc_fetch_instruction (start_pc + 0xec); 59130803Smarcel if (insn != 0x83e82067) 60130803Smarcel return 0; 61130803Smarcel 62130803Smarcel /* Check for "t ST_SYSCALL". */ 63130803Smarcel insn = sparc_fetch_instruction (start_pc + 0xf4); 64130803Smarcel if (insn != 0x91d02000) 65130803Smarcel return 0; 66130803Smarcel 67130803Smarcel return 1; 68130803Smarcel} 69130803Smarcel 70130803Smarcelstatic struct sparc_frame_cache * 71130803Smarcelsparc32obsd_frame_cache (struct frame_info *next_frame, void **this_cache) 72130803Smarcel{ 73130803Smarcel struct sparc_frame_cache *cache; 74130803Smarcel CORE_ADDR addr; 75130803Smarcel 76130803Smarcel if (*this_cache) 77130803Smarcel return *this_cache; 78130803Smarcel 79130803Smarcel cache = sparc_frame_cache (next_frame, this_cache); 80130803Smarcel gdb_assert (cache == *this_cache); 81130803Smarcel 82130803Smarcel /* If we couldn't find the frame's function, we're probably dealing 83130803Smarcel with an on-stack signal trampoline. */ 84130803Smarcel if (cache->pc == 0) 85130803Smarcel { 86130803Smarcel cache->pc = frame_pc_unwind (next_frame); 87130803Smarcel cache->pc &= ~(sparc32obsd_page_size - 1); 88130803Smarcel 89130803Smarcel /* Since we couldn't find the frame's function, the cache was 90130803Smarcel initialized under the assumption that we're frameless. */ 91130803Smarcel cache->frameless_p = 0; 92130803Smarcel addr = frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM); 93130803Smarcel cache->base = addr; 94130803Smarcel } 95130803Smarcel 96130803Smarcel cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (next_frame); 97130803Smarcel 98130803Smarcel return cache; 99130803Smarcel} 100130803Smarcel 101130803Smarcelstatic void 102130803Smarcelsparc32obsd_frame_this_id (struct frame_info *next_frame, void **this_cache, 103130803Smarcel struct frame_id *this_id) 104130803Smarcel{ 105130803Smarcel struct sparc_frame_cache *cache = 106130803Smarcel sparc32obsd_frame_cache (next_frame, this_cache); 107130803Smarcel 108130803Smarcel (*this_id) = frame_id_build (cache->base, cache->pc); 109130803Smarcel} 110130803Smarcel 111130803Smarcelstatic void 112130803Smarcelsparc32obsd_frame_prev_register (struct frame_info *next_frame, 113130803Smarcel void **this_cache, 114130803Smarcel int regnum, int *optimizedp, 115130803Smarcel enum lval_type *lvalp, CORE_ADDR *addrp, 116130803Smarcel int *realnump, void *valuep) 117130803Smarcel{ 118130803Smarcel struct sparc_frame_cache *cache = 119130803Smarcel sparc32obsd_frame_cache (next_frame, this_cache); 120130803Smarcel 121130803Smarcel trad_frame_prev_register (next_frame, cache->saved_regs, regnum, 122130803Smarcel optimizedp, lvalp, addrp, realnump, valuep); 123130803Smarcel} 124130803Smarcel 125130803Smarcelstatic const struct frame_unwind sparc32obsd_frame_unwind = 126130803Smarcel{ 127130803Smarcel SIGTRAMP_FRAME, 128130803Smarcel sparc32obsd_frame_this_id, 129130803Smarcel sparc32obsd_frame_prev_register 130130803Smarcel}; 131130803Smarcel 132130803Smarcelstatic const struct frame_unwind * 133130803Smarcelsparc32obsd_sigtramp_frame_sniffer (struct frame_info *next_frame) 134130803Smarcel{ 135130803Smarcel CORE_ADDR pc = frame_pc_unwind (next_frame); 136130803Smarcel char *name; 137130803Smarcel 138130803Smarcel find_pc_partial_function (pc, &name, NULL, NULL); 139130803Smarcel if (sparc32obsd_pc_in_sigtramp (pc, name)) 140130803Smarcel return &sparc32obsd_frame_unwind; 141130803Smarcel 142130803Smarcel return NULL; 143130803Smarcel} 144130803Smarcel 145130803Smarcel 146130803Smarcelstatic void 147130803Smarcelsparc32obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 148130803Smarcel{ 149130803Smarcel struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 150130803Smarcel 151130803Smarcel /* OpenBSD doesn't support the 128-bit `long double' from the psABI. */ 152130803Smarcel set_gdbarch_long_double_bit (gdbarch, 64); 153130803Smarcel set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big); 154130803Smarcel 155130803Smarcel set_gdbarch_pc_in_sigtramp (gdbarch, sparc32obsd_pc_in_sigtramp); 156130803Smarcel frame_unwind_append_sniffer (gdbarch, sparc32obsd_sigtramp_frame_sniffer); 157130803Smarcel 158130803Smarcel set_solib_svr4_fetch_link_map_offsets 159130803Smarcel (gdbarch, nbsd_ilp32_solib_svr4_fetch_link_map_offsets); 160130803Smarcel} 161130803Smarcel 162130803Smarcel 163130803Smarcel/* Provide a prototype to silence -Wmissing-prototypes. */ 164130803Smarcelvoid _initialize_sparc32obsd_tdep (void); 165130803Smarcel 166130803Smarcelvoid 167130803Smarcel_initialize_sparc32obsd_tdep (void) 168130803Smarcel{ 169130803Smarcel gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_OPENBSD_ELF, 170130803Smarcel sparc32obsd_init_abi); 171130803Smarcel} 172