trgt_mips.c revision 214952
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: head/gnu/usr.bin/gdb/kgdb/trgt_mips.c 214952 2010-11-07 20:56:41Z gonzo $"); 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 49214952Sgonzo#include <machine/pcb.h> 50214952Sgonzo 51179161Sobrien#include "kgdb.h" 52179161Sobrien 53179161Sobrienvoid 54179161Sobrienkgdb_trgt_fetch_registers(int regno __unused) 55179161Sobrien{ 56179161Sobrien struct kthr *kt; 57179161Sobrien struct pcb pcb; 58179161Sobrien 59179859Sjhb kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); 60179161Sobrien if (kt == NULL) 61179161Sobrien return; 62179161Sobrien if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { 63179161Sobrien warnx("kvm_read: %s", kvm_geterr(kvm)); 64179161Sobrien memset(&pcb, 0, sizeof(pcb)); 65179161Sobrien } 66214952Sgonzo 67214952Sgonzo supply_register(MIPS_S0_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S0]); 68214952Sgonzo supply_register(MIPS_S1_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S1]); 69214952Sgonzo supply_register(MIPS_S2_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S2]); 70214952Sgonzo supply_register(MIPS_S3_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S3]); 71214952Sgonzo supply_register(MIPS_S4_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S4]); 72214952Sgonzo supply_register(MIPS_S5_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S5]); 73214952Sgonzo supply_register(MIPS_S6_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S6]); 74214952Sgonzo supply_register(MIPS_S7_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S7]); 75214952Sgonzo supply_register(MIPS_SP_REGNUM, (char *)&pcb.pcb_context[PCB_REG_SP]); 76214952Sgonzo supply_register(MIPS_FP_REGNUM, (char *)&pcb.pcb_context[PCB_REG_GP]); 77214952Sgonzo supply_register(MIPS_RA_REGNUM, (char *)&pcb.pcb_context[PCB_REG_RA]); 78214952Sgonzo supply_register(MIPS_EMBED_PC_REGNUM, (char *)&pcb.pcb_context[PCB_REG_PC]); 79179161Sobrien} 80179161Sobrien 81179161Sobrienvoid 82179161Sobrienkgdb_trgt_store_registers(int regno __unused) 83179161Sobrien{ 84179161Sobrien 85214952Sgonzo fprintf_unfiltered(gdb_stderr, "Unimplemented function: %s\n", __func__); 86179161Sobrien} 87179161Sobrien 88179859Sjhbvoid 89179859Sjhbkgdb_trgt_new_objfile(struct objfile *objfile) 90179859Sjhb{ 91179859Sjhb} 92179859Sjhb 93179161Sobrienstruct kgdb_frame_cache { 94179161Sobrien CORE_ADDR pc; 95179161Sobrien CORE_ADDR sp; 96179161Sobrien}; 97179161Sobrien 98179161Sobrienstatic int kgdb_trgt_frame_offset[] = { 99179161Sobrien offsetof(struct trapframe, zero), 100179161Sobrien offsetof(struct trapframe, ast), 101179161Sobrien offsetof(struct trapframe, v0), 102179161Sobrien offsetof(struct trapframe, v1), 103179161Sobrien offsetof(struct trapframe, a0), 104179161Sobrien offsetof(struct trapframe, a1), 105179161Sobrien offsetof(struct trapframe, a2), 106179161Sobrien offsetof(struct trapframe, a3), 107179161Sobrien offsetof(struct trapframe, t0), 108179161Sobrien offsetof(struct trapframe, t1), 109179161Sobrien offsetof(struct trapframe, t2), 110179161Sobrien offsetof(struct trapframe, t3), 111179161Sobrien offsetof(struct trapframe, t4), 112179161Sobrien offsetof(struct trapframe, t5), 113179161Sobrien offsetof(struct trapframe, t6), 114179161Sobrien offsetof(struct trapframe, t7), 115179161Sobrien offsetof(struct trapframe, s0), 116179161Sobrien offsetof(struct trapframe, s1), 117179161Sobrien offsetof(struct trapframe, s2), 118179161Sobrien offsetof(struct trapframe, s3), 119179161Sobrien offsetof(struct trapframe, s4), 120179161Sobrien offsetof(struct trapframe, s5), 121179161Sobrien offsetof(struct trapframe, s6), 122179161Sobrien offsetof(struct trapframe, s7), 123179161Sobrien offsetof(struct trapframe, t8), 124179161Sobrien offsetof(struct trapframe, t9), 125179161Sobrien offsetof(struct trapframe, k0), 126179161Sobrien offsetof(struct trapframe, k1), 127179161Sobrien offsetof(struct trapframe, gp), 128179161Sobrien offsetof(struct trapframe, sp), 129179161Sobrien offsetof(struct trapframe, s8), 130179161Sobrien offsetof(struct trapframe, ra), 131179161Sobrien}; 132179161Sobrien 133179161Sobrienstatic struct kgdb_frame_cache * 134214952Sgonzokgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) 135179161Sobrien{ 136179161Sobrien char buf[MAX_REGISTER_SIZE]; 137179161Sobrien struct kgdb_frame_cache *cache; 138179161Sobrien 139179161Sobrien cache = *this_cache; 140179161Sobrien if (cache == NULL) { 141179161Sobrien cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); 142179161Sobrien *this_cache = cache; 143179161Sobrien cache->pc = frame_func_unwind(next_frame); 144179161Sobrien frame_unwind_register(next_frame, SP_REGNUM, buf); 145179161Sobrien cache->sp = extract_unsigned_integer(buf, 146179161Sobrien register_size(current_gdbarch, SP_REGNUM)); 147179161Sobrien } 148179161Sobrien return (cache); 149179161Sobrien} 150179161Sobrien 151179161Sobrienstatic void 152179161Sobrienkgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, 153179161Sobrien struct frame_id *this_id) 154179161Sobrien{ 155179161Sobrien struct kgdb_frame_cache *cache; 156179161Sobrien 157179161Sobrien cache = kgdb_trgt_frame_cache(next_frame, this_cache); 158179161Sobrien *this_id = frame_id_build(cache->sp, cache->pc); 159179161Sobrien} 160179161Sobrien 161179161Sobrienstatic void 162179161Sobrienkgdb_trgt_trapframe_prev_register(struct frame_info *next_frame __unused, 163179161Sobrien void **this_cache __unused, int regnum __unused, int *optimizedp __unused, 164179161Sobrien enum lval_type *lvalp __unused, CORE_ADDR *addrp __unused, 165179161Sobrien int *realnump __unused, void *valuep __unused) 166179161Sobrien{ 167179161Sobrien char dummy_valuep[MAX_REGISTER_SIZE]; 168179161Sobrien struct kgdb_frame_cache *cache; 169179161Sobrien int ofs, regsz; 170179161Sobrien 171179161Sobrien regsz = register_size(current_gdbarch, regnum); 172179161Sobrien 173179161Sobrien if (valuep == NULL) 174179161Sobrien valuep = dummy_valuep; 175179161Sobrien memset(valuep, 0, regsz); 176179161Sobrien *optimizedp = 0; 177179161Sobrien *addrp = 0; 178179161Sobrien *lvalp = not_lval; 179179161Sobrien *realnump = -1; 180179161Sobrien 181179161Sobrien ofs = (regnum >= 0 && regnum <= MIPS_RA_REGNUM) ? 182179161Sobrien kgdb_trgt_frame_offset[regnum] : -1; 183179161Sobrien if (ofs == -1) 184179161Sobrien return; 185179161Sobrien 186179161Sobrien cache = kgdb_trgt_frame_cache(next_frame, this_cache); 187179161Sobrien *addrp = cache->sp + ofs * 8; 188179161Sobrien *lvalp = lval_memory; 189179161Sobrien target_read_memory(*addrp, valuep, regsz); 190179161Sobrien} 191179161Sobrien 192179161Sobrienstatic const struct frame_unwind kgdb_trgt_trapframe_unwind = { 193179161Sobrien UNKNOWN_FRAME, 194179161Sobrien &kgdb_trgt_trapframe_this_id, 195179161Sobrien &kgdb_trgt_trapframe_prev_register 196179161Sobrien}; 197179161Sobrien 198179161Sobrienconst struct frame_unwind * 199214952Sgonzokgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) 200179161Sobrien{ 201179161Sobrien char *pname; 202179161Sobrien CORE_ADDR pc; 203179161Sobrien 204179161Sobrien pc = frame_pc_unwind(next_frame); 205179161Sobrien pname = NULL; 206179161Sobrien find_pc_partial_function(pc, &pname, NULL, NULL); 207179161Sobrien if (pname == NULL) 208179161Sobrien return (NULL); 209179161Sobrien if ((strcmp(pname, "MipsKernIntr") == 0) || 210179161Sobrien (strcmp(pname, "MipsKernGenException") == 0) || 211179161Sobrien (strcmp(pname, "MipsUserIntr") == 0) || 212179161Sobrien (strcmp(pname, "MipsUserGenException") == 0)) 213179161Sobrien return (&kgdb_trgt_trapframe_unwind); 214179161Sobrien return (NULL); 215179161Sobrien} 216