trgt_mips.c revision 179859
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 179859 2008-06-18 14:23:28Z jhb $"); 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 49179161Sobrien#include "kgdb.h" 50179161Sobrien 51179161Sobrienvoid 52179161Sobrienkgdb_trgt_fetch_registers(int regno __unused) 53179161Sobrien{ 54179161Sobrien struct kthr *kt; 55179161Sobrien struct pcb pcb; 56179161Sobrien 57179859Sjhb kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); 58179161Sobrien if (kt == NULL) 59179161Sobrien return; 60179161Sobrien if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { 61179161Sobrien warnx("kvm_read: %s", kvm_geterr(kvm)); 62179161Sobrien memset(&pcb, 0, sizeof(pcb)); 63179161Sobrien } 64179161Sobrien supply_register(MIPS_S0_REGNUM, (char *)&pcb.pcb_context.val[0]); 65179161Sobrien supply_register(MIPS_S1_REGNUM, (char *)&pcb.pcb_context.val[1]); 66179161Sobrien supply_register(MIPS_S2_REGNUM, (char *)&pcb.pcb_context.val[2]); 67179161Sobrien supply_register(MIPS_S3_REGNUM, (char *)&pcb.pcb_context.val[3]); 68179161Sobrien supply_register(MIPS_S4_REGNUM, (char *)&pcb.pcb_context.val[4]); 69179161Sobrien supply_register(MIPS_S5_REGNUM, (char *)&pcb.pcb_context.val[5]); 70179161Sobrien supply_register(MIPS_S6_REGNUM, (char *)&pcb.pcb_context.val[6]); 71179161Sobrien supply_register(MIPS_S7_REGNUM, (char *)&pcb.pcb_context.val[7]); 72179161Sobrien supply_register(MIPS_SP_REGNUM, (char *)&pcb.pcb_context.val[8]); 73179161Sobrien supply_register(MIPS_SP_REGNUM, (char *)&pcb.pcb_context.val[8]); 74179161Sobrien supply_register(MIPS_FP_REGNUM, (char *)&pcb.pcb_context.val[9]); 75179161Sobrien supply_register(MIPS_RA_REGNUM, (char *)&pcb.pcb_context.val[10]); 76179161Sobrien} 77179161Sobrien 78179161Sobrienvoid 79179161Sobrienkgdb_trgt_store_registers(int regno __unused) 80179161Sobrien{ 81179161Sobrien 82179161Sobrien fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); 83179161Sobrien} 84179161Sobrien 85179859Sjhbvoid 86179859Sjhbkgdb_trgt_new_objfile(struct objfile *objfile) 87179859Sjhb{ 88179859Sjhb} 89179859Sjhb 90179161Sobrienstruct kgdb_frame_cache { 91179161Sobrien CORE_ADDR pc; 92179161Sobrien CORE_ADDR sp; 93179161Sobrien}; 94179161Sobrien 95179161Sobrienstatic int kgdb_trgt_frame_offset[] = { 96179161Sobrien offsetof(struct trapframe, zero), 97179161Sobrien offsetof(struct trapframe, ast), 98179161Sobrien offsetof(struct trapframe, v0), 99179161Sobrien offsetof(struct trapframe, v1), 100179161Sobrien offsetof(struct trapframe, a0), 101179161Sobrien offsetof(struct trapframe, a1), 102179161Sobrien offsetof(struct trapframe, a2), 103179161Sobrien offsetof(struct trapframe, a3), 104179161Sobrien offsetof(struct trapframe, t0), 105179161Sobrien offsetof(struct trapframe, t1), 106179161Sobrien offsetof(struct trapframe, t2), 107179161Sobrien offsetof(struct trapframe, t3), 108179161Sobrien offsetof(struct trapframe, t4), 109179161Sobrien offsetof(struct trapframe, t5), 110179161Sobrien offsetof(struct trapframe, t6), 111179161Sobrien offsetof(struct trapframe, t7), 112179161Sobrien offsetof(struct trapframe, s0), 113179161Sobrien offsetof(struct trapframe, s1), 114179161Sobrien offsetof(struct trapframe, s2), 115179161Sobrien offsetof(struct trapframe, s3), 116179161Sobrien offsetof(struct trapframe, s4), 117179161Sobrien offsetof(struct trapframe, s5), 118179161Sobrien offsetof(struct trapframe, s6), 119179161Sobrien offsetof(struct trapframe, s7), 120179161Sobrien offsetof(struct trapframe, t8), 121179161Sobrien offsetof(struct trapframe, t9), 122179161Sobrien offsetof(struct trapframe, k0), 123179161Sobrien offsetof(struct trapframe, k1), 124179161Sobrien offsetof(struct trapframe, gp), 125179161Sobrien offsetof(struct trapframe, sp), 126179161Sobrien offsetof(struct trapframe, s8), 127179161Sobrien offsetof(struct trapframe, ra), 128179161Sobrien}; 129179161Sobrien 130179161Sobrienstatic struct kgdb_frame_cache * 131179161Sobrienkgdb_trgt_frame_cache(struct frame_info *next_frame __unused, void **this_cache __unused) 132179161Sobrien{ 133179161Sobrien char buf[MAX_REGISTER_SIZE]; 134179161Sobrien struct kgdb_frame_cache *cache; 135179161Sobrien 136179161Sobrien cache = *this_cache; 137179161Sobrien if (cache == NULL) { 138179161Sobrien cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); 139179161Sobrien *this_cache = cache; 140179161Sobrien cache->pc = frame_func_unwind(next_frame); 141179161Sobrien frame_unwind_register(next_frame, SP_REGNUM, buf); 142179161Sobrien cache->sp = extract_unsigned_integer(buf, 143179161Sobrien register_size(current_gdbarch, SP_REGNUM)); 144179161Sobrien } 145179161Sobrien return (cache); 146179161Sobrien} 147179161Sobrien 148179161Sobrienstatic void 149179161Sobrienkgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, 150179161Sobrien struct frame_id *this_id) 151179161Sobrien{ 152179161Sobrien struct kgdb_frame_cache *cache; 153179161Sobrien 154179161Sobrien cache = kgdb_trgt_frame_cache(next_frame, this_cache); 155179161Sobrien *this_id = frame_id_build(cache->sp, cache->pc); 156179161Sobrien} 157179161Sobrien 158179161Sobrienstatic void 159179161Sobrienkgdb_trgt_trapframe_prev_register(struct frame_info *next_frame __unused, 160179161Sobrien void **this_cache __unused, int regnum __unused, int *optimizedp __unused, 161179161Sobrien enum lval_type *lvalp __unused, CORE_ADDR *addrp __unused, 162179161Sobrien int *realnump __unused, void *valuep __unused) 163179161Sobrien{ 164179161Sobrien char dummy_valuep[MAX_REGISTER_SIZE]; 165179161Sobrien struct kgdb_frame_cache *cache; 166179161Sobrien int ofs, regsz; 167179161Sobrien 168179161Sobrien regsz = register_size(current_gdbarch, regnum); 169179161Sobrien 170179161Sobrien if (valuep == NULL) 171179161Sobrien valuep = dummy_valuep; 172179161Sobrien memset(valuep, 0, regsz); 173179161Sobrien *optimizedp = 0; 174179161Sobrien *addrp = 0; 175179161Sobrien *lvalp = not_lval; 176179161Sobrien *realnump = -1; 177179161Sobrien 178179161Sobrien ofs = (regnum >= 0 && regnum <= MIPS_RA_REGNUM) ? 179179161Sobrien kgdb_trgt_frame_offset[regnum] : -1; 180179161Sobrien if (ofs == -1) 181179161Sobrien return; 182179161Sobrien 183179161Sobrien cache = kgdb_trgt_frame_cache(next_frame, this_cache); 184179161Sobrien *addrp = cache->sp + ofs * 8; 185179161Sobrien *lvalp = lval_memory; 186179161Sobrien target_read_memory(*addrp, valuep, regsz); 187179161Sobrien} 188179161Sobrien 189179161Sobrienstatic const struct frame_unwind kgdb_trgt_trapframe_unwind = { 190179161Sobrien UNKNOWN_FRAME, 191179161Sobrien &kgdb_trgt_trapframe_this_id, 192179161Sobrien &kgdb_trgt_trapframe_prev_register 193179161Sobrien}; 194179161Sobrien 195179161Sobrienconst struct frame_unwind * 196179161Sobrienkgdb_trgt_trapframe_sniffer(struct frame_info *next_frame __unused) 197179161Sobrien{ 198179161Sobrien char *pname; 199179161Sobrien CORE_ADDR pc; 200179161Sobrien 201179161Sobrien pc = frame_pc_unwind(next_frame); 202179161Sobrien pname = NULL; 203179161Sobrien find_pc_partial_function(pc, &pname, NULL, NULL); 204179161Sobrien if (pname == NULL) 205179161Sobrien return (NULL); 206179161Sobrien if ((strcmp(pname, "MipsKernIntr") == 0) || 207179161Sobrien (strcmp(pname, "MipsKernGenException") == 0) || 208179161Sobrien (strcmp(pname, "MipsUserIntr") == 0) || 209179161Sobrien (strcmp(pname, "MipsUserGenException") == 0)) 210179161Sobrien return (&kgdb_trgt_trapframe_unwind); 211179161Sobrien /* printf("%s: %llx =%s\n", __func__, pc, pname); */ 212179161Sobrien return (NULL); 213179161Sobrien} 214