1130803Smarcel/* Target-dependent code for Solaris UltraSPARC. 2130803Smarcel 3130803Smarcel Copyright 2003, 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 "frame.h" 24130803Smarcel#include "frame-unwind.h" 25130803Smarcel#include "gdbarch.h" 26130803Smarcel#include "symtab.h" 27130803Smarcel#include "objfiles.h" 28130803Smarcel#include "osabi.h" 29130803Smarcel#include "trad-frame.h" 30130803Smarcel 31130803Smarcel#include "gdb_assert.h" 32130803Smarcel 33130803Smarcel#include "sparc64-tdep.h" 34130803Smarcel 35130803Smarcel/* From <sys/regset.h>. */ 36130803Smarcelconst struct sparc_gregset sparc64_sol2_gregset = 37130803Smarcel{ 38130803Smarcel 32 * 8, /* "tstate" */ 39130803Smarcel 33 * 8, /* %pc */ 40130803Smarcel 34 * 8, /* %npc */ 41130803Smarcel 35 * 8, /* %y */ 42130803Smarcel -1, /* %wim */ 43130803Smarcel -1, /* %tbr */ 44130803Smarcel 1 * 8, /* %g1 */ 45130803Smarcel 16 * 8, /* %l0 */ 46130803Smarcel 8 /* sizeof (%y) */ 47130803Smarcel}; 48130803Smarcel 49130803Smarcel 50130803Smarcelstatic struct sparc_frame_cache * 51130803Smarcelsparc64_sol2_sigtramp_frame_cache (struct frame_info *next_frame, 52130803Smarcel void **this_cache) 53130803Smarcel{ 54130803Smarcel struct sparc_frame_cache *cache; 55130803Smarcel CORE_ADDR mcontext_addr, addr; 56130803Smarcel int regnum; 57130803Smarcel 58130803Smarcel if (*this_cache) 59130803Smarcel return *this_cache; 60130803Smarcel 61130803Smarcel cache = sparc_frame_cache (next_frame, this_cache); 62130803Smarcel gdb_assert (cache == *this_cache); 63130803Smarcel 64130803Smarcel cache->saved_regs = trad_frame_alloc_saved_regs (next_frame); 65130803Smarcel 66130803Smarcel /* The third argument is a pointer to an instance of `ucontext_t', 67130803Smarcel which has a member `uc_mcontext' that contains the saved 68130803Smarcel registers. */ 69130803Smarcel regnum = (cache->frameless_p ? SPARC_O2_REGNUM : SPARC_I2_REGNUM); 70130803Smarcel mcontext_addr = frame_unwind_register_unsigned (next_frame, regnum) + 64; 71130803Smarcel 72130803Smarcel cache->saved_regs[SPARC64_CCR_REGNUM].addr = mcontext_addr + 0 * 8; 73130803Smarcel cache->saved_regs[SPARC64_PC_REGNUM].addr = mcontext_addr + 1 * 8; 74130803Smarcel cache->saved_regs[SPARC64_NPC_REGNUM].addr = mcontext_addr + 2 * 8; 75130803Smarcel cache->saved_regs[SPARC64_Y_REGNUM].addr = mcontext_addr + 3 * 8; 76130803Smarcel cache->saved_regs[SPARC64_ASI_REGNUM].addr = mcontext_addr + 19 * 8; 77130803Smarcel cache->saved_regs[SPARC64_FPRS_REGNUM].addr = mcontext_addr + 20 * 8; 78130803Smarcel 79130803Smarcel /* Since %g0 is always zero, keep the identity encoding. */ 80130803Smarcel for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 4 * 8; 81130803Smarcel regnum <= SPARC_O7_REGNUM; regnum++, addr += 8) 82130803Smarcel cache->saved_regs[regnum].addr = addr; 83130803Smarcel 84130803Smarcel if (get_frame_memory_unsigned (next_frame, mcontext_addr + 21 * 8, 8)) 85130803Smarcel { 86130803Smarcel /* The register windows haven't been flushed. */ 87130803Smarcel for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++) 88130803Smarcel trad_frame_set_unknown (cache->saved_regs, regnum); 89130803Smarcel } 90130803Smarcel else 91130803Smarcel { 92130803Smarcel CORE_ADDR sp; 93130803Smarcel 94130803Smarcel addr = cache->saved_regs[SPARC_SP_REGNUM].addr; 95130803Smarcel sp = get_frame_memory_unsigned (next_frame, addr, 8); 96130803Smarcel for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS; 97130803Smarcel regnum <= SPARC_I7_REGNUM; regnum++, addr += 8) 98130803Smarcel cache->saved_regs[regnum].addr = addr; 99130803Smarcel } 100130803Smarcel 101130803Smarcel return cache; 102130803Smarcel} 103130803Smarcel 104130803Smarcelstatic void 105130803Smarcelsparc64_sol2_sigtramp_frame_this_id (struct frame_info *next_frame, 106130803Smarcel void **this_cache, 107130803Smarcel struct frame_id *this_id) 108130803Smarcel{ 109130803Smarcel struct sparc_frame_cache *cache = 110130803Smarcel sparc64_sol2_sigtramp_frame_cache (next_frame, this_cache); 111130803Smarcel 112130803Smarcel (*this_id) = frame_id_build (cache->base, cache->pc); 113130803Smarcel} 114130803Smarcel 115130803Smarcelstatic void 116130803Smarcelsparc64_sol2_sigtramp_frame_prev_register (struct frame_info *next_frame, 117130803Smarcel void **this_cache, 118130803Smarcel int regnum, int *optimizedp, 119130803Smarcel enum lval_type *lvalp, 120130803Smarcel CORE_ADDR *addrp, 121130803Smarcel int *realnump, void *valuep) 122130803Smarcel{ 123130803Smarcel struct sparc_frame_cache *cache = 124130803Smarcel sparc64_sol2_sigtramp_frame_cache (next_frame, this_cache); 125130803Smarcel 126130803Smarcel trad_frame_prev_register (next_frame, cache->saved_regs, regnum, 127130803Smarcel optimizedp, lvalp, addrp, realnump, valuep); 128130803Smarcel} 129130803Smarcel 130130803Smarcelstatic const struct frame_unwind sparc64_sol2_sigtramp_frame_unwind = 131130803Smarcel{ 132130803Smarcel SIGTRAMP_FRAME, 133130803Smarcel sparc64_sol2_sigtramp_frame_this_id, 134130803Smarcel sparc64_sol2_sigtramp_frame_prev_register 135130803Smarcel}; 136130803Smarcel 137130803Smarcelstatic const struct frame_unwind * 138130803Smarcelsparc64_sol2_sigtramp_frame_sniffer (struct frame_info *next_frame) 139130803Smarcel{ 140130803Smarcel CORE_ADDR pc = frame_pc_unwind (next_frame); 141130803Smarcel char *name; 142130803Smarcel 143130803Smarcel find_pc_partial_function (pc, &name, NULL, NULL); 144130803Smarcel if (sparc_sol2_pc_in_sigtramp (pc, name)) 145130803Smarcel return &sparc64_sol2_sigtramp_frame_unwind; 146130803Smarcel 147130803Smarcel return NULL; 148130803Smarcel} 149130803Smarcel 150130803Smarcel 151130803Smarcelvoid 152130803Smarcelsparc64_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 153130803Smarcel{ 154130803Smarcel struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 155130803Smarcel 156130803Smarcel set_gdbarch_pc_in_sigtramp (gdbarch, sparc_sol2_pc_in_sigtramp); 157130803Smarcel frame_unwind_append_sniffer (gdbarch, sparc64_sol2_sigtramp_frame_sniffer); 158130803Smarcel 159130803Smarcel sparc64_init_abi (info, gdbarch); 160130803Smarcel 161130803Smarcel /* Solaris has SVR4-style shared libraries... */ 162130803Smarcel set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section); 163130803Smarcel set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); 164130803Smarcel 165130803Smarcel /* ...which means that we need some special handling when doing 166130803Smarcel prologue analysis. */ 167130803Smarcel tdep->plt_entry_size = 16; 168130803Smarcel 169130803Smarcel /* Solaris has kernel-assisted single-stepping support. */ 170130803Smarcel set_gdbarch_software_single_step (gdbarch, NULL); 171130803Smarcel} 172130803Smarcel 173130803Smarcel 174130803Smarcel/* Provide a prototype to silence -Wmissing-prototypes. */ 175130803Smarcelvoid _initialize_sparc64_sol2_tdep (void); 176130803Smarcel 177130803Smarcelvoid 178130803Smarcel_initialize_sparc64_sol2_tdep (void) 179130803Smarcel{ 180130803Smarcel gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9, 181130803Smarcel GDB_OSABI_SOLARIS, sparc64_sol2_init_abi); 182130803Smarcel} 183