trgt_powerpc.c revision 234739
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: head/gnu/usr.bin/gdb/kgdb/trgt_powerpc.c 234739 2012-04-27 20:16:20Z marcel $"); 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 52161589Smarcelvoid 53161589Smarcelkgdb_trgt_fetch_registers(int regno __unused) 54161589Smarcel{ 55161589Smarcel struct kthr *kt; 56163440Sjhb struct pcb pcb; 57161589Smarcel struct gdbarch_tdep *tdep; 58161589Smarcel int i; 59161589Smarcel 60161589Smarcel tdep = gdbarch_tdep (current_gdbarch); 61161589Smarcel 62178713Sjhb kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); 63161589Smarcel if (kt == NULL) 64161589Smarcel return; 65161589Smarcel if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { 66161589Smarcel warnx("kvm_read: %s", kvm_geterr(kvm)); 67161589Smarcel memset(&pcb, 0, sizeof(pcb)); 68161589Smarcel } 69161589Smarcel 70161589Smarcel /* 71161589Smarcel * r14-r31 are saved in the pcb 72161589Smarcel */ 73161589Smarcel for (i = 14; i <= 31; i++) { 74161589Smarcel supply_register(tdep->ppc_gp0_regnum + i, 75161589Smarcel (char *)&pcb.pcb_context[i]); 76161589Smarcel } 77163440Sjhb 78161589Smarcel /* r1 is saved in the sp field */ 79161589Smarcel supply_register(tdep->ppc_gp0_regnum + 1, (char *)&pcb.pcb_sp); 80161589Smarcel 81161589Smarcel supply_register(tdep->ppc_lr_regnum, (char *)&pcb.pcb_lr); 82161589Smarcel supply_register(tdep->ppc_cr_regnum, (char *)&pcb.pcb_cr); 83161589Smarcel} 84161589Smarcel 85161589Smarcelvoid 86161589Smarcelkgdb_trgt_store_registers(int regno __unused) 87161589Smarcel{ 88161589Smarcel fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); 89161589Smarcel} 90161589Smarcel 91178670Sjhbvoid 92178670Sjhbkgdb_trgt_new_objfile(struct objfile *objfile) 93178670Sjhb{ 94178670Sjhb} 95178670Sjhb 96161589Smarcelstruct kgdb_frame_cache { 97161589Smarcel CORE_ADDR pc; 98161589Smarcel CORE_ADDR sp; 99161589Smarcel}; 100161589Smarcel 101161589Smarcelstatic struct kgdb_frame_cache * 102161589Smarcelkgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) 103161589Smarcel{ 104161589Smarcel char buf[MAX_REGISTER_SIZE]; 105161589Smarcel struct kgdb_frame_cache *cache; 106161589Smarcel 107161589Smarcel cache = *this_cache; 108161589Smarcel if (cache == NULL) { 109161589Smarcel cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); 110161589Smarcel *this_cache = cache; 111161589Smarcel cache->pc = frame_func_unwind(next_frame); 112161589Smarcel frame_unwind_register(next_frame, SP_REGNUM, buf); 113161589Smarcel cache->sp = extract_unsigned_integer(buf, 114161589Smarcel register_size(current_gdbarch, SP_REGNUM)); 115161589Smarcel } 116161589Smarcel return (cache); 117161589Smarcel} 118161589Smarcel 119161589Smarcelstatic void 120161589Smarcelkgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, 121161589Smarcel struct frame_id *this_id) 122161589Smarcel{ 123161589Smarcel struct kgdb_frame_cache *cache; 124161589Smarcel 125161589Smarcel cache = kgdb_trgt_frame_cache(next_frame, this_cache); 126161589Smarcel *this_id = frame_id_build(cache->sp, cache->pc); 127161589Smarcel} 128161589Smarcel 129161589Smarcelstatic void 130161589Smarcelkgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, 131161589Smarcel void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, 132161589Smarcel CORE_ADDR *addrp, int *realnump, void *valuep) 133161589Smarcel{ 134161589Smarcel char dummy_valuep[MAX_REGISTER_SIZE]; 135161589Smarcel struct gdbarch_tdep *tdep; 136161589Smarcel struct kgdb_frame_cache *cache; 137161589Smarcel int ofs, regsz; 138161589Smarcel 139161589Smarcel tdep = gdbarch_tdep(current_gdbarch); 140161589Smarcel regsz = register_size(current_gdbarch, regnum); 141161589Smarcel 142161589Smarcel if (valuep == NULL) 143161589Smarcel valuep = dummy_valuep; 144161589Smarcel memset(valuep, 0, regsz); 145161589Smarcel *optimizedp = 0; 146161589Smarcel *addrp = 0; 147161589Smarcel *lvalp = not_lval; 148161589Smarcel *realnump = -1; 149161589Smarcel 150161589Smarcel if (regnum >= tdep->ppc_gp0_regnum && 151161589Smarcel regnum <= tdep->ppc_gplast_regnum) 152161589Smarcel ofs = offsetof(struct trapframe, 153161589Smarcel fixreg[regnum - tdep->ppc_gp0_regnum]); 154161589Smarcel else if (regnum == tdep->ppc_lr_regnum) 155161589Smarcel ofs = offsetof(struct trapframe, lr); 156161589Smarcel else if (regnum == tdep->ppc_cr_regnum) 157161589Smarcel ofs = offsetof(struct trapframe, cr); 158161589Smarcel else if (regnum == tdep->ppc_xer_regnum) 159161589Smarcel ofs = offsetof(struct trapframe, xer); 160161589Smarcel else if (regnum == tdep->ppc_ctr_regnum) 161161589Smarcel ofs = offsetof(struct trapframe, ctr); 162161589Smarcel else if (regnum == PC_REGNUM) 163161589Smarcel ofs = offsetof(struct trapframe, srr0); 164161589Smarcel else 165161589Smarcel return; 166161589Smarcel 167161589Smarcel cache = kgdb_trgt_frame_cache(next_frame, this_cache); 168161589Smarcel *addrp = cache->sp + 8 + ofs; 169161589Smarcel *lvalp = lval_memory; 170161589Smarcel target_read_memory(*addrp, valuep, regsz); 171161589Smarcel} 172161589Smarcel 173161589Smarcelstatic const struct frame_unwind kgdb_trgt_trapframe_unwind = { 174161589Smarcel UNKNOWN_FRAME, 175161589Smarcel &kgdb_trgt_trapframe_this_id, 176161589Smarcel &kgdb_trgt_trapframe_prev_register 177161589Smarcel}; 178161589Smarcel 179161589Smarcelconst struct frame_unwind * 180161589Smarcelkgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) 181161589Smarcel{ 182161589Smarcel char *pname; 183161589Smarcel CORE_ADDR pc; 184161589Smarcel 185161589Smarcel pc = frame_pc_unwind(next_frame); 186161589Smarcel pname = NULL; 187161589Smarcel find_pc_partial_function(pc, &pname, NULL, NULL); 188161589Smarcel if (pname == NULL) 189161589Smarcel return (NULL); 190161589Smarcel if (strcmp(pname, "asttrapexit") == 0 || 191161589Smarcel strcmp(pname, "trapexit") == 0) 192161589Smarcel return (&kgdb_trgt_trapframe_unwind); 193161589Smarcel /* printf("%s: %llx =%s\n", __func__, pc, pname); */ 194161589Smarcel return (NULL); 195161589Smarcel} 196