sparcnbsd-tdep.c revision 130803
1130803Smarcel/* Target-dependent code for NetBSD/sparc. 2130803Smarcel 3130803Smarcel Copyright 2002, 2003, 2004 Free Software Foundation, Inc. 4130803Smarcel Contributed by Wasabi Systems, Inc. 5130803Smarcel 6130803Smarcel This file is part of GDB. 7130803Smarcel 8130803Smarcel This program is free software; you can redistribute it and/or modify 9130803Smarcel it under the terms of the GNU General Public License as published by 10130803Smarcel the Free Software Foundation; either version 2 of the License, or 11130803Smarcel (at your option) any later version. 12130803Smarcel 13130803Smarcel This program is distributed in the hope that it will be useful, 14130803Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 15130803Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16130803Smarcel GNU General Public License for more details. 17130803Smarcel 18130803Smarcel You should have received a copy of the GNU General Public License 19130803Smarcel along with this program; if not, write to the Free Software 20130803Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 21130803Smarcel Boston, MA 02111-1307, USA. */ 22130803Smarcel 23130803Smarcel#include "defs.h" 24130803Smarcel#include "floatformat.h" 25130803Smarcel#include "frame.h" 26130803Smarcel#include "frame-unwind.h" 27130803Smarcel#include "gdbcore.h" 28130803Smarcel#include "osabi.h" 29130803Smarcel#include "regcache.h" 30130803Smarcel#include "regset.h" 31130803Smarcel#include "solib-svr4.h" 32130803Smarcel#include "symtab.h" 33130803Smarcel#include "trad-frame.h" 34130803Smarcel 35130803Smarcel#include "gdb_assert.h" 36130803Smarcel#include "gdb_string.h" 37130803Smarcel 38130803Smarcel#include "sparc-tdep.h" 39130803Smarcel#include "nbsd-tdep.h" 40130803Smarcel 41130803Smarcelconst struct sparc_gregset sparc32nbsd_gregset = 42130803Smarcel{ 43130803Smarcel 0 * 4, /* %psr */ 44130803Smarcel 1 * 4, /* %pc */ 45130803Smarcel 2 * 4, /* %npc */ 46130803Smarcel 3 * 4, /* %y */ 47130803Smarcel -1, /* %wim */ 48130803Smarcel -1, /* %tbr */ 49130803Smarcel 5 * 4, /* %g1 */ 50130803Smarcel -1 /* %l0 */ 51130803Smarcel}; 52130803Smarcel 53130803Smarcelstatic void 54130803Smarcelsparc32nbsd_supply_gregset (const struct regset *regset, 55130803Smarcel struct regcache *regcache, 56130803Smarcel int regnum, const void *gregs, size_t len) 57130803Smarcel{ 58130803Smarcel sparc32_supply_gregset (regset->descr, regcache, regnum, gregs); 59130803Smarcel 60130803Smarcel /* Traditional NetBSD core files don't use multiple register sets. 61130803Smarcel Instead, the general-purpose and floating-point registers are 62130803Smarcel lumped together in a single section. */ 63130803Smarcel if (len >= 212) 64130803Smarcel sparc32_supply_fpregset (regcache, regnum, (const char *) gregs + 80); 65130803Smarcel} 66130803Smarcel 67130803Smarcelstatic void 68130803Smarcelsparc32nbsd_supply_fpregset (const struct regset *regset, 69130803Smarcel struct regcache *regcache, 70130803Smarcel int regnum, const void *fpregs, size_t len) 71130803Smarcel{ 72130803Smarcel sparc32_supply_fpregset (regcache, regnum, fpregs); 73130803Smarcel} 74130803Smarcel 75130803Smarcel 76130803Smarcel/* Signal trampolines. */ 77130803Smarcel 78130803Smarcel/* The following variables describe the location of an on-stack signal 79130803Smarcel trampoline. The current values correspond to the memory layout for 80130803Smarcel NetBSD 1.3 and up. These shouldn't be necessary for NetBSD 2.0 and 81130803Smarcel up, since NetBSD uses signal trampolines provided by libc now. */ 82130803Smarcel 83130803Smarcelstatic const CORE_ADDR sparc32nbsd_sigtramp_start = 0xeffffef0; 84130803Smarcelstatic const CORE_ADDR sparc32nbsd_sigtramp_end = 0xeffffff0; 85130803Smarcel 86130803Smarcelstatic int 87130803Smarcelsparc32nbsd_pc_in_sigtramp (CORE_ADDR pc, char *name) 88130803Smarcel{ 89130803Smarcel if (pc >= sparc32nbsd_sigtramp_start && pc < sparc32nbsd_sigtramp_end) 90130803Smarcel return 1; 91130803Smarcel 92130803Smarcel return nbsd_pc_in_sigtramp (pc, name); 93130803Smarcel} 94130803Smarcel 95130803Smarcelstruct trad_frame_saved_reg * 96130803Smarcelsparc32nbsd_sigcontext_saved_regs (struct frame_info *next_frame) 97130803Smarcel{ 98130803Smarcel struct trad_frame_saved_reg *saved_regs; 99130803Smarcel CORE_ADDR addr, sigcontext_addr; 100130803Smarcel int regnum, delta; 101130803Smarcel ULONGEST psr; 102130803Smarcel 103130803Smarcel saved_regs = trad_frame_alloc_saved_regs (next_frame); 104130803Smarcel 105130803Smarcel /* We find the appropriate instance of `struct sigcontext' at a 106130803Smarcel fixed offset in the signal frame. */ 107130803Smarcel addr = frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM); 108130803Smarcel sigcontext_addr = addr + 64 + 16; 109130803Smarcel 110130803Smarcel /* The registers are saved in bits and pieces scattered all over the 111130803Smarcel place. The code below records their location on the assumption 112130803Smarcel that the part of the signal trampoline that saves the state has 113130803Smarcel been executed. */ 114130803Smarcel 115130803Smarcel saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8; 116130803Smarcel saved_regs[SPARC32_PC_REGNUM].addr = sigcontext_addr + 12; 117130803Smarcel saved_regs[SPARC32_NPC_REGNUM].addr = sigcontext_addr + 16; 118130803Smarcel saved_regs[SPARC32_PSR_REGNUM].addr = sigcontext_addr + 20; 119130803Smarcel saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 24; 120130803Smarcel saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 28; 121130803Smarcel 122130803Smarcel /* The remaining `global' registers and %y are saved in the `local' 123130803Smarcel registers. */ 124130803Smarcel delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM; 125130803Smarcel for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++) 126130803Smarcel saved_regs[regnum].realreg = regnum + delta; 127130803Smarcel saved_regs[SPARC32_Y_REGNUM].realreg = SPARC_L1_REGNUM; 128130803Smarcel 129130803Smarcel /* The remaining `out' registers can be found in the current frame's 130130803Smarcel `in' registers. */ 131130803Smarcel delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM; 132130803Smarcel for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++) 133130803Smarcel saved_regs[regnum].realreg = regnum + delta; 134130803Smarcel saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM; 135130803Smarcel 136130803Smarcel /* The `local' and `in' registers have been saved in the register 137130803Smarcel save area. */ 138130803Smarcel addr = saved_regs[SPARC_SP_REGNUM].addr; 139130803Smarcel addr = get_frame_memory_unsigned (next_frame, addr, 4); 140130803Smarcel for (regnum = SPARC_L0_REGNUM; 141130803Smarcel regnum <= SPARC_I7_REGNUM; regnum++, addr += 4) 142130803Smarcel saved_regs[regnum].addr = addr; 143130803Smarcel 144130803Smarcel /* Handle StackGhost. */ 145130803Smarcel { 146130803Smarcel ULONGEST wcookie = sparc_fetch_wcookie (); 147130803Smarcel 148130803Smarcel if (wcookie != 0) 149130803Smarcel { 150130803Smarcel ULONGEST i7; 151130803Smarcel 152130803Smarcel addr = saved_regs[SPARC_I7_REGNUM].addr; 153130803Smarcel i7 = get_frame_memory_unsigned (next_frame, addr, 4); 154130803Smarcel trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie); 155130803Smarcel } 156130803Smarcel } 157130803Smarcel 158130803Smarcel /* The floating-point registers are only saved if the EF bit in %prs 159130803Smarcel has been set. */ 160130803Smarcel 161130803Smarcel#define PSR_EF 0x00001000 162130803Smarcel 163130803Smarcel addr = saved_regs[SPARC32_PSR_REGNUM].addr; 164130803Smarcel psr = get_frame_memory_unsigned (next_frame, addr, 4); 165130803Smarcel if (psr & PSR_EF) 166130803Smarcel { 167130803Smarcel CORE_ADDR sp; 168130803Smarcel 169130803Smarcel sp = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM); 170130803Smarcel saved_regs[SPARC32_FSR_REGNUM].addr = sp + 96; 171130803Smarcel for (regnum = SPARC_F0_REGNUM, addr = sp + 96 + 8; 172130803Smarcel regnum <= SPARC_F31_REGNUM; regnum++, addr += 4) 173130803Smarcel saved_regs[regnum].addr = addr; 174130803Smarcel } 175130803Smarcel 176130803Smarcel return saved_regs; 177130803Smarcel} 178130803Smarcel 179130803Smarcelstatic struct sparc_frame_cache * 180130803Smarcelsparc32nbsd_sigcontext_frame_cache (struct frame_info *next_frame, 181130803Smarcel void **this_cache) 182130803Smarcel{ 183130803Smarcel struct sparc_frame_cache *cache; 184130803Smarcel CORE_ADDR addr; 185130803Smarcel 186130803Smarcel if (*this_cache) 187130803Smarcel return *this_cache; 188130803Smarcel 189130803Smarcel cache = sparc_frame_cache (next_frame, this_cache); 190130803Smarcel gdb_assert (cache == *this_cache); 191130803Smarcel 192130803Smarcel /* If we couldn't find the frame's function, we're probably dealing 193130803Smarcel with an on-stack signal trampoline. */ 194130803Smarcel if (cache->pc == 0) 195130803Smarcel { 196130803Smarcel cache->pc = sparc32nbsd_sigtramp_start; 197130803Smarcel 198130803Smarcel /* Since we couldn't find the frame's function, the cache was 199130803Smarcel initialized under the assumption that we're frameless. */ 200130803Smarcel cache->frameless_p = 0; 201130803Smarcel addr = frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM); 202130803Smarcel cache->base = addr; 203130803Smarcel } 204130803Smarcel 205130803Smarcel cache->saved_regs = sparc32nbsd_sigcontext_saved_regs (next_frame); 206130803Smarcel 207130803Smarcel return cache; 208130803Smarcel} 209130803Smarcel 210130803Smarcelstatic void 211130803Smarcelsparc32nbsd_sigcontext_frame_this_id (struct frame_info *next_frame, 212130803Smarcel void **this_cache, 213130803Smarcel struct frame_id *this_id) 214130803Smarcel{ 215130803Smarcel struct sparc_frame_cache *cache = 216130803Smarcel sparc32nbsd_sigcontext_frame_cache (next_frame, this_cache); 217130803Smarcel 218130803Smarcel (*this_id) = frame_id_build (cache->base, cache->pc); 219130803Smarcel} 220130803Smarcel 221130803Smarcelstatic void 222130803Smarcelsparc32nbsd_sigcontext_frame_prev_register (struct frame_info *next_frame, 223130803Smarcel void **this_cache, 224130803Smarcel int regnum, int *optimizedp, 225130803Smarcel enum lval_type *lvalp, 226130803Smarcel CORE_ADDR *addrp, 227130803Smarcel int *realnump, void *valuep) 228130803Smarcel{ 229130803Smarcel struct sparc_frame_cache *cache = 230130803Smarcel sparc32nbsd_sigcontext_frame_cache (next_frame, this_cache); 231130803Smarcel 232130803Smarcel trad_frame_prev_register (next_frame, cache->saved_regs, regnum, 233130803Smarcel optimizedp, lvalp, addrp, realnump, valuep); 234130803Smarcel} 235130803Smarcel 236130803Smarcelstatic const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind = 237130803Smarcel{ 238130803Smarcel SIGTRAMP_FRAME, 239130803Smarcel sparc32nbsd_sigcontext_frame_this_id, 240130803Smarcel sparc32nbsd_sigcontext_frame_prev_register 241130803Smarcel}; 242130803Smarcel 243130803Smarcelstatic const struct frame_unwind * 244130803Smarcelsparc32nbsd_sigtramp_frame_sniffer (struct frame_info *next_frame) 245130803Smarcel{ 246130803Smarcel CORE_ADDR pc = frame_pc_unwind (next_frame); 247130803Smarcel char *name; 248130803Smarcel 249130803Smarcel find_pc_partial_function (pc, &name, NULL, NULL); 250130803Smarcel if (sparc32nbsd_pc_in_sigtramp (pc, name)) 251130803Smarcel { 252130803Smarcel if (name == NULL || strncmp (name, "__sigtramp_sigcontext", 21)) 253130803Smarcel return &sparc32nbsd_sigcontext_frame_unwind; 254130803Smarcel } 255130803Smarcel 256130803Smarcel return NULL; 257130803Smarcel} 258130803Smarcel 259130803Smarcel 260130803Smarcel/* Return non-zero if we are in a shared library trampoline code stub. */ 261130803Smarcel 262130803Smarcelstatic int 263130803Smarcelsparcnbsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name) 264130803Smarcel{ 265130803Smarcel return (name && !strcmp (name, "_DYNAMIC")); 266130803Smarcel} 267130803Smarcel 268130803Smarcelstatic void 269130803Smarcelsparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 270130803Smarcel{ 271130803Smarcel struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 272130803Smarcel 273130803Smarcel /* NetBSD doesn't support the 128-bit `long double' from the psABI. */ 274130803Smarcel set_gdbarch_long_double_bit (gdbarch, 64); 275130803Smarcel set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big); 276130803Smarcel 277130803Smarcel tdep->gregset = XMALLOC (struct regset); 278130803Smarcel tdep->gregset->descr = &sparc32nbsd_gregset; 279130803Smarcel tdep->gregset->supply_regset = sparc32nbsd_supply_gregset; 280130803Smarcel tdep->sizeof_gregset = 20 * 4; 281130803Smarcel 282130803Smarcel tdep->fpregset = XMALLOC (struct regset); 283130803Smarcel tdep->fpregset->supply_regset = sparc32nbsd_supply_fpregset; 284130803Smarcel tdep->sizeof_fpregset = 33 * 4; 285130803Smarcel 286130803Smarcel set_gdbarch_pc_in_sigtramp (gdbarch, sparc32nbsd_pc_in_sigtramp); 287130803Smarcel frame_unwind_append_sniffer (gdbarch, sparc32nbsd_sigtramp_frame_sniffer); 288130803Smarcel} 289130803Smarcel 290130803Smarcelstatic void 291130803Smarcelsparc32nbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 292130803Smarcel{ 293130803Smarcel sparc32nbsd_init_abi (info, gdbarch); 294130803Smarcel 295130803Smarcel set_gdbarch_in_solib_call_trampoline 296130803Smarcel (gdbarch, sparcnbsd_aout_in_solib_call_trampoline); 297130803Smarcel} 298130803Smarcel 299130803Smarcelstatic void 300130803Smarcelsparc32nbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 301130803Smarcel{ 302130803Smarcel sparc32nbsd_init_abi (info, gdbarch); 303130803Smarcel 304130803Smarcel set_solib_svr4_fetch_link_map_offsets 305130803Smarcel (gdbarch, nbsd_ilp32_solib_svr4_fetch_link_map_offsets); 306130803Smarcel} 307130803Smarcel 308130803Smarcelstatic enum gdb_osabi 309130803Smarcelsparcnbsd_aout_osabi_sniffer (bfd *abfd) 310130803Smarcel{ 311130803Smarcel if (strcmp (bfd_get_target (abfd), "a.out-sparc-netbsd") == 0) 312130803Smarcel return GDB_OSABI_NETBSD_AOUT; 313130803Smarcel 314130803Smarcel return GDB_OSABI_UNKNOWN; 315130803Smarcel} 316130803Smarcel 317130803Smarcel/* OpenBSD uses the traditional NetBSD core file format, even for 318130803Smarcel ports that use ELF. Therefore, if the default OS ABI is OpenBSD 319130803Smarcel ELF, we return that instead of NetBSD a.out. This is mainly for 320130803Smarcel the benfit of OpenBSD/sparc64, which inherits the sniffer below 321130803Smarcel since we include this file for an OpenBSD/sparc64 target. For 322130803Smarcel OpenBSD/sparc, the NetBSD a.out OS ABI is probably similar enough 323130803Smarcel to both the OpenBSD a.out and the OpenBSD ELF OS ABI. */ 324130803Smarcel#if defined (GDB_OSABI_DEFAULT) && (GDB_OSABI_DEFAULT == GDB_OSABI_OPENBSD_ELF) 325130803Smarcel#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF 326130803Smarcel#else 327130803Smarcel#define GDB_OSABI_NETBSD_CORE GDB_OSABI_NETBSD_AOUT 328130803Smarcel#endif 329130803Smarcel 330130803Smarcelstatic enum gdb_osabi 331130803Smarcelsparcnbsd_core_osabi_sniffer (bfd *abfd) 332130803Smarcel{ 333130803Smarcel if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0) 334130803Smarcel return GDB_OSABI_NETBSD_CORE; 335130803Smarcel 336130803Smarcel return GDB_OSABI_UNKNOWN; 337130803Smarcel} 338130803Smarcel 339130803Smarcel 340130803Smarcel/* Provide a prototype to silence -Wmissing-prototypes. */ 341130803Smarcelvoid _initialize_sparcnbsd_tdep (void); 342130803Smarcel 343130803Smarcelvoid 344130803Smarcel_initialize_sparnbsd_tdep (void) 345130803Smarcel{ 346130803Smarcel gdbarch_register_osabi_sniffer (bfd_arch_sparc, bfd_target_aout_flavour, 347130803Smarcel sparcnbsd_aout_osabi_sniffer); 348130803Smarcel 349130803Smarcel /* BFD doesn't set the architecture for NetBSD style a.out core 350130803Smarcel files. */ 351130803Smarcel gdbarch_register_osabi_sniffer (bfd_arch_unknown, bfd_target_unknown_flavour, 352130803Smarcel sparcnbsd_core_osabi_sniffer); 353130803Smarcel 354130803Smarcel gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD_AOUT, 355130803Smarcel sparc32nbsd_aout_init_abi); 356130803Smarcel gdbarch_register_osabi (bfd_arch_sparc, 0, GDB_OSABI_NETBSD_ELF, 357130803Smarcel sparc32nbsd_elf_init_abi); 358130803Smarcel} 359