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 55179161Sobrienvoid 56179161Sobrienkgdb_trgt_fetch_registers(int regno __unused) 57179161Sobrien{ 58214962Sgonzo#ifndef CROSS_DEBUGGER 59179161Sobrien struct kthr *kt; 60179161Sobrien struct pcb pcb; 61179161Sobrien 62179859Sjhb kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); 63179161Sobrien if (kt == NULL) 64179161Sobrien return; 65179161Sobrien if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { 66179161Sobrien warnx("kvm_read: %s", kvm_geterr(kvm)); 67179161Sobrien memset(&pcb, 0, sizeof(pcb)); 68179161Sobrien } 69214952Sgonzo 70214952Sgonzo supply_register(MIPS_S0_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S0]); 71214952Sgonzo supply_register(MIPS_S1_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S1]); 72214952Sgonzo supply_register(MIPS_S2_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S2]); 73214952Sgonzo supply_register(MIPS_S3_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S3]); 74214952Sgonzo supply_register(MIPS_S4_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S4]); 75214952Sgonzo supply_register(MIPS_S5_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S5]); 76214952Sgonzo supply_register(MIPS_S6_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S6]); 77214952Sgonzo supply_register(MIPS_S7_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S7]); 78214952Sgonzo supply_register(MIPS_SP_REGNUM, (char *)&pcb.pcb_context[PCB_REG_SP]); 79214952Sgonzo supply_register(MIPS_FP_REGNUM, (char *)&pcb.pcb_context[PCB_REG_GP]); 80214952Sgonzo supply_register(MIPS_RA_REGNUM, (char *)&pcb.pcb_context[PCB_REG_RA]); 81214952Sgonzo supply_register(MIPS_EMBED_PC_REGNUM, (char *)&pcb.pcb_context[PCB_REG_PC]); 82214962Sgonzo#endif 83179161Sobrien} 84179161Sobrien 85179161Sobrienvoid 86179161Sobrienkgdb_trgt_store_registers(int regno __unused) 87179161Sobrien{ 88179161Sobrien 89214952Sgonzo fprintf_unfiltered(gdb_stderr, "Unimplemented function: %s\n", __func__); 90179161Sobrien} 91179161Sobrien 92179859Sjhbvoid 93179859Sjhbkgdb_trgt_new_objfile(struct objfile *objfile) 94179859Sjhb{ 95179859Sjhb} 96179859Sjhb 97214962Sgonzo#ifndef CROSS_DEBUGGER 98179161Sobrienstruct kgdb_frame_cache { 99179161Sobrien CORE_ADDR pc; 100179161Sobrien CORE_ADDR sp; 101179161Sobrien}; 102179161Sobrien 103179161Sobrienstatic int kgdb_trgt_frame_offset[] = { 104179161Sobrien offsetof(struct trapframe, zero), 105179161Sobrien offsetof(struct trapframe, ast), 106179161Sobrien offsetof(struct trapframe, v0), 107179161Sobrien offsetof(struct trapframe, v1), 108179161Sobrien offsetof(struct trapframe, a0), 109179161Sobrien offsetof(struct trapframe, a1), 110179161Sobrien offsetof(struct trapframe, a2), 111179161Sobrien offsetof(struct trapframe, a3), 112179161Sobrien offsetof(struct trapframe, t0), 113179161Sobrien offsetof(struct trapframe, t1), 114179161Sobrien offsetof(struct trapframe, t2), 115179161Sobrien offsetof(struct trapframe, t3), 116179161Sobrien offsetof(struct trapframe, t4), 117179161Sobrien offsetof(struct trapframe, t5), 118179161Sobrien offsetof(struct trapframe, t6), 119179161Sobrien offsetof(struct trapframe, t7), 120179161Sobrien offsetof(struct trapframe, s0), 121179161Sobrien offsetof(struct trapframe, s1), 122179161Sobrien offsetof(struct trapframe, s2), 123179161Sobrien offsetof(struct trapframe, s3), 124179161Sobrien offsetof(struct trapframe, s4), 125179161Sobrien offsetof(struct trapframe, s5), 126179161Sobrien offsetof(struct trapframe, s6), 127179161Sobrien offsetof(struct trapframe, s7), 128179161Sobrien offsetof(struct trapframe, t8), 129179161Sobrien offsetof(struct trapframe, t9), 130179161Sobrien offsetof(struct trapframe, k0), 131179161Sobrien offsetof(struct trapframe, k1), 132179161Sobrien offsetof(struct trapframe, gp), 133179161Sobrien offsetof(struct trapframe, sp), 134179161Sobrien offsetof(struct trapframe, s8), 135179161Sobrien offsetof(struct trapframe, ra), 136179161Sobrien}; 137179161Sobrien 138179161Sobrienstatic struct kgdb_frame_cache * 139214952Sgonzokgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) 140179161Sobrien{ 141179161Sobrien char buf[MAX_REGISTER_SIZE]; 142179161Sobrien struct kgdb_frame_cache *cache; 143179161Sobrien 144179161Sobrien cache = *this_cache; 145179161Sobrien if (cache == NULL) { 146179161Sobrien cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); 147179161Sobrien *this_cache = cache; 148179161Sobrien cache->pc = frame_func_unwind(next_frame); 149179161Sobrien frame_unwind_register(next_frame, SP_REGNUM, buf); 150179161Sobrien cache->sp = extract_unsigned_integer(buf, 151179161Sobrien register_size(current_gdbarch, SP_REGNUM)); 152179161Sobrien } 153179161Sobrien return (cache); 154179161Sobrien} 155179161Sobrien 156179161Sobrienstatic void 157179161Sobrienkgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, 158179161Sobrien struct frame_id *this_id) 159179161Sobrien{ 160179161Sobrien struct kgdb_frame_cache *cache; 161179161Sobrien 162179161Sobrien cache = kgdb_trgt_frame_cache(next_frame, this_cache); 163179161Sobrien *this_id = frame_id_build(cache->sp, cache->pc); 164179161Sobrien} 165179161Sobrien 166179161Sobrienstatic void 167179161Sobrienkgdb_trgt_trapframe_prev_register(struct frame_info *next_frame __unused, 168179161Sobrien void **this_cache __unused, int regnum __unused, int *optimizedp __unused, 169179161Sobrien enum lval_type *lvalp __unused, CORE_ADDR *addrp __unused, 170179161Sobrien int *realnump __unused, void *valuep __unused) 171179161Sobrien{ 172179161Sobrien char dummy_valuep[MAX_REGISTER_SIZE]; 173179161Sobrien struct kgdb_frame_cache *cache; 174179161Sobrien int ofs, regsz; 175179161Sobrien 176179161Sobrien regsz = register_size(current_gdbarch, regnum); 177179161Sobrien 178179161Sobrien if (valuep == NULL) 179179161Sobrien valuep = dummy_valuep; 180179161Sobrien memset(valuep, 0, regsz); 181179161Sobrien *optimizedp = 0; 182179161Sobrien *addrp = 0; 183179161Sobrien *lvalp = not_lval; 184179161Sobrien *realnump = -1; 185179161Sobrien 186179161Sobrien ofs = (regnum >= 0 && regnum <= MIPS_RA_REGNUM) ? 187179161Sobrien kgdb_trgt_frame_offset[regnum] : -1; 188179161Sobrien if (ofs == -1) 189179161Sobrien return; 190179161Sobrien 191179161Sobrien cache = kgdb_trgt_frame_cache(next_frame, this_cache); 192179161Sobrien *addrp = cache->sp + ofs * 8; 193179161Sobrien *lvalp = lval_memory; 194179161Sobrien target_read_memory(*addrp, valuep, regsz); 195179161Sobrien} 196179161Sobrien 197179161Sobrienstatic const struct frame_unwind kgdb_trgt_trapframe_unwind = { 198179161Sobrien UNKNOWN_FRAME, 199179161Sobrien &kgdb_trgt_trapframe_this_id, 200179161Sobrien &kgdb_trgt_trapframe_prev_register 201179161Sobrien}; 202214962Sgonzo#endif 203179161Sobrien 204179161Sobrienconst struct frame_unwind * 205214952Sgonzokgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) 206179161Sobrien{ 207214962Sgonzo#ifndef CROSS_DEBUGGER 208179161Sobrien char *pname; 209179161Sobrien CORE_ADDR pc; 210179161Sobrien 211179161Sobrien pc = frame_pc_unwind(next_frame); 212179161Sobrien pname = NULL; 213179161Sobrien find_pc_partial_function(pc, &pname, NULL, NULL); 214179161Sobrien if (pname == NULL) 215179161Sobrien return (NULL); 216179161Sobrien if ((strcmp(pname, "MipsKernIntr") == 0) || 217179161Sobrien (strcmp(pname, "MipsKernGenException") == 0) || 218179161Sobrien (strcmp(pname, "MipsUserIntr") == 0) || 219179161Sobrien (strcmp(pname, "MipsUserGenException") == 0)) 220179161Sobrien return (&kgdb_trgt_trapframe_unwind); 221214962Sgonzo#endif 222179161Sobrien return (NULL); 223179161Sobrien} 224