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: releng/11.0/gnu/usr.bin/gdb/kgdb/trgt_powerpc64.c 298363 2016-04-20 20:22:48Z wma $"); 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 47246893SmarcelCORE_ADDR 48246893Smarcelkgdb_trgt_core_pcb(u_int cpuid) 49246893Smarcel{ 50246893Smarcel return (kgdb_trgt_stop_pcb(cpuid, sizeof(struct pcb))); 51246893Smarcel} 52246893Smarcel 53161589Smarcelvoid 54161589Smarcelkgdb_trgt_fetch_registers(int regno __unused) 55161589Smarcel{ 56161589Smarcel struct kthr *kt; 57163440Sjhb struct pcb pcb; 58161589Smarcel struct gdbarch_tdep *tdep; 59161589Smarcel int i; 60161589Smarcel 61161589Smarcel tdep = gdbarch_tdep (current_gdbarch); 62161589Smarcel 63178713Sjhb kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); 64161589Smarcel if (kt == NULL) 65161589Smarcel return; 66161589Smarcel if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { 67161589Smarcel warnx("kvm_read: %s", kvm_geterr(kvm)); 68161589Smarcel memset(&pcb, 0, sizeof(pcb)); 69161589Smarcel } 70161589Smarcel 71161589Smarcel /* 72161589Smarcel * r14-r31 are saved in the pcb 73161589Smarcel */ 74161589Smarcel for (i = 14; i <= 31; i++) { 75161589Smarcel supply_register(tdep->ppc_gp0_regnum + i, 76161589Smarcel (char *)&pcb.pcb_context[i]); 77161589Smarcel } 78163440Sjhb 79161589Smarcel /* r1 is saved in the sp field */ 80161589Smarcel supply_register(tdep->ppc_gp0_regnum + 1, (char *)&pcb.pcb_sp); 81209867Snwhitehorn /* r2 is saved in the toc field */ 82209867Snwhitehorn supply_register(tdep->ppc_gp0_regnum + 2, (char *)&pcb.pcb_toc); 83161589Smarcel 84161589Smarcel supply_register(tdep->ppc_lr_regnum, (char *)&pcb.pcb_lr); 85161589Smarcel supply_register(tdep->ppc_cr_regnum, (char *)&pcb.pcb_cr); 86161589Smarcel} 87161589Smarcel 88161589Smarcelvoid 89161589Smarcelkgdb_trgt_store_registers(int regno __unused) 90161589Smarcel{ 91161589Smarcel fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); 92161589Smarcel} 93161589Smarcel 94178670Sjhbvoid 95178670Sjhbkgdb_trgt_new_objfile(struct objfile *objfile) 96178670Sjhb{ 97178670Sjhb} 98178670Sjhb 99161589Smarcelstruct kgdb_frame_cache { 100161589Smarcel CORE_ADDR pc; 101161589Smarcel CORE_ADDR sp; 102161589Smarcel}; 103161589Smarcel 104161589Smarcelstatic struct kgdb_frame_cache * 105161589Smarcelkgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) 106161589Smarcel{ 107161589Smarcel char buf[MAX_REGISTER_SIZE]; 108161589Smarcel struct kgdb_frame_cache *cache; 109161589Smarcel 110161589Smarcel cache = *this_cache; 111161589Smarcel if (cache == NULL) { 112161589Smarcel cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); 113161589Smarcel *this_cache = cache; 114161589Smarcel cache->pc = frame_func_unwind(next_frame); 115161589Smarcel frame_unwind_register(next_frame, SP_REGNUM, buf); 116161589Smarcel cache->sp = extract_unsigned_integer(buf, 117161589Smarcel register_size(current_gdbarch, SP_REGNUM)); 118161589Smarcel } 119161589Smarcel return (cache); 120161589Smarcel} 121161589Smarcel 122161589Smarcelstatic void 123161589Smarcelkgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, 124161589Smarcel struct frame_id *this_id) 125161589Smarcel{ 126161589Smarcel struct kgdb_frame_cache *cache; 127161589Smarcel 128161589Smarcel cache = kgdb_trgt_frame_cache(next_frame, this_cache); 129161589Smarcel *this_id = frame_id_build(cache->sp, cache->pc); 130161589Smarcel} 131161589Smarcel 132161589Smarcelstatic void 133161589Smarcelkgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, 134161589Smarcel void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, 135161589Smarcel CORE_ADDR *addrp, int *realnump, void *valuep) 136161589Smarcel{ 137161589Smarcel char dummy_valuep[MAX_REGISTER_SIZE]; 138161589Smarcel struct gdbarch_tdep *tdep; 139161589Smarcel struct kgdb_frame_cache *cache; 140161589Smarcel int ofs, regsz; 141161589Smarcel 142161589Smarcel tdep = gdbarch_tdep(current_gdbarch); 143161589Smarcel regsz = register_size(current_gdbarch, regnum); 144161589Smarcel 145161589Smarcel if (valuep == NULL) 146161589Smarcel valuep = dummy_valuep; 147161589Smarcel memset(valuep, 0, regsz); 148161589Smarcel *optimizedp = 0; 149161589Smarcel *addrp = 0; 150161589Smarcel *lvalp = not_lval; 151161589Smarcel *realnump = -1; 152161589Smarcel 153161589Smarcel if (regnum >= tdep->ppc_gp0_regnum && 154161589Smarcel regnum <= tdep->ppc_gplast_regnum) 155161589Smarcel ofs = offsetof(struct trapframe, 156161589Smarcel fixreg[regnum - tdep->ppc_gp0_regnum]); 157161589Smarcel else if (regnum == tdep->ppc_lr_regnum) 158161589Smarcel ofs = offsetof(struct trapframe, lr); 159161589Smarcel else if (regnum == tdep->ppc_cr_regnum) 160161589Smarcel ofs = offsetof(struct trapframe, cr); 161161589Smarcel else if (regnum == tdep->ppc_xer_regnum) 162161589Smarcel ofs = offsetof(struct trapframe, xer); 163161589Smarcel else if (regnum == tdep->ppc_ctr_regnum) 164161589Smarcel ofs = offsetof(struct trapframe, ctr); 165161589Smarcel else if (regnum == PC_REGNUM) 166161589Smarcel ofs = offsetof(struct trapframe, srr0); 167161589Smarcel else 168161589Smarcel return; 169161589Smarcel 170161589Smarcel cache = kgdb_trgt_frame_cache(next_frame, this_cache); 171209867Snwhitehorn *addrp = cache->sp + 48 + ofs; 172161589Smarcel *lvalp = lval_memory; 173161589Smarcel target_read_memory(*addrp, valuep, regsz); 174161589Smarcel} 175161589Smarcel 176161589Smarcelstatic const struct frame_unwind kgdb_trgt_trapframe_unwind = { 177161589Smarcel UNKNOWN_FRAME, 178161589Smarcel &kgdb_trgt_trapframe_this_id, 179161589Smarcel &kgdb_trgt_trapframe_prev_register 180161589Smarcel}; 181161589Smarcel 182161589Smarcelconst struct frame_unwind * 183161589Smarcelkgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) 184161589Smarcel{ 185161589Smarcel char *pname; 186161589Smarcel CORE_ADDR pc; 187161589Smarcel 188161589Smarcel pc = frame_pc_unwind(next_frame); 189161589Smarcel pname = NULL; 190161589Smarcel find_pc_partial_function(pc, &pname, NULL, NULL); 191161589Smarcel if (pname == NULL) 192161589Smarcel return (NULL); 193161589Smarcel if (strcmp(pname, "asttrapexit") == 0 || 194161589Smarcel strcmp(pname, "trapexit") == 0) 195161589Smarcel return (&kgdb_trgt_trapframe_unwind); 196161589Smarcel /* printf("%s: %llx =%s\n", __func__, pc, pname); */ 197161589Smarcel return (NULL); 198161589Smarcel} 199298363Swma 200298363Swma/* 201298363Swma * This function ensures, that the PC is inside the 202298363Swma * function section which is understood by GDB. 203298363Swma * 204298363Swma * Return 0 when fixup is necessary, -1 otherwise. 205298363Swma */ 206298363Swmaint 207298363Swmakgdb_trgt_pc_fixup(CORE_ADDR *pc __unused) 208298363Swma{ 209298363Swma 210298363Swma return (-1); 211298363Swma} 212