1132624Smarcel/* 2132624Smarcel * Copyright (c) 2004 Marcel Moolenaar 3132624Smarcel * All rights reserved. 4132624Smarcel * 5132624Smarcel * Redistribution and use in source and binary forms, with or without 6132624Smarcel * modification, are permitted provided that the following conditions 7132624Smarcel * are met: 8132624Smarcel * 9132624Smarcel * 1. Redistributions of source code must retain the above copyright 10132624Smarcel * notice, this list of conditions and the following disclaimer. 11132624Smarcel * 2. Redistributions in binary form must reproduce the above copyright 12132624Smarcel * notice, this list of conditions and the following disclaimer in the 13132624Smarcel * documentation and/or other materials provided with the distribution. 14132624Smarcel * 15132624Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16132624Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17132624Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18132624Smarcel * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 19132624Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20132624Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21132624Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22132624Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23132624Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24132624Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25132624Smarcel */ 26132624Smarcel 27132624Smarcel#include <sys/cdefs.h> 28132624Smarcel__FBSDID("$FreeBSD$"); 29132624Smarcel 30132624Smarcel#include <sys/types.h> 31132624Smarcel#include <machine/asm.h> 32132624Smarcel#include <machine/pcb.h> 33149961Smarcel#include <machine/frame.h> 34132624Smarcel#include <err.h> 35132624Smarcel#include <kvm.h> 36132624Smarcel#include <string.h> 37132624Smarcel 38132624Smarcel#include <defs.h> 39132624Smarcel#include <target.h> 40132624Smarcel#include <gdbthread.h> 41132624Smarcel#include <inferior.h> 42132624Smarcel#include <regcache.h> 43149954Smarcel#include <frame-unwind.h> 44149119Smarcel#include <sparc-tdep.h> 45149119Smarcel#include <sparc64-tdep.h> 46132624Smarcel 47149954Smarcel#include "kgdb.h" 48149954Smarcel 49132624Smarcelvoid 50132624Smarcelkgdb_trgt_fetch_registers(int regno __unused) 51132624Smarcel{ 52132624Smarcel struct kthr *kt; 53132624Smarcel struct pcb pcb; 54132624Smarcel 55178713Sjhb kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); 56132624Smarcel if (kt == NULL) 57132624Smarcel return; 58132624Smarcel if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { 59132624Smarcel warnx("kvm_read: %s", kvm_geterr(kvm)); 60132624Smarcel memset(&pcb, 0, sizeof(pcb)); 61132624Smarcel } 62132624Smarcel 63149119Smarcel supply_register(SPARC_SP_REGNUM, (char *)&pcb.pcb_sp); 64149119Smarcel sparc_supply_rwindow(current_regcache, pcb.pcb_sp, -1); 65149119Smarcel supply_register(SPARC64_PC_REGNUM, (char *)&pcb.pcb_pc); 66149119Smarcel pcb.pcb_pc += 4; 67149119Smarcel supply_register(SPARC64_NPC_REGNUM, (char *)&pcb.pcb_pc); 68132624Smarcel} 69132624Smarcel 70132624Smarcelvoid 71132624Smarcelkgdb_trgt_store_registers(int regno __unused) 72132624Smarcel{ 73132624Smarcel fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); 74132624Smarcel} 75149954Smarcel 76178670Sjhbvoid 77178670Sjhbkgdb_trgt_new_objfile(struct objfile *objfile) 78178670Sjhb{ 79178670Sjhb} 80178670Sjhb 81149961Smarcelstruct kgdb_frame_cache { 82149961Smarcel CORE_ADDR pc; 83149961Smarcel CORE_ADDR sp; 84149961Smarcel CORE_ADDR fp; 85149961Smarcel}; 86149961Smarcel 87149961Smarcelstatic struct kgdb_frame_cache * 88149961Smarcelkgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) 89149961Smarcel{ 90149961Smarcel char buf[MAX_REGISTER_SIZE]; 91149961Smarcel struct kgdb_frame_cache *cache; 92149961Smarcel 93149961Smarcel cache = *this_cache; 94149961Smarcel if (cache == NULL) { 95149961Smarcel cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); 96149961Smarcel *this_cache = cache; 97149961Smarcel cache->pc = frame_func_unwind(next_frame); 98149961Smarcel frame_unwind_register(next_frame, SPARC_SP_REGNUM, buf); 99149961Smarcel cache->sp = extract_unsigned_integer(buf, 100149961Smarcel register_size(current_gdbarch, SPARC_SP_REGNUM)); 101149961Smarcel frame_unwind_register(next_frame, SPARC_FP_REGNUM, buf); 102149961Smarcel cache->fp = extract_unsigned_integer(buf, 103149961Smarcel register_size(current_gdbarch, SPARC_FP_REGNUM)); 104149961Smarcel cache->fp += BIAS - sizeof(struct trapframe); 105149961Smarcel } 106149961Smarcel return (cache); 107149961Smarcel} 108149961Smarcel 109149954Smarcelstatic void 110149954Smarcelkgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, 111149954Smarcel struct frame_id *this_id) 112149954Smarcel{ 113149961Smarcel struct kgdb_frame_cache *cache; 114149961Smarcel 115149961Smarcel cache = kgdb_trgt_frame_cache(next_frame, this_cache); 116149961Smarcel *this_id = frame_id_build(cache->sp, cache->pc); 117149954Smarcel} 118149954Smarcel 119149954Smarcelstatic void 120149954Smarcelkgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, 121149954Smarcel void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, 122149954Smarcel CORE_ADDR *addrp, int *realnump, void *valuep) 123149954Smarcel{ 124149961Smarcel char dummy_valuep[MAX_REGISTER_SIZE]; 125149961Smarcel struct kgdb_frame_cache *cache; 126149961Smarcel int ofs, regsz; 127149961Smarcel 128149961Smarcel regsz = register_size(current_gdbarch, regnum); 129149961Smarcel 130149961Smarcel if (valuep == NULL) 131149961Smarcel valuep = dummy_valuep; 132149961Smarcel memset(valuep, 0, regsz); 133149961Smarcel *optimizedp = 0; 134149961Smarcel *addrp = 0; 135149961Smarcel *lvalp = not_lval; 136149961Smarcel *realnump = -1; 137149961Smarcel 138149961Smarcel cache = kgdb_trgt_frame_cache(next_frame, this_cache); 139149961Smarcel 140149961Smarcel switch (regnum) { 141149961Smarcel case SPARC_SP_REGNUM: 142149961Smarcel ofs = offsetof(struct trapframe, tf_sp); 143149961Smarcel break; 144149961Smarcel case SPARC64_PC_REGNUM: 145149961Smarcel ofs = offsetof(struct trapframe, tf_tpc); 146149961Smarcel break; 147149961Smarcel case SPARC64_NPC_REGNUM: 148149961Smarcel ofs = offsetof(struct trapframe, tf_tnpc); 149149961Smarcel break; 150149961Smarcel case SPARC_O0_REGNUM: 151149961Smarcel case SPARC_O1_REGNUM: 152149961Smarcel case SPARC_O2_REGNUM: 153149961Smarcel case SPARC_O3_REGNUM: 154149961Smarcel case SPARC_O4_REGNUM: 155149961Smarcel case SPARC_O5_REGNUM: 156149961Smarcel case SPARC_O7_REGNUM: 157149961Smarcel ofs = offsetof(struct trapframe, tf_out) + 158149961Smarcel (regnum - SPARC_O0_REGNUM) * 8; 159149961Smarcel break; 160149961Smarcel default: 161149961Smarcel if (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) { 162149961Smarcel ofs = (regnum - SPARC_L0_REGNUM) * 8; 163149961Smarcel *addrp = cache->sp + BIAS + ofs; 164149961Smarcel *lvalp = lval_memory; 165149961Smarcel target_read_memory(*addrp, valuep, regsz); 166149961Smarcel } 167149961Smarcel return; 168149961Smarcel } 169149961Smarcel 170149961Smarcel *addrp = cache->fp + ofs; 171149961Smarcel *lvalp = lval_memory; 172149961Smarcel target_read_memory(*addrp, valuep, regsz); 173149954Smarcel} 174149954Smarcel 175149954Smarcelstatic const struct frame_unwind kgdb_trgt_trapframe_unwind = { 176149954Smarcel UNKNOWN_FRAME, 177149954Smarcel &kgdb_trgt_trapframe_this_id, 178149954Smarcel &kgdb_trgt_trapframe_prev_register 179149954Smarcel}; 180149954Smarcel 181149954Smarcelconst struct frame_unwind * 182149954Smarcelkgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) 183149954Smarcel{ 184149961Smarcel char *pname; 185149961Smarcel CORE_ADDR pc; 186149954Smarcel 187149961Smarcel pc = frame_func_unwind(next_frame); 188149961Smarcel pname = NULL; 189149961Smarcel find_pc_partial_function(pc, &pname, NULL, NULL); 190149961Smarcel if (pname == NULL) 191149961Smarcel return (NULL); 192149977Smarcel if (strcmp(pname, "tl0_intr") == 0 || 193149977Smarcel strcmp(pname, "tl0_trap") == 0 || 194149977Smarcel strcmp(pname, "tl1_intr") == 0 || 195149977Smarcel strcmp(pname, "tl1_trap") == 0) 196149961Smarcel return (&kgdb_trgt_trapframe_unwind); 197149961Smarcel /* printf("%s: %lx =%s\n", __func__, pc, pname); */ 198149961Smarcel return (NULL); 199149954Smarcel} 200