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> 31234739Smarcel#ifdef CROSS_DEBUGGER 32234739Smarcel#include <sys/powerpc/include/pcb.h> 33234739Smarcel#include <sys/powerpc/include/frame.h> 34234739Smarcel#else 35161589Smarcel#include <machine/pcb.h> 36161589Smarcel#include <machine/frame.h> 37234739Smarcel#endif 38161589Smarcel#include <err.h> 39161589Smarcel#include <kvm.h> 40161589Smarcel#include <string.h> 41161589Smarcel 42161589Smarcel#include <defs.h> 43161589Smarcel#include <target.h> 44161589Smarcel#include <gdbthread.h> 45161589Smarcel#include <inferior.h> 46161589Smarcel#include <regcache.h> 47161589Smarcel#include <frame-unwind.h> 48161589Smarcel#include <ppc-tdep.h> 49161589Smarcel 50161589Smarcel#include "kgdb.h" 51161589Smarcel 52246893SmarcelCORE_ADDR 53246893Smarcelkgdb_trgt_core_pcb(u_int cpuid) 54246893Smarcel{ 55246893Smarcel return (kgdb_trgt_stop_pcb(cpuid, sizeof(struct pcb))); 56246893Smarcel} 57246893Smarcel 58161589Smarcelvoid 59161589Smarcelkgdb_trgt_fetch_registers(int regno __unused) 60161589Smarcel{ 61161589Smarcel struct kthr *kt; 62163440Sjhb struct pcb pcb; 63161589Smarcel struct gdbarch_tdep *tdep; 64161589Smarcel int i; 65161589Smarcel 66161589Smarcel tdep = gdbarch_tdep (current_gdbarch); 67161589Smarcel 68178713Sjhb kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); 69161589Smarcel if (kt == NULL) 70161589Smarcel return; 71161589Smarcel if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { 72161589Smarcel warnx("kvm_read: %s", kvm_geterr(kvm)); 73161589Smarcel memset(&pcb, 0, sizeof(pcb)); 74161589Smarcel } 75161589Smarcel 76161589Smarcel /* 77161589Smarcel * r14-r31 are saved in the pcb 78161589Smarcel */ 79161589Smarcel for (i = 14; i <= 31; i++) { 80161589Smarcel supply_register(tdep->ppc_gp0_regnum + i, 81161589Smarcel (char *)&pcb.pcb_context[i]); 82161589Smarcel } 83163440Sjhb 84161589Smarcel /* r1 is saved in the sp field */ 85161589Smarcel supply_register(tdep->ppc_gp0_regnum + 1, (char *)&pcb.pcb_sp); 86161589Smarcel 87161589Smarcel supply_register(tdep->ppc_lr_regnum, (char *)&pcb.pcb_lr); 88161589Smarcel supply_register(tdep->ppc_cr_regnum, (char *)&pcb.pcb_cr); 89161589Smarcel} 90161589Smarcel 91161589Smarcelvoid 92161589Smarcelkgdb_trgt_store_registers(int regno __unused) 93161589Smarcel{ 94161589Smarcel fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); 95161589Smarcel} 96161589Smarcel 97178670Sjhbvoid 98178670Sjhbkgdb_trgt_new_objfile(struct objfile *objfile) 99178670Sjhb{ 100178670Sjhb} 101178670Sjhb 102161589Smarcelstruct kgdb_frame_cache { 103161589Smarcel CORE_ADDR pc; 104161589Smarcel CORE_ADDR sp; 105161589Smarcel}; 106161589Smarcel 107161589Smarcelstatic struct kgdb_frame_cache * 108161589Smarcelkgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) 109161589Smarcel{ 110161589Smarcel char buf[MAX_REGISTER_SIZE]; 111161589Smarcel struct kgdb_frame_cache *cache; 112161589Smarcel 113161589Smarcel cache = *this_cache; 114161589Smarcel if (cache == NULL) { 115161589Smarcel cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); 116161589Smarcel *this_cache = cache; 117161589Smarcel cache->pc = frame_func_unwind(next_frame); 118161589Smarcel frame_unwind_register(next_frame, SP_REGNUM, buf); 119161589Smarcel cache->sp = extract_unsigned_integer(buf, 120161589Smarcel register_size(current_gdbarch, SP_REGNUM)); 121161589Smarcel } 122161589Smarcel return (cache); 123161589Smarcel} 124161589Smarcel 125161589Smarcelstatic void 126161589Smarcelkgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, 127161589Smarcel struct frame_id *this_id) 128161589Smarcel{ 129161589Smarcel struct kgdb_frame_cache *cache; 130161589Smarcel 131161589Smarcel cache = kgdb_trgt_frame_cache(next_frame, this_cache); 132161589Smarcel *this_id = frame_id_build(cache->sp, cache->pc); 133161589Smarcel} 134161589Smarcel 135161589Smarcelstatic void 136161589Smarcelkgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, 137161589Smarcel void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, 138161589Smarcel CORE_ADDR *addrp, int *realnump, void *valuep) 139161589Smarcel{ 140161589Smarcel char dummy_valuep[MAX_REGISTER_SIZE]; 141161589Smarcel struct gdbarch_tdep *tdep; 142161589Smarcel struct kgdb_frame_cache *cache; 143161589Smarcel int ofs, regsz; 144161589Smarcel 145161589Smarcel tdep = gdbarch_tdep(current_gdbarch); 146161589Smarcel regsz = register_size(current_gdbarch, regnum); 147161589Smarcel 148161589Smarcel if (valuep == NULL) 149161589Smarcel valuep = dummy_valuep; 150161589Smarcel memset(valuep, 0, regsz); 151161589Smarcel *optimizedp = 0; 152161589Smarcel *addrp = 0; 153161589Smarcel *lvalp = not_lval; 154161589Smarcel *realnump = -1; 155161589Smarcel 156161589Smarcel if (regnum >= tdep->ppc_gp0_regnum && 157161589Smarcel regnum <= tdep->ppc_gplast_regnum) 158161589Smarcel ofs = offsetof(struct trapframe, 159161589Smarcel fixreg[regnum - tdep->ppc_gp0_regnum]); 160161589Smarcel else if (regnum == tdep->ppc_lr_regnum) 161161589Smarcel ofs = offsetof(struct trapframe, lr); 162161589Smarcel else if (regnum == tdep->ppc_cr_regnum) 163161589Smarcel ofs = offsetof(struct trapframe, cr); 164161589Smarcel else if (regnum == tdep->ppc_xer_regnum) 165161589Smarcel ofs = offsetof(struct trapframe, xer); 166161589Smarcel else if (regnum == tdep->ppc_ctr_regnum) 167161589Smarcel ofs = offsetof(struct trapframe, ctr); 168161589Smarcel else if (regnum == PC_REGNUM) 169161589Smarcel ofs = offsetof(struct trapframe, srr0); 170161589Smarcel else 171161589Smarcel return; 172161589Smarcel 173161589Smarcel cache = kgdb_trgt_frame_cache(next_frame, this_cache); 174161589Smarcel *addrp = cache->sp + 8 + ofs; 175161589Smarcel *lvalp = lval_memory; 176161589Smarcel target_read_memory(*addrp, valuep, regsz); 177161589Smarcel} 178161589Smarcel 179161589Smarcelstatic const struct frame_unwind kgdb_trgt_trapframe_unwind = { 180161589Smarcel UNKNOWN_FRAME, 181161589Smarcel &kgdb_trgt_trapframe_this_id, 182161589Smarcel &kgdb_trgt_trapframe_prev_register 183161589Smarcel}; 184161589Smarcel 185161589Smarcelconst struct frame_unwind * 186161589Smarcelkgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) 187161589Smarcel{ 188161589Smarcel char *pname; 189161589Smarcel CORE_ADDR pc; 190161589Smarcel 191161589Smarcel pc = frame_pc_unwind(next_frame); 192161589Smarcel pname = NULL; 193161589Smarcel find_pc_partial_function(pc, &pname, NULL, NULL); 194161589Smarcel if (pname == NULL) 195161589Smarcel return (NULL); 196161589Smarcel if (strcmp(pname, "asttrapexit") == 0 || 197161589Smarcel strcmp(pname, "trapexit") == 0) 198161589Smarcel return (&kgdb_trgt_trapframe_unwind); 199161589Smarcel /* printf("%s: %llx =%s\n", __func__, pc, pname); */ 200161589Smarcel return (NULL); 201161589Smarcel} 202