1130803Smarcel/* Target-dependent code for Solaris SPARC. 2130803Smarcel 3130803Smarcel Copyright 2003 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 "frame.h" 24130803Smarcel#include "frame-unwind.h" 25130803Smarcel#include "gdbcore.h" 26130803Smarcel#include "symtab.h" 27130803Smarcel#include "objfiles.h" 28130803Smarcel#include "osabi.h" 29130803Smarcel#include "regcache.h" 30130803Smarcel#include "target.h" 31130803Smarcel#include "trad-frame.h" 32130803Smarcel 33130803Smarcel#include "gdb_assert.h" 34130803Smarcel#include "gdb_string.h" 35130803Smarcel 36130803Smarcel#include "sparc-tdep.h" 37130803Smarcel 38130803Smarcel/* From <sys/regset.h>. */ 39130803Smarcelconst struct sparc_gregset sparc32_sol2_gregset = 40130803Smarcel{ 41130803Smarcel 32 * 4, /* %psr */ 42130803Smarcel 33 * 4, /* %pc */ 43130803Smarcel 34 * 4, /* %npc */ 44130803Smarcel 35 * 4, /* %y */ 45130803Smarcel 36 * 4, /* %wim */ 46130803Smarcel 37 * 4, /* %tbr */ 47130803Smarcel 1 * 4, /* %g1 */ 48130803Smarcel 16 * 4, /* %l0 */ 49130803Smarcel}; 50130803Smarcel 51130803Smarcel 52130803Smarcel/* The Solaris signal trampolines reside in libc. For normal signals, 53130803Smarcel the function `sigacthandler' is used. This signal trampoline will 54130803Smarcel call the signal handler using the System V calling convention, 55130803Smarcel where the third argument is a pointer to an instance of 56130803Smarcel `ucontext_t', which has a member `uc_mcontext' that contains the 57130803Smarcel saved registers. Incidentally, the kernel passes the `ucontext_t' 58130803Smarcel pointer as the third argument of the signal trampoline too, and 59130803Smarcel `sigacthandler' simply passes it on. However, if you link your 60130803Smarcel program with "-L/usr/ucblib -R/usr/ucblib -lucb", the function 61130803Smarcel `ucbsigvechandler' will be used, which invokes the using the BSD 62130803Smarcel convention, where the third argument is a pointer to an instance of 63130803Smarcel `struct sigcontext'. It is the `ucbsigvechandler' function that 64130803Smarcel converts the `ucontext_t' to a `sigcontext', and back. Unless the 65130803Smarcel signal handler modifies the `struct sigcontext' we can safely 66130803Smarcel ignore this. */ 67130803Smarcel 68130803Smarcelint 69130803Smarcelsparc_sol2_pc_in_sigtramp (CORE_ADDR pc, char *name) 70130803Smarcel{ 71130803Smarcel return (name && (strcmp (name, "sigacthandler") == 0 72130803Smarcel || strcmp (name, "ucbsigvechandler") == 0)); 73130803Smarcel} 74130803Smarcel 75130803Smarcelstatic struct sparc_frame_cache * 76130803Smarcelsparc32_sol2_sigtramp_frame_cache (struct frame_info *next_frame, 77130803Smarcel void **this_cache) 78130803Smarcel{ 79130803Smarcel struct sparc_frame_cache *cache; 80130803Smarcel CORE_ADDR mcontext_addr, addr; 81130803Smarcel int regnum; 82130803Smarcel 83130803Smarcel if (*this_cache) 84130803Smarcel return *this_cache; 85130803Smarcel 86130803Smarcel cache = sparc_frame_cache (next_frame, this_cache); 87130803Smarcel gdb_assert (cache == *this_cache); 88130803Smarcel 89130803Smarcel cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); 90130803Smarcel 91130803Smarcel /* The third argument is a pointer to an instance of `ucontext_t', 92130803Smarcel which has a member `uc_mcontext' that contains the saved 93130803Smarcel registers. */ 94130803Smarcel regnum = (cache->frameless_p ? SPARC_O2_REGNUM : SPARC_I2_REGNUM); 95130803Smarcel mcontext_addr = frame_unwind_register_unsigned (next_frame, regnum) + 40; 96130803Smarcel 97130803Smarcel cache->saved_regs[SPARC32_PSR_REGNUM].addr = mcontext_addr + 0 * 4; 98130803Smarcel cache->saved_regs[SPARC32_PC_REGNUM].addr = mcontext_addr + 1 * 4; 99130803Smarcel cache->saved_regs[SPARC32_NPC_REGNUM].addr = mcontext_addr + 2 * 4; 100130803Smarcel cache->saved_regs[SPARC32_Y_REGNUM].addr = mcontext_addr + 3 * 4; 101130803Smarcel 102130803Smarcel /* Since %g0 is always zero, keep the identity encoding. */ 103130803Smarcel for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 4 * 4; 104130803Smarcel regnum <= SPARC_O7_REGNUM; regnum++, addr += 4) 105130803Smarcel cache->saved_regs[regnum].addr = addr; 106130803Smarcel 107130803Smarcel if (get_frame_memory_unsigned (next_frame, mcontext_addr + 19 * 4, 4)) 108130803Smarcel { 109130803Smarcel /* The register windows haven't been flushed. */ 110130803Smarcel for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++) 111130803Smarcel trad_frame_set_unknown (cache->saved_regs, regnum); 112130803Smarcel } 113130803Smarcel else 114130803Smarcel { 115130803Smarcel addr = cache->saved_regs[SPARC_SP_REGNUM].addr; 116130803Smarcel addr = get_frame_memory_unsigned (next_frame, addr, 4); 117130803Smarcel for (regnum = SPARC_L0_REGNUM; 118130803Smarcel regnum <= SPARC_I7_REGNUM; regnum++, addr += 4) 119130803Smarcel cache->saved_regs[regnum].addr = addr; 120130803Smarcel } 121130803Smarcel 122130803Smarcel return cache; 123130803Smarcel} 124130803Smarcel 125130803Smarcelstatic void 126130803Smarcelsparc32_sol2_sigtramp_frame_this_id (struct frame_info *next_frame, 127130803Smarcel void **this_cache, 128130803Smarcel struct frame_id *this_id) 129130803Smarcel{ 130130803Smarcel struct sparc_frame_cache *cache = 131130803Smarcel sparc32_sol2_sigtramp_frame_cache (next_frame, this_cache); 132130803Smarcel 133130803Smarcel (*this_id) = frame_id_build (cache->base, cache->pc); 134130803Smarcel} 135130803Smarcel 136130803Smarcelstatic void 137130803Smarcelsparc32_sol2_sigtramp_frame_prev_register (struct frame_info *next_frame, 138130803Smarcel void **this_cache, 139130803Smarcel int regnum, int *optimizedp, 140130803Smarcel enum lval_type *lvalp, 141130803Smarcel CORE_ADDR *addrp, 142130803Smarcel int *realnump, void *valuep) 143130803Smarcel{ 144130803Smarcel struct sparc_frame_cache *cache = 145130803Smarcel sparc32_sol2_sigtramp_frame_cache (next_frame, this_cache); 146130803Smarcel 147130803Smarcel trad_frame_prev_register (next_frame, cache->saved_regs, regnum, 148130803Smarcel optimizedp, lvalp, addrp, realnump, valuep); 149130803Smarcel} 150130803Smarcel 151130803Smarcelstatic const struct frame_unwind sparc32_sol2_sigtramp_frame_unwind = 152130803Smarcel{ 153130803Smarcel SIGTRAMP_FRAME, 154130803Smarcel sparc32_sol2_sigtramp_frame_this_id, 155130803Smarcel sparc32_sol2_sigtramp_frame_prev_register 156130803Smarcel}; 157130803Smarcel 158130803Smarcelstatic const struct frame_unwind * 159130803Smarcelsparc32_sol2_sigtramp_frame_sniffer (struct frame_info *next_frame) 160130803Smarcel{ 161130803Smarcel CORE_ADDR pc = frame_pc_unwind (next_frame); 162130803Smarcel char *name; 163130803Smarcel 164130803Smarcel find_pc_partial_function (pc, &name, NULL, NULL); 165130803Smarcel if (sparc_sol2_pc_in_sigtramp (pc, name)) 166130803Smarcel return &sparc32_sol2_sigtramp_frame_unwind; 167130803Smarcel 168130803Smarcel return NULL; 169130803Smarcel} 170130803Smarcel 171130803Smarcel 172130803Smarcelvoid 173130803Smarcelsparc32_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 174130803Smarcel{ 175130803Smarcel struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 176130803Smarcel 177130803Smarcel /* Solaris has SVR4-style shared libraries... */ 178130803Smarcel set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section); 179130803Smarcel set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); 180130803Smarcel 181130803Smarcel /* ...which means that we need some special handling when doing 182130803Smarcel prologue analysis. */ 183130803Smarcel tdep->plt_entry_size = 12; 184130803Smarcel 185130803Smarcel /* Solaris has kernel-assisted single-stepping support. */ 186130803Smarcel set_gdbarch_software_single_step (gdbarch, NULL); 187130803Smarcel 188130803Smarcel set_gdbarch_pc_in_sigtramp (gdbarch, sparc_sol2_pc_in_sigtramp); 189130803Smarcel frame_unwind_append_sniffer (gdbarch, sparc32_sol2_sigtramp_frame_sniffer); 190130803Smarcel} 191130803Smarcel 192130803Smarcel 193130803Smarcel/* Provide a prototype to silence -Wmissing-prototypes. */ 194130803Smarcelvoid _initialize_sparc_sol2_tdep (void); 195130803Smarcel 196130803Smarcelvoid 197130803Smarcel_initialize_sparc_sol2_tdep (void) 198130803Smarcel{ 199130803Smarcel gdbarch_register_osabi (bfd_arch_sparc, 0, 200130803Smarcel GDB_OSABI_SOLARIS, sparc32_sol2_init_abi); 201130803Smarcel} 202