1179161Sobrien/* 2179162Sobrien * Copyright (c) 2007 Juniper Networks, Inc. 3179161Sobrien * Copyright (c) 2004 Marcel Moolenaar 4179161Sobrien * All rights reserved. 5179161Sobrien * 6179161Sobrien * Redistribution and use in source and binary forms, with or without 7179161Sobrien * modification, are permitted provided that the following conditions 8179161Sobrien * are met: 9179161Sobrien * 10179161Sobrien * 1. Redistributions of source code must retain the above copyright 11179161Sobrien * notice, this list of conditions and the following disclaimer. 12179161Sobrien * 2. Redistributions in binary form must reproduce the above copyright 13179161Sobrien * notice, this list of conditions and the following disclaimer in the 14179161Sobrien * documentation and/or other materials provided with the distribution. 15179161Sobrien * 16179161Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 17179161Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18179161Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19179161Sobrien * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20179161Sobrien * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21179161Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22179161Sobrien * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23179161Sobrien * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24179161Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25179161Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26179161Sobrien * 27179161Sobrien * from: src/gnu/usr.bin/gdb/kgdb/trgt_alpha.c,v 1.2.2.1 2005/09/15 05:32:10 marcel 28179161Sobrien */ 29179161Sobrien 30179161Sobrien#include <sys/cdefs.h> 31179161Sobrien__FBSDID("$FreeBSD$"); 32179161Sobrien 33179161Sobrien#include <sys/types.h> 34179161Sobrien#include <machine/asm.h> 35179161Sobrien#include <machine/pcb.h> 36179161Sobrien#include <machine/frame.h> 37179161Sobrien#include <err.h> 38179161Sobrien#include <kvm.h> 39179161Sobrien#include <string.h> 40179161Sobrien 41179161Sobrien#include <defs.h> 42179161Sobrien#include <target.h> 43179161Sobrien#include <gdbthread.h> 44179161Sobrien#include <inferior.h> 45179161Sobrien#include <regcache.h> 46179161Sobrien#include <frame-unwind.h> 47179161Sobrien#include <mips-tdep.h> 48179161Sobrien 49214962Sgonzo#ifndef CROSS_DEBUGGER 50214952Sgonzo#include <machine/pcb.h> 51214962Sgonzo#endif 52214952Sgonzo 53179161Sobrien#include "kgdb.h" 54179161Sobrien 55246893SmarcelCORE_ADDR 56246893Smarcelkgdb_trgt_core_pcb(u_int cpuid) 57246893Smarcel{ 58246893Smarcel return (kgdb_trgt_stop_pcb(cpuid, sizeof(struct pcb))); 59246893Smarcel} 60246893Smarcel 61179161Sobrienvoid 62179161Sobrienkgdb_trgt_fetch_registers(int regno __unused) 63179161Sobrien{ 64214962Sgonzo#ifndef CROSS_DEBUGGER 65179161Sobrien struct kthr *kt; 66179161Sobrien struct pcb pcb; 67179161Sobrien 68179859Sjhb kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); 69179161Sobrien if (kt == NULL) 70179161Sobrien return; 71179161Sobrien if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { 72179161Sobrien warnx("kvm_read: %s", kvm_geterr(kvm)); 73179161Sobrien memset(&pcb, 0, sizeof(pcb)); 74179161Sobrien } 75214952Sgonzo 76214952Sgonzo supply_register(MIPS_S0_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S0]); 77214952Sgonzo supply_register(MIPS_S1_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S1]); 78214952Sgonzo supply_register(MIPS_S2_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S2]); 79214952Sgonzo supply_register(MIPS_S3_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S3]); 80214952Sgonzo supply_register(MIPS_S4_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S4]); 81214952Sgonzo supply_register(MIPS_S5_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S5]); 82214952Sgonzo supply_register(MIPS_S6_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S6]); 83214952Sgonzo supply_register(MIPS_S7_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S7]); 84214952Sgonzo supply_register(MIPS_SP_REGNUM, (char *)&pcb.pcb_context[PCB_REG_SP]); 85214952Sgonzo supply_register(MIPS_FP_REGNUM, (char *)&pcb.pcb_context[PCB_REG_GP]); 86214952Sgonzo supply_register(MIPS_RA_REGNUM, (char *)&pcb.pcb_context[PCB_REG_RA]); 87214952Sgonzo supply_register(MIPS_EMBED_PC_REGNUM, (char *)&pcb.pcb_context[PCB_REG_PC]); 88214962Sgonzo#endif 89179161Sobrien} 90179161Sobrien 91179161Sobrienvoid 92179161Sobrienkgdb_trgt_store_registers(int regno __unused) 93179161Sobrien{ 94179161Sobrien 95214952Sgonzo fprintf_unfiltered(gdb_stderr, "Unimplemented function: %s\n", __func__); 96179161Sobrien} 97179161Sobrien 98179859Sjhbvoid 99179859Sjhbkgdb_trgt_new_objfile(struct objfile *objfile) 100179859Sjhb{ 101179859Sjhb} 102179859Sjhb 103214962Sgonzo#ifndef CROSS_DEBUGGER 104179161Sobrienstruct kgdb_frame_cache { 105179161Sobrien CORE_ADDR pc; 106179161Sobrien CORE_ADDR sp; 107179161Sobrien}; 108179161Sobrien 109179161Sobrienstatic int kgdb_trgt_frame_offset[] = { 110179161Sobrien offsetof(struct trapframe, zero), 111179161Sobrien offsetof(struct trapframe, ast), 112179161Sobrien offsetof(struct trapframe, v0), 113179161Sobrien offsetof(struct trapframe, v1), 114179161Sobrien offsetof(struct trapframe, a0), 115179161Sobrien offsetof(struct trapframe, a1), 116179161Sobrien offsetof(struct trapframe, a2), 117179161Sobrien offsetof(struct trapframe, a3), 118249878Simp#if defined(__mips_n32) || defined(__mips_n64) 119249878Simp offsetof(struct trapframe, a4), 120249878Simp offsetof(struct trapframe, a5), 121249878Simp offsetof(struct trapframe, a6), 122249878Simp offsetof(struct trapframe, a7), 123179161Sobrien offsetof(struct trapframe, t0), 124179161Sobrien offsetof(struct trapframe, t1), 125179161Sobrien offsetof(struct trapframe, t2), 126179161Sobrien offsetof(struct trapframe, t3), 127249878Simp#else 128249878Simp offsetof(struct trapframe, t0), 129249878Simp offsetof(struct trapframe, t1), 130249878Simp offsetof(struct trapframe, t2), 131249878Simp offsetof(struct trapframe, t3), 132179161Sobrien offsetof(struct trapframe, t4), 133179161Sobrien offsetof(struct trapframe, t5), 134179161Sobrien offsetof(struct trapframe, t6), 135179161Sobrien offsetof(struct trapframe, t7), 136249878Simp#endif 137179161Sobrien offsetof(struct trapframe, s0), 138179161Sobrien offsetof(struct trapframe, s1), 139179161Sobrien offsetof(struct trapframe, s2), 140179161Sobrien offsetof(struct trapframe, s3), 141179161Sobrien offsetof(struct trapframe, s4), 142179161Sobrien offsetof(struct trapframe, s5), 143179161Sobrien offsetof(struct trapframe, s6), 144179161Sobrien offsetof(struct trapframe, s7), 145179161Sobrien offsetof(struct trapframe, t8), 146179161Sobrien offsetof(struct trapframe, t9), 147179161Sobrien offsetof(struct trapframe, k0), 148179161Sobrien offsetof(struct trapframe, k1), 149179161Sobrien offsetof(struct trapframe, gp), 150179161Sobrien offsetof(struct trapframe, sp), 151179161Sobrien offsetof(struct trapframe, s8), 152179161Sobrien offsetof(struct trapframe, ra), 153179161Sobrien}; 154179161Sobrien 155179161Sobrienstatic struct kgdb_frame_cache * 156214952Sgonzokgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) 157179161Sobrien{ 158179161Sobrien char buf[MAX_REGISTER_SIZE]; 159179161Sobrien struct kgdb_frame_cache *cache; 160179161Sobrien 161179161Sobrien cache = *this_cache; 162179161Sobrien if (cache == NULL) { 163179161Sobrien cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); 164179161Sobrien *this_cache = cache; 165179161Sobrien cache->pc = frame_func_unwind(next_frame); 166179161Sobrien frame_unwind_register(next_frame, SP_REGNUM, buf); 167179161Sobrien cache->sp = extract_unsigned_integer(buf, 168179161Sobrien register_size(current_gdbarch, SP_REGNUM)); 169179161Sobrien } 170179161Sobrien return (cache); 171179161Sobrien} 172179161Sobrien 173179161Sobrienstatic void 174179161Sobrienkgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, 175179161Sobrien struct frame_id *this_id) 176179161Sobrien{ 177179161Sobrien struct kgdb_frame_cache *cache; 178179161Sobrien 179179161Sobrien cache = kgdb_trgt_frame_cache(next_frame, this_cache); 180179161Sobrien *this_id = frame_id_build(cache->sp, cache->pc); 181179161Sobrien} 182179161Sobrien 183179161Sobrienstatic void 184179161Sobrienkgdb_trgt_trapframe_prev_register(struct frame_info *next_frame __unused, 185179161Sobrien void **this_cache __unused, int regnum __unused, int *optimizedp __unused, 186179161Sobrien enum lval_type *lvalp __unused, CORE_ADDR *addrp __unused, 187179161Sobrien int *realnump __unused, void *valuep __unused) 188179161Sobrien{ 189179161Sobrien char dummy_valuep[MAX_REGISTER_SIZE]; 190179161Sobrien struct kgdb_frame_cache *cache; 191179161Sobrien int ofs, regsz; 192179161Sobrien 193179161Sobrien regsz = register_size(current_gdbarch, regnum); 194179161Sobrien 195179161Sobrien if (valuep == NULL) 196179161Sobrien valuep = dummy_valuep; 197179161Sobrien memset(valuep, 0, regsz); 198179161Sobrien *optimizedp = 0; 199179161Sobrien *addrp = 0; 200179161Sobrien *lvalp = not_lval; 201179161Sobrien *realnump = -1; 202179161Sobrien 203179161Sobrien ofs = (regnum >= 0 && regnum <= MIPS_RA_REGNUM) ? 204179161Sobrien kgdb_trgt_frame_offset[regnum] : -1; 205179161Sobrien if (ofs == -1) 206179161Sobrien return; 207179161Sobrien 208179161Sobrien cache = kgdb_trgt_frame_cache(next_frame, this_cache); 209179161Sobrien *addrp = cache->sp + ofs * 8; 210179161Sobrien *lvalp = lval_memory; 211179161Sobrien target_read_memory(*addrp, valuep, regsz); 212179161Sobrien} 213179161Sobrien 214179161Sobrienstatic const struct frame_unwind kgdb_trgt_trapframe_unwind = { 215179161Sobrien UNKNOWN_FRAME, 216179161Sobrien &kgdb_trgt_trapframe_this_id, 217179161Sobrien &kgdb_trgt_trapframe_prev_register 218179161Sobrien}; 219214962Sgonzo#endif 220179161Sobrien 221179161Sobrienconst struct frame_unwind * 222214952Sgonzokgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) 223179161Sobrien{ 224214962Sgonzo#ifndef CROSS_DEBUGGER 225179161Sobrien char *pname; 226179161Sobrien CORE_ADDR pc; 227179161Sobrien 228179161Sobrien pc = frame_pc_unwind(next_frame); 229179161Sobrien pname = NULL; 230179161Sobrien find_pc_partial_function(pc, &pname, NULL, NULL); 231179161Sobrien if (pname == NULL) 232179161Sobrien return (NULL); 233179161Sobrien if ((strcmp(pname, "MipsKernIntr") == 0) || 234179161Sobrien (strcmp(pname, "MipsKernGenException") == 0) || 235179161Sobrien (strcmp(pname, "MipsUserIntr") == 0) || 236179161Sobrien (strcmp(pname, "MipsUserGenException") == 0)) 237179161Sobrien return (&kgdb_trgt_trapframe_unwind); 238214962Sgonzo#endif 239179161Sobrien return (NULL); 240179161Sobrien} 241298363Swma 242298363Swma/* 243298363Swma * This function ensures, that the PC is inside the 244298363Swma * function section which is understood by GDB. 245298363Swma * 246298363Swma * Return 0 when fixup is necessary, -1 otherwise. 247298363Swma */ 248298363Swmaint 249298363Swmakgdb_trgt_pc_fixup(CORE_ADDR *pc __unused) 250298363Swma{ 251298363Swma 252298363Swma return (-1); 253298363Swma} 254