1161589Smarcel/*- 2161589Smarcel * Copyright (c) 2006 Marcel Moolenaar 3161589Smarcel * All rights reserved. 4161589Smarcel * 5161589Smarcel * Redistribution and use in source and binary forms, with or without 6161589Smarcel * modification, are permitted provided that the following conditions 7161589Smarcel * are met: 8161589Smarcel * 9161589Smarcel * 1. Redistributions of source code must retain the above copyright 10161589Smarcel * notice, this list of conditions and the following disclaimer. 11161589Smarcel * 2. Redistributions in binary form must reproduce the above copyright 12161589Smarcel * notice, this list of conditions and the following disclaimer in the 13161589Smarcel * documentation and/or other materials provided with the distribution. 14161589Smarcel * 15161589Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16161589Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17161589Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18161589Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19161589Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20161589Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21161589Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22161589Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23161589Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24161589Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25161589Smarcel */ 26161589Smarcel 27161589Smarcel#include <sys/cdefs.h> 28161589Smarcel__FBSDID("$FreeBSD$"); 29161589Smarcel 30161589Smarcel#include <sys/types.h> 31161589Smarcel#include <machine/pcb.h> 32161589Smarcel#include <machine/frame.h> 33161589Smarcel#include <err.h> 34161589Smarcel#include <kvm.h> 35161589Smarcel#include <string.h> 36161589Smarcel 37161589Smarcel#include <defs.h> 38161589Smarcel#include <target.h> 39161589Smarcel#include <gdbthread.h> 40161589Smarcel#include <inferior.h> 41161589Smarcel#include <regcache.h> 42161589Smarcel#include <frame-unwind.h> 43161589Smarcel#include <ppc-tdep.h> 44161589Smarcel 45161589Smarcel#include "kgdb.h" 46161589Smarcel 47161589Smarcelvoid 48161589Smarcelkgdb_trgt_fetch_registers(int regno __unused) 49161589Smarcel{ 50161589Smarcel struct kthr *kt; 51163440Sjhb struct pcb pcb; 52161589Smarcel struct gdbarch_tdep *tdep; 53161589Smarcel int i; 54161589Smarcel 55161589Smarcel tdep = gdbarch_tdep (current_gdbarch); 56161589Smarcel 57178713Sjhb kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); 58161589Smarcel if (kt == NULL) 59161589Smarcel return; 60161589Smarcel if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { 61161589Smarcel warnx("kvm_read: %s", kvm_geterr(kvm)); 62161589Smarcel memset(&pcb, 0, sizeof(pcb)); 63161589Smarcel } 64161589Smarcel 65161589Smarcel /* 66161589Smarcel * r14-r31 are saved in the pcb 67161589Smarcel */ 68161589Smarcel for (i = 14; i <= 31; i++) { 69161589Smarcel supply_register(tdep->ppc_gp0_regnum + i, 70161589Smarcel (char *)&pcb.pcb_context[i]); 71161589Smarcel } 72163440Sjhb 73161589Smarcel /* r1 is saved in the sp field */ 74161589Smarcel supply_register(tdep->ppc_gp0_regnum + 1, (char *)&pcb.pcb_sp); 75209867Snwhitehorn /* r2 is saved in the toc field */ 76209867Snwhitehorn supply_register(tdep->ppc_gp0_regnum + 2, (char *)&pcb.pcb_toc); 77161589Smarcel 78161589Smarcel supply_register(tdep->ppc_lr_regnum, (char *)&pcb.pcb_lr); 79161589Smarcel supply_register(tdep->ppc_cr_regnum, (char *)&pcb.pcb_cr); 80161589Smarcel} 81161589Smarcel 82161589Smarcelvoid 83161589Smarcelkgdb_trgt_store_registers(int regno __unused) 84161589Smarcel{ 85161589Smarcel fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); 86161589Smarcel} 87161589Smarcel 88178670Sjhbvoid 89178670Sjhbkgdb_trgt_new_objfile(struct objfile *objfile) 90178670Sjhb{ 91178670Sjhb} 92178670Sjhb 93161589Smarcelstruct kgdb_frame_cache { 94161589Smarcel CORE_ADDR pc; 95161589Smarcel CORE_ADDR sp; 96161589Smarcel}; 97161589Smarcel 98161589Smarcelstatic struct kgdb_frame_cache * 99161589Smarcelkgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) 100161589Smarcel{ 101161589Smarcel char buf[MAX_REGISTER_SIZE]; 102161589Smarcel struct kgdb_frame_cache *cache; 103161589Smarcel 104161589Smarcel cache = *this_cache; 105161589Smarcel if (cache == NULL) { 106161589Smarcel cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); 107161589Smarcel *this_cache = cache; 108161589Smarcel cache->pc = frame_func_unwind(next_frame); 109161589Smarcel frame_unwind_register(next_frame, SP_REGNUM, buf); 110161589Smarcel cache->sp = extract_unsigned_integer(buf, 111161589Smarcel register_size(current_gdbarch, SP_REGNUM)); 112161589Smarcel } 113161589Smarcel return (cache); 114161589Smarcel} 115161589Smarcel 116161589Smarcelstatic void 117161589Smarcelkgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, 118161589Smarcel struct frame_id *this_id) 119161589Smarcel{ 120161589Smarcel struct kgdb_frame_cache *cache; 121161589Smarcel 122161589Smarcel cache = kgdb_trgt_frame_cache(next_frame, this_cache); 123161589Smarcel *this_id = frame_id_build(cache->sp, cache->pc); 124161589Smarcel} 125161589Smarcel 126161589Smarcelstatic void 127161589Smarcelkgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, 128161589Smarcel void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, 129161589Smarcel CORE_ADDR *addrp, int *realnump, void *valuep) 130161589Smarcel{ 131161589Smarcel char dummy_valuep[MAX_REGISTER_SIZE]; 132161589Smarcel struct gdbarch_tdep *tdep; 133161589Smarcel struct kgdb_frame_cache *cache; 134161589Smarcel int ofs, regsz; 135161589Smarcel 136161589Smarcel tdep = gdbarch_tdep(current_gdbarch); 137161589Smarcel regsz = register_size(current_gdbarch, regnum); 138161589Smarcel 139161589Smarcel if (valuep == NULL) 140161589Smarcel valuep = dummy_valuep; 141161589Smarcel memset(valuep, 0, regsz); 142161589Smarcel *optimizedp = 0; 143161589Smarcel *addrp = 0; 144161589Smarcel *lvalp = not_lval; 145161589Smarcel *realnump = -1; 146161589Smarcel 147161589Smarcel if (regnum >= tdep->ppc_gp0_regnum && 148161589Smarcel regnum <= tdep->ppc_gplast_regnum) 149161589Smarcel ofs = offsetof(struct trapframe, 150161589Smarcel fixreg[regnum - tdep->ppc_gp0_regnum]); 151161589Smarcel else if (regnum == tdep->ppc_lr_regnum) 152161589Smarcel ofs = offsetof(struct trapframe, lr); 153161589Smarcel else if (regnum == tdep->ppc_cr_regnum) 154161589Smarcel ofs = offsetof(struct trapframe, cr); 155161589Smarcel else if (regnum == tdep->ppc_xer_regnum) 156161589Smarcel ofs = offsetof(struct trapframe, xer); 157161589Smarcel else if (regnum == tdep->ppc_ctr_regnum) 158161589Smarcel ofs = offsetof(struct trapframe, ctr); 159161589Smarcel else if (regnum == PC_REGNUM) 160161589Smarcel ofs = offsetof(struct trapframe, srr0); 161161589Smarcel else 162161589Smarcel return; 163161589Smarcel 164161589Smarcel cache = kgdb_trgt_frame_cache(next_frame, this_cache); 165209867Snwhitehorn *addrp = cache->sp + 48 + ofs; 166161589Smarcel *lvalp = lval_memory; 167161589Smarcel target_read_memory(*addrp, valuep, regsz); 168161589Smarcel} 169161589Smarcel 170161589Smarcelstatic const struct frame_unwind kgdb_trgt_trapframe_unwind = { 171161589Smarcel UNKNOWN_FRAME, 172161589Smarcel &kgdb_trgt_trapframe_this_id, 173161589Smarcel &kgdb_trgt_trapframe_prev_register 174161589Smarcel}; 175161589Smarcel 176161589Smarcelconst struct frame_unwind * 177161589Smarcelkgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) 178161589Smarcel{ 179161589Smarcel char *pname; 180161589Smarcel CORE_ADDR pc; 181161589Smarcel 182161589Smarcel pc = frame_pc_unwind(next_frame); 183161589Smarcel pname = NULL; 184161589Smarcel find_pc_partial_function(pc, &pname, NULL, NULL); 185161589Smarcel if (pname == NULL) 186161589Smarcel return (NULL); 187161589Smarcel if (strcmp(pname, "asttrapexit") == 0 || 188161589Smarcel strcmp(pname, "trapexit") == 0) 189161589Smarcel return (&kgdb_trgt_trapframe_unwind); 190161589Smarcel /* printf("%s: %llx =%s\n", __func__, pc, pname); */ 191161589Smarcel return (NULL); 192161589Smarcel} 193