1156772Sdeischen/* 2156772Sdeischen * Copyright (c) 2007 Juniper Networks, Inc. 3156772Sdeischen * Copyright (c) 2004 Marcel Moolenaar 4156772Sdeischen * All rights reserved. 5156772Sdeischen * 6156772Sdeischen * Redistribution and use in source and binary forms, with or without 7156772Sdeischen * modification, are permitted provided that the following conditions 8156772Sdeischen * are met: 9156772Sdeischen * 10156772Sdeischen * 1. Redistributions of source code must retain the above copyright 11156772Sdeischen * notice, this list of conditions and the following disclaimer. 12156772Sdeischen * 2. Redistributions in binary form must reproduce the above copyright 13156772Sdeischen * notice, this list of conditions and the following disclaimer in the 14156772Sdeischen * documentation and/or other materials provided with the distribution. 15156772Sdeischen * 16156772Sdeischen * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 17156772Sdeischen * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18156772Sdeischen * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19156772Sdeischen * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20156772Sdeischen * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21156772Sdeischen * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22156772Sdeischen * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23156772Sdeischen * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24156772Sdeischen * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25156772Sdeischen * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26156772Sdeischen * 27156772Sdeischen * from: src/gnu/usr.bin/gdb/kgdb/trgt_alpha.c,v 1.2.2.1 2005/09/15 05:32:10 marcel 28156772Sdeischen */ 29156772Sdeischen 30156772Sdeischen#include <sys/cdefs.h> 31156772Sdeischen__FBSDID("$FreeBSD: releng/11.0/gnu/usr.bin/gdb/kgdb/trgt_mips.c 298363 2016-04-20 20:22:48Z wma $"); 32156772Sdeischen 33156772Sdeischen#include <sys/types.h> 34156772Sdeischen#include <machine/asm.h> 35156772Sdeischen#include <machine/pcb.h> 36156772Sdeischen#include <machine/frame.h> 37172729Syar#include <err.h> 38172729Syar#include <kvm.h> 39156772Sdeischen#include <string.h> 40156772Sdeischen 41156772Sdeischen#include <defs.h> 42156772Sdeischen#include <target.h> 43156772Sdeischen#include <gdbthread.h> 44156772Sdeischen#include <inferior.h> 45156772Sdeischen#include <regcache.h> 46156772Sdeischen#include <frame-unwind.h> 47156772Sdeischen#include <mips-tdep.h> 48156772Sdeischen 49156772Sdeischen#ifndef CROSS_DEBUGGER 50172729Syar#include <machine/pcb.h> 51172729Syar#endif 52172729Syar 53156772Sdeischen#include "kgdb.h" 54172729Syar 55172729SyarCORE_ADDR 56172729Syarkgdb_trgt_core_pcb(u_int cpuid) 57156772Sdeischen{ 58156772Sdeischen return (kgdb_trgt_stop_pcb(cpuid, sizeof(struct pcb))); 59156772Sdeischen} 60156772Sdeischen 61168963Sdeischenvoid 62156772Sdeischenkgdb_trgt_fetch_registers(int regno __unused) 63156772Sdeischen{ 64172729Syar#ifndef CROSS_DEBUGGER 65172729Syar struct kthr *kt; 66172729Syar struct pcb pcb; 67172729Syar 68156772Sdeischen kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); 69172729Syar if (kt == NULL) 70172729Syar return; 71172729Syar if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { 72172729Syar warnx("kvm_read: %s", kvm_geterr(kvm)); 73172729Syar memset(&pcb, 0, sizeof(pcb)); 74172729Syar } 75172729Syar 76172729Syar supply_register(MIPS_S0_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S0]); 77172729Syar supply_register(MIPS_S1_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S1]); 78172729Syar supply_register(MIPS_S2_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S2]); 79172729Syar supply_register(MIPS_S3_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S3]); 80172729Syar supply_register(MIPS_S4_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S4]); 81156772Sdeischen supply_register(MIPS_S5_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S5]); 82172729Syar supply_register(MIPS_S6_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S6]); 83156772Sdeischen supply_register(MIPS_S7_REGNUM, (char *)&pcb.pcb_context[PCB_REG_S7]); 84156772Sdeischen supply_register(MIPS_SP_REGNUM, (char *)&pcb.pcb_context[PCB_REG_SP]); 85172729Syar supply_register(MIPS_FP_REGNUM, (char *)&pcb.pcb_context[PCB_REG_GP]); 86172729Syar supply_register(MIPS_RA_REGNUM, (char *)&pcb.pcb_context[PCB_REG_RA]); 87156772Sdeischen supply_register(MIPS_EMBED_PC_REGNUM, (char *)&pcb.pcb_context[PCB_REG_PC]); 88156772Sdeischen#endif 89172729Syar} 90172729Syar 91156772Sdeischenvoid 92156772Sdeischenkgdb_trgt_store_registers(int regno __unused) 93156772Sdeischen{ 94172729Syar 95172729Syar fprintf_unfiltered(gdb_stderr, "Unimplemented function: %s\n", __func__); 96156772Sdeischen} 97172729Syar 98156772Sdeischenvoid 99156772Sdeischenkgdb_trgt_new_objfile(struct objfile *objfile) 100156772Sdeischen{ 101172729Syar} 102172729Syar 103156772Sdeischen#ifndef CROSS_DEBUGGER 104172729Syarstruct kgdb_frame_cache { 105172729Syar CORE_ADDR pc; 106156772Sdeischen CORE_ADDR sp; 107156772Sdeischen}; 108156772Sdeischen 109156772Sdeischenstatic int kgdb_trgt_frame_offset[] = { 110172729Syar offsetof(struct trapframe, zero), 111172729Syar offsetof(struct trapframe, ast), 112172729Syar offsetof(struct trapframe, v0), 113172729Syar offsetof(struct trapframe, v1), 114156772Sdeischen offsetof(struct trapframe, a0), 115156772Sdeischen offsetof(struct trapframe, a1), 116156772Sdeischen offsetof(struct trapframe, a2), 117156772Sdeischen offsetof(struct trapframe, a3), 118156772Sdeischen#if defined(__mips_n32) || defined(__mips_n64) 119156772Sdeischen offsetof(struct trapframe, a4), 120156772Sdeischen offsetof(struct trapframe, a5), 121156772Sdeischen offsetof(struct trapframe, a6), 122156772Sdeischen offsetof(struct trapframe, a7), 123172729Syar offsetof(struct trapframe, t0), 124156772Sdeischen offsetof(struct trapframe, t1), 125156772Sdeischen offsetof(struct trapframe, t2), 126172729Syar offsetof(struct trapframe, t3), 127156772Sdeischen#else 128172729Syar offsetof(struct trapframe, t0), 129172729Syar offsetof(struct trapframe, t1), 130172729Syar offsetof(struct trapframe, t2), 131156772Sdeischen offsetof(struct trapframe, t3), 132156772Sdeischen offsetof(struct trapframe, t4), 133172729Syar offsetof(struct trapframe, t5), 134172729Syar offsetof(struct trapframe, t6), 135156772Sdeischen offsetof(struct trapframe, t7), 136156772Sdeischen#endif 137156772Sdeischen offsetof(struct trapframe, s0), 138156772Sdeischen offsetof(struct trapframe, s1), 139156772Sdeischen offsetof(struct trapframe, s2), 140156772Sdeischen offsetof(struct trapframe, s3), 141156772Sdeischen offsetof(struct trapframe, s4), 142156772Sdeischen offsetof(struct trapframe, s5), 143156772Sdeischen offsetof(struct trapframe, s6), 144172729Syar offsetof(struct trapframe, s7), 145172729Syar offsetof(struct trapframe, t8), 146172729Syar offsetof(struct trapframe, t9), 147156772Sdeischen offsetof(struct trapframe, k0), 148156772Sdeischen offsetof(struct trapframe, k1), 149156772Sdeischen offsetof(struct trapframe, gp), 150156772Sdeischen offsetof(struct trapframe, sp), 151172729Syar offsetof(struct trapframe, s8), 152172729Syar offsetof(struct trapframe, ra), 153172729Syar}; 154172729Syar 155172729Syarstatic struct kgdb_frame_cache * 156172729Syarkgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) 157156772Sdeischen{ 158172729Syar char buf[MAX_REGISTER_SIZE]; 159172729Syar struct kgdb_frame_cache *cache; 160172729Syar 161172729Syar cache = *this_cache; 162172729Syar if (cache == NULL) { 163156772Sdeischen cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); 164156772Sdeischen *this_cache = cache; 165156772Sdeischen cache->pc = frame_func_unwind(next_frame); 166172729Syar frame_unwind_register(next_frame, SP_REGNUM, buf); 167156772Sdeischen cache->sp = extract_unsigned_integer(buf, 168156772Sdeischen register_size(current_gdbarch, SP_REGNUM)); 169156772Sdeischen } 170172729Syar return (cache); 171172729Syar} 172156772Sdeischen 173156772Sdeischenstatic void 174156772Sdeischenkgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, 175156772Sdeischen struct frame_id *this_id) 176156772Sdeischen{ 177156772Sdeischen struct kgdb_frame_cache *cache; 178156772Sdeischen 179172729Syar cache = kgdb_trgt_frame_cache(next_frame, this_cache); 180172729Syar *this_id = frame_id_build(cache->sp, cache->pc); 181172729Syar} 182172729Syar 183156772Sdeischenstatic void 184156772Sdeischenkgdb_trgt_trapframe_prev_register(struct frame_info *next_frame __unused, 185168963Sdeischen void **this_cache __unused, int regnum __unused, int *optimizedp __unused, 186168963Sdeischen enum lval_type *lvalp __unused, CORE_ADDR *addrp __unused, 187168963Sdeischen int *realnump __unused, void *valuep __unused) 188168963Sdeischen{ 189168963Sdeischen char dummy_valuep[MAX_REGISTER_SIZE]; 190168963Sdeischen struct kgdb_frame_cache *cache; 191168963Sdeischen int ofs, regsz; 192168963Sdeischen 193168963Sdeischen regsz = register_size(current_gdbarch, regnum); 194168963Sdeischen 195168963Sdeischen if (valuep == NULL) 196168963Sdeischen valuep = dummy_valuep; 197168963Sdeischen memset(valuep, 0, regsz); 198168963Sdeischen *optimizedp = 0; 199168963Sdeischen *addrp = 0; 200168963Sdeischen *lvalp = not_lval; 201168963Sdeischen *realnump = -1; 202168963Sdeischen 203168963Sdeischen ofs = (regnum >= 0 && regnum <= MIPS_RA_REGNUM) ? 204168963Sdeischen kgdb_trgt_frame_offset[regnum] : -1; 205172729Syar if (ofs == -1) 206168963Sdeischen return; 207171530Skan 208171530Skan cache = kgdb_trgt_frame_cache(next_frame, this_cache); 209171530Skan *addrp = cache->sp + ofs * 8; 210168963Sdeischen *lvalp = lval_memory; 211168963Sdeischen target_read_memory(*addrp, valuep, regsz); 212171530Skan} 213171530Skan 214168963Sdeischenstatic const struct frame_unwind kgdb_trgt_trapframe_unwind = { 215168963Sdeischen UNKNOWN_FRAME, 216168963Sdeischen &kgdb_trgt_trapframe_this_id, 217168963Sdeischen &kgdb_trgt_trapframe_prev_register 218168963Sdeischen}; 219168963Sdeischen#endif 220168963Sdeischen 221172729Syarconst struct frame_unwind * 222156772Sdeischenkgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) 223172729Syar{ 224172729Syar#ifndef CROSS_DEBUGGER 225172729Syar char *pname; 226172729Syar CORE_ADDR pc; 227172729Syar 228156772Sdeischen pc = frame_pc_unwind(next_frame); 229168963Sdeischen pname = NULL; 230156772Sdeischen find_pc_partial_function(pc, &pname, NULL, NULL); 231156772Sdeischen if (pname == NULL) 232 return (NULL); 233 if ((strcmp(pname, "MipsKernIntr") == 0) || 234 (strcmp(pname, "MipsKernGenException") == 0) || 235 (strcmp(pname, "MipsUserIntr") == 0) || 236 (strcmp(pname, "MipsUserGenException") == 0)) 237 return (&kgdb_trgt_trapframe_unwind); 238#endif 239 return (NULL); 240} 241 242/* 243 * This function ensures, that the PC is inside the 244 * function section which is understood by GDB. 245 * 246 * Return 0 when fixup is necessary, -1 otherwise. 247 */ 248int 249kgdb_trgt_pc_fixup(CORE_ADDR *pc __unused) 250{ 251 252 return (-1); 253} 254