1132624Smarcel/* 2132624Smarcel * Copyright (c) 2004 Marcel Moolenaar 3132624Smarcel * All rights reserved. 4132624Smarcel * 5132624Smarcel * Redistribution and use in source and binary forms, with or without 6132624Smarcel * modification, are permitted provided that the following conditions 7132624Smarcel * are met: 8132624Smarcel * 9132624Smarcel * 1. Redistributions of source code must retain the above copyright 10132624Smarcel * notice, this list of conditions and the following disclaimer. 11132624Smarcel * 2. Redistributions in binary form must reproduce the above copyright 12132624Smarcel * notice, this list of conditions and the following disclaimer in the 13132624Smarcel * documentation and/or other materials provided with the distribution. 14132624Smarcel * 15132624Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16132624Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17132624Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18132624Smarcel * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 19132624Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20132624Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21132624Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22132624Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23132624Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24132624Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25132624Smarcel */ 26132624Smarcel 27132624Smarcel#include <sys/cdefs.h> 28132624Smarcel__FBSDID("$FreeBSD$"); 29132624Smarcel 30132624Smarcel#include <sys/types.h> 31132624Smarcel#include <machine/pcb.h> 32149957Smarcel#include <machine/frame.h> 33132624Smarcel#include <err.h> 34132624Smarcel#include <kvm.h> 35132624Smarcel#include <string.h> 36132624Smarcel 37132624Smarcel#include <defs.h> 38132624Smarcel#include <target.h> 39132624Smarcel#include <gdbthread.h> 40132624Smarcel#include <inferior.h> 41132624Smarcel#include <regcache.h> 42149954Smarcel#include <frame-unwind.h> 43149957Smarcel#include <amd64-tdep.h> 44132624Smarcel 45149954Smarcel#include "kgdb.h" 46149954Smarcel 47132624Smarcelvoid 48132624Smarcelkgdb_trgt_fetch_registers(int regno __unused) 49132624Smarcel{ 50132624Smarcel struct kthr *kt; 51132624Smarcel struct pcb pcb; 52132624Smarcel 53178713Sjhb kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); 54132624Smarcel if (kt == NULL) 55132624Smarcel return; 56132624Smarcel if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { 57132624Smarcel warnx("kvm_read: %s", kvm_geterr(kvm)); 58132624Smarcel memset(&pcb, 0, sizeof(pcb)); 59132624Smarcel } 60132624Smarcel 61149957Smarcel supply_register(AMD64_RBX_REGNUM, (char *)&pcb.pcb_rbx); 62149957Smarcel supply_register(AMD64_RBP_REGNUM, (char *)&pcb.pcb_rbp); 63149957Smarcel supply_register(AMD64_RSP_REGNUM, (char *)&pcb.pcb_rsp); 64149957Smarcel supply_register(AMD64_R8_REGNUM + 4, (char *)&pcb.pcb_r12); 65149957Smarcel supply_register(AMD64_R8_REGNUM + 5, (char *)&pcb.pcb_r13); 66149957Smarcel supply_register(AMD64_R8_REGNUM + 6, (char *)&pcb.pcb_r14); 67149957Smarcel supply_register(AMD64_R15_REGNUM, (char *)&pcb.pcb_r15); 68149957Smarcel supply_register(AMD64_RIP_REGNUM, (char *)&pcb.pcb_rip); 69231980Skib amd64_supply_fxsave(current_regcache, -1, (struct fpusave *)(&pcb + 1)); 70132624Smarcel} 71132624Smarcel 72132624Smarcelvoid 73132624Smarcelkgdb_trgt_store_registers(int regno __unused) 74132624Smarcel{ 75132624Smarcel fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); 76132624Smarcel} 77149954Smarcel 78178670Sjhbvoid 79178670Sjhbkgdb_trgt_new_objfile(struct objfile *objfile) 80178670Sjhb{ 81178670Sjhb} 82178670Sjhb 83149957Smarcelstruct kgdb_frame_cache { 84149957Smarcel CORE_ADDR pc; 85149957Smarcel CORE_ADDR sp; 86149957Smarcel}; 87149957Smarcel 88149957Smarcelstatic int kgdb_trgt_frame_offset[20] = { 89149957Smarcel offsetof(struct trapframe, tf_rax), 90149957Smarcel offsetof(struct trapframe, tf_rbx), 91149957Smarcel offsetof(struct trapframe, tf_rcx), 92149957Smarcel offsetof(struct trapframe, tf_rdx), 93149957Smarcel offsetof(struct trapframe, tf_rsi), 94149957Smarcel offsetof(struct trapframe, tf_rdi), 95149957Smarcel offsetof(struct trapframe, tf_rbp), 96149957Smarcel offsetof(struct trapframe, tf_rsp), 97149957Smarcel offsetof(struct trapframe, tf_r8), 98149957Smarcel offsetof(struct trapframe, tf_r9), 99149957Smarcel offsetof(struct trapframe, tf_r10), 100149957Smarcel offsetof(struct trapframe, tf_r11), 101149957Smarcel offsetof(struct trapframe, tf_r12), 102149957Smarcel offsetof(struct trapframe, tf_r13), 103149957Smarcel offsetof(struct trapframe, tf_r14), 104149957Smarcel offsetof(struct trapframe, tf_r15), 105149957Smarcel offsetof(struct trapframe, tf_rip), 106149957Smarcel offsetof(struct trapframe, tf_rflags), 107149957Smarcel offsetof(struct trapframe, tf_cs), 108149957Smarcel offsetof(struct trapframe, tf_ss) 109149957Smarcel}; 110149957Smarcel 111149957Smarcelstatic struct kgdb_frame_cache * 112149957Smarcelkgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) 113149957Smarcel{ 114149957Smarcel char buf[MAX_REGISTER_SIZE]; 115149957Smarcel struct kgdb_frame_cache *cache; 116149957Smarcel 117149957Smarcel cache = *this_cache; 118149957Smarcel if (cache == NULL) { 119149957Smarcel cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); 120149957Smarcel *this_cache = cache; 121149957Smarcel cache->pc = frame_func_unwind(next_frame); 122149957Smarcel frame_unwind_register(next_frame, SP_REGNUM, buf); 123149957Smarcel cache->sp = extract_unsigned_integer(buf, 124149957Smarcel register_size(current_gdbarch, SP_REGNUM)); 125149957Smarcel } 126149957Smarcel return (cache); 127149957Smarcel} 128149957Smarcel 129149954Smarcelstatic void 130149954Smarcelkgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, 131149954Smarcel struct frame_id *this_id) 132149954Smarcel{ 133149957Smarcel struct kgdb_frame_cache *cache; 134149957Smarcel 135149957Smarcel cache = kgdb_trgt_frame_cache(next_frame, this_cache); 136149957Smarcel *this_id = frame_id_build(cache->sp, cache->pc); 137149954Smarcel} 138149954Smarcel 139149954Smarcelstatic void 140149954Smarcelkgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, 141149954Smarcel void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, 142149954Smarcel CORE_ADDR *addrp, int *realnump, void *valuep) 143149954Smarcel{ 144149957Smarcel char dummy_valuep[MAX_REGISTER_SIZE]; 145149957Smarcel struct kgdb_frame_cache *cache; 146149957Smarcel int ofs, regsz; 147149957Smarcel 148149957Smarcel regsz = register_size(current_gdbarch, regnum); 149149957Smarcel 150149957Smarcel if (valuep == NULL) 151149957Smarcel valuep = dummy_valuep; 152149957Smarcel memset(valuep, 0, regsz); 153149957Smarcel *optimizedp = 0; 154149957Smarcel *addrp = 0; 155149957Smarcel *lvalp = not_lval; 156149957Smarcel *realnump = -1; 157149957Smarcel 158149957Smarcel ofs = (regnum >= AMD64_RAX_REGNUM && regnum <= AMD64_EFLAGS_REGNUM + 2) 159149957Smarcel ? kgdb_trgt_frame_offset[regnum] : -1; 160149957Smarcel if (ofs == -1) 161149957Smarcel return; 162149957Smarcel 163161555Sjhb cache = kgdb_trgt_frame_cache(next_frame, this_cache); 164149957Smarcel *addrp = cache->sp + ofs; 165149957Smarcel *lvalp = lval_memory; 166149957Smarcel target_read_memory(*addrp, valuep, regsz); 167149954Smarcel} 168149954Smarcel 169149954Smarcelstatic const struct frame_unwind kgdb_trgt_trapframe_unwind = { 170149954Smarcel UNKNOWN_FRAME, 171149954Smarcel &kgdb_trgt_trapframe_this_id, 172149954Smarcel &kgdb_trgt_trapframe_prev_register 173149954Smarcel}; 174149954Smarcel 175149954Smarcelconst struct frame_unwind * 176149954Smarcelkgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) 177149954Smarcel{ 178149957Smarcel char *pname; 179149957Smarcel CORE_ADDR pc; 180149954Smarcel 181149957Smarcel pc = frame_pc_unwind(next_frame); 182149957Smarcel pname = NULL; 183149957Smarcel find_pc_partial_function(pc, &pname, NULL, NULL); 184149957Smarcel if (pname == NULL) 185149957Smarcel return (NULL); 186149976Smarcel if (strcmp(pname, "calltrap") == 0 || 187171924Sjhb strcmp(pname, "nmi_calltrap") == 0 || 188149976Smarcel (pname[0] == 'X' && pname[1] != '_')) 189149957Smarcel return (&kgdb_trgt_trapframe_unwind); 190149957Smarcel /* printf("%s: %lx =%s\n", __func__, pc, pname); */ 191149957Smarcel return (NULL); 192149954Smarcel} 193