trgt_mips.c revision 179162
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 179162 2008-05-20 22:58:47Z obrien $"); 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 57179161Sobrien kt = kgdb_thr_lookup_tid(ptid_get_tid(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 85179161Sobrienstruct kgdb_frame_cache { 86179161Sobrien CORE_ADDR pc; 87179161Sobrien CORE_ADDR sp; 88179161Sobrien}; 89179161Sobrien 90179161Sobrienstatic int kgdb_trgt_frame_offset[] = { 91179161Sobrien offsetof(struct trapframe, zero), 92179161Sobrien offsetof(struct trapframe, ast), 93179161Sobrien offsetof(struct trapframe, v0), 94179161Sobrien offsetof(struct trapframe, v1), 95179161Sobrien offsetof(struct trapframe, a0), 96179161Sobrien offsetof(struct trapframe, a1), 97179161Sobrien offsetof(struct trapframe, a2), 98179161Sobrien offsetof(struct trapframe, a3), 99179161Sobrien offsetof(struct trapframe, t0), 100179161Sobrien offsetof(struct trapframe, t1), 101179161Sobrien offsetof(struct trapframe, t2), 102179161Sobrien offsetof(struct trapframe, t3), 103179161Sobrien offsetof(struct trapframe, t4), 104179161Sobrien offsetof(struct trapframe, t5), 105179161Sobrien offsetof(struct trapframe, t6), 106179161Sobrien offsetof(struct trapframe, t7), 107179161Sobrien offsetof(struct trapframe, s0), 108179161Sobrien offsetof(struct trapframe, s1), 109179161Sobrien offsetof(struct trapframe, s2), 110179161Sobrien offsetof(struct trapframe, s3), 111179161Sobrien offsetof(struct trapframe, s4), 112179161Sobrien offsetof(struct trapframe, s5), 113179161Sobrien offsetof(struct trapframe, s6), 114179161Sobrien offsetof(struct trapframe, s7), 115179161Sobrien offsetof(struct trapframe, t8), 116179161Sobrien offsetof(struct trapframe, t9), 117179161Sobrien offsetof(struct trapframe, k0), 118179161Sobrien offsetof(struct trapframe, k1), 119179161Sobrien offsetof(struct trapframe, gp), 120179161Sobrien offsetof(struct trapframe, sp), 121179161Sobrien offsetof(struct trapframe, s8), 122179161Sobrien offsetof(struct trapframe, ra), 123179161Sobrien}; 124179161Sobrien 125179161Sobrienstatic struct kgdb_frame_cache * 126179161Sobrienkgdb_trgt_frame_cache(struct frame_info *next_frame __unused, void **this_cache __unused) 127179161Sobrien{ 128179161Sobrien char buf[MAX_REGISTER_SIZE]; 129179161Sobrien struct kgdb_frame_cache *cache; 130179161Sobrien 131179161Sobrien cache = *this_cache; 132179161Sobrien if (cache == NULL) { 133179161Sobrien cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); 134179161Sobrien *this_cache = cache; 135179161Sobrien cache->pc = frame_func_unwind(next_frame); 136179161Sobrien frame_unwind_register(next_frame, SP_REGNUM, buf); 137179161Sobrien cache->sp = extract_unsigned_integer(buf, 138179161Sobrien register_size(current_gdbarch, SP_REGNUM)); 139179161Sobrien } 140179161Sobrien return (cache); 141179161Sobrien} 142179161Sobrien 143179161Sobrienstatic void 144179161Sobrienkgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, 145179161Sobrien struct frame_id *this_id) 146179161Sobrien{ 147179161Sobrien struct kgdb_frame_cache *cache; 148179161Sobrien 149179161Sobrien cache = kgdb_trgt_frame_cache(next_frame, this_cache); 150179161Sobrien *this_id = frame_id_build(cache->sp, cache->pc); 151179161Sobrien} 152179161Sobrien 153179161Sobrienstatic void 154179161Sobrienkgdb_trgt_trapframe_prev_register(struct frame_info *next_frame __unused, 155179161Sobrien void **this_cache __unused, int regnum __unused, int *optimizedp __unused, 156179161Sobrien enum lval_type *lvalp __unused, CORE_ADDR *addrp __unused, 157179161Sobrien int *realnump __unused, void *valuep __unused) 158179161Sobrien{ 159179161Sobrien char dummy_valuep[MAX_REGISTER_SIZE]; 160179161Sobrien struct kgdb_frame_cache *cache; 161179161Sobrien int ofs, regsz; 162179161Sobrien 163179161Sobrien regsz = register_size(current_gdbarch, regnum); 164179161Sobrien 165179161Sobrien if (valuep == NULL) 166179161Sobrien valuep = dummy_valuep; 167179161Sobrien memset(valuep, 0, regsz); 168179161Sobrien *optimizedp = 0; 169179161Sobrien *addrp = 0; 170179161Sobrien *lvalp = not_lval; 171179161Sobrien *realnump = -1; 172179161Sobrien 173179161Sobrien ofs = (regnum >= 0 && regnum <= MIPS_RA_REGNUM) ? 174179161Sobrien kgdb_trgt_frame_offset[regnum] : -1; 175179161Sobrien if (ofs == -1) 176179161Sobrien return; 177179161Sobrien 178179161Sobrien cache = kgdb_trgt_frame_cache(next_frame, this_cache); 179179161Sobrien *addrp = cache->sp + ofs * 8; 180179161Sobrien *lvalp = lval_memory; 181179161Sobrien target_read_memory(*addrp, valuep, regsz); 182179161Sobrien} 183179161Sobrien 184179161Sobrienstatic const struct frame_unwind kgdb_trgt_trapframe_unwind = { 185179161Sobrien UNKNOWN_FRAME, 186179161Sobrien &kgdb_trgt_trapframe_this_id, 187179161Sobrien &kgdb_trgt_trapframe_prev_register 188179161Sobrien}; 189179161Sobrien 190179161Sobrienconst struct frame_unwind * 191179161Sobrienkgdb_trgt_trapframe_sniffer(struct frame_info *next_frame __unused) 192179161Sobrien{ 193179161Sobrien char *pname; 194179161Sobrien CORE_ADDR pc; 195179161Sobrien 196179161Sobrien pc = frame_pc_unwind(next_frame); 197179161Sobrien pname = NULL; 198179161Sobrien find_pc_partial_function(pc, &pname, NULL, NULL); 199179161Sobrien if (pname == NULL) 200179161Sobrien return (NULL); 201179161Sobrien if ((strcmp(pname, "MipsKernIntr") == 0) || 202179161Sobrien (strcmp(pname, "MipsKernGenException") == 0) || 203179161Sobrien (strcmp(pname, "MipsUserIntr") == 0) || 204179161Sobrien (strcmp(pname, "MipsUserGenException") == 0)) 205179161Sobrien return (&kgdb_trgt_trapframe_unwind); 206179161Sobrien /* printf("%s: %llx =%s\n", __func__, pc, pname); */ 207179161Sobrien return (NULL); 208179161Sobrien} 209