1/* 2 * Copyright (c) 2004 Marcel Moolenaar 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD$"); 29 30#include <sys/types.h> 31#ifdef CROSS_DEBUGGER 32#include <sys/ia64/include/_regset.h> 33#include <sys/ia64/include/frame.h> 34#include <sys/ia64/include/md_var.h> 35#include <sys/ia64/include/pcb.h> 36#else 37#include <machine/frame.h> 38#include <machine/md_var.h> 39#include <machine/pcb.h> 40#endif 41#include <err.h> 42#include <kvm.h> 43#include <string.h> 44 45#include <defs.h> 46#include <target.h> 47#include <gdbthread.h> 48#include <inferior.h> 49#include <regcache.h> 50#include <frame-unwind.h> 51#include <ia64-tdep.h> 52 53#include "kgdb.h" 54 55void 56kgdb_trgt_fetch_registers(int regno __unused) 57{ 58 struct kthr *kt; 59 struct pcb pcb; 60 uint64_t r; 61 62 kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); 63 if (kt == NULL) 64 return; 65 if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { 66 warnx("kvm_read: %s", kvm_geterr(kvm)); 67 memset(&pcb, 0, sizeof(pcb)); 68 } 69 70 /* Registers 0-127: general registers. */ 71 supply_register(IA64_GR1_REGNUM, (char *)&pcb.pcb_special.gp); 72 supply_register(IA64_GR4_REGNUM, (char *)&pcb.pcb_preserved.gr4); 73 supply_register(IA64_GR5_REGNUM, (char *)&pcb.pcb_preserved.gr5); 74 supply_register(IA64_GR6_REGNUM, (char *)&pcb.pcb_preserved.gr6); 75 supply_register(IA64_GR7_REGNUM, (char *)&pcb.pcb_preserved.gr7); 76 supply_register(IA64_GR12_REGNUM, (char *)&pcb.pcb_special.sp); 77 supply_register(IA64_GR12_REGNUM+1, (char *)&pcb.pcb_special.tp); 78 79 /* Registers 128-255: floating-point registers. */ 80 supply_register(IA64_FR2_REGNUM, (char *)&pcb.pcb_preserved_fp.fr2); 81 supply_register(IA64_FR2_REGNUM+1, (char *)&pcb.pcb_preserved_fp.fr3); 82 supply_register(IA64_FR2_REGNUM+2, (char *)&pcb.pcb_preserved_fp.fr4); 83 supply_register(IA64_FR2_REGNUM+3, (char *)&pcb.pcb_preserved_fp.fr5); 84 supply_register(IA64_FR16_REGNUM, (char *)&pcb.pcb_preserved_fp.fr16); 85 supply_register(IA64_FR16_REGNUM+1, (char*)&pcb.pcb_preserved_fp.fr17); 86 supply_register(IA64_FR16_REGNUM+2, (char*)&pcb.pcb_preserved_fp.fr18); 87 supply_register(IA64_FR16_REGNUM+3, (char*)&pcb.pcb_preserved_fp.fr19); 88 supply_register(IA64_FR16_REGNUM+4, (char*)&pcb.pcb_preserved_fp.fr20); 89 supply_register(IA64_FR16_REGNUM+5, (char*)&pcb.pcb_preserved_fp.fr21); 90 supply_register(IA64_FR16_REGNUM+6, (char*)&pcb.pcb_preserved_fp.fr22); 91 supply_register(IA64_FR16_REGNUM+7, (char*)&pcb.pcb_preserved_fp.fr23); 92 supply_register(IA64_FR16_REGNUM+8, (char*)&pcb.pcb_preserved_fp.fr24); 93 supply_register(IA64_FR16_REGNUM+9, (char*)&pcb.pcb_preserved_fp.fr25); 94 supply_register(IA64_FR16_REGNUM+10,(char*)&pcb.pcb_preserved_fp.fr26); 95 supply_register(IA64_FR16_REGNUM+11,(char*)&pcb.pcb_preserved_fp.fr27); 96 supply_register(IA64_FR16_REGNUM+12,(char*)&pcb.pcb_preserved_fp.fr28); 97 supply_register(IA64_FR16_REGNUM+13,(char*)&pcb.pcb_preserved_fp.fr29); 98 supply_register(IA64_FR16_REGNUM+14,(char*)&pcb.pcb_preserved_fp.fr30); 99 supply_register(IA64_FR16_REGNUM+15,(char*)&pcb.pcb_preserved_fp.fr31); 100 101 /* Registers 320-327: branch registers. */ 102 if (pcb.pcb_special.__spare == ~0UL) 103 supply_register(IA64_BR0_REGNUM, (char *)&pcb.pcb_special.rp); 104 supply_register(IA64_BR1_REGNUM, (char *)&pcb.pcb_preserved.br1); 105 supply_register(IA64_BR2_REGNUM, (char *)&pcb.pcb_preserved.br2); 106 supply_register(IA64_BR3_REGNUM, (char *)&pcb.pcb_preserved.br3); 107 supply_register(IA64_BR4_REGNUM, (char *)&pcb.pcb_preserved.br4); 108 supply_register(IA64_BR5_REGNUM, (char *)&pcb.pcb_preserved.br5); 109 110 /* Registers 328-333: misc. other registers. */ 111 supply_register(IA64_PR_REGNUM, (char *)&pcb.pcb_special.pr); 112 if (pcb.pcb_special.__spare == ~0UL) { 113 r = pcb.pcb_special.iip + ((pcb.pcb_special.psr >> 41) & 3); 114 supply_register(IA64_IP_REGNUM, (char *)&r); 115 supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.cfm); 116 } else { 117 supply_register(IA64_IP_REGNUM, (char *)&pcb.pcb_special.rp); 118 supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.pfs); 119 } 120 121 /* Registers 334-461: application registers. */ 122 supply_register(IA64_RSC_REGNUM, (char *)&pcb.pcb_special.rsc); 123 r = pcb.pcb_special.bspstore; 124 if (pcb.pcb_special.__spare == ~0UL) 125 r += pcb.pcb_special.ndirty; 126 else 127 r = ia64_bsp_adjust(r, IA64_CFM_SOF(pcb.pcb_special.pfs) - 128 IA64_CFM_SOL(pcb.pcb_special.pfs)); 129 supply_register(IA64_BSP_REGNUM, (char *)&r); 130 supply_register(IA64_BSPSTORE_REGNUM, (char *)&r); 131 supply_register(IA64_RNAT_REGNUM, (char *)&pcb.pcb_special.rnat); 132 supply_register(IA64_UNAT_REGNUM, (char *)&pcb.pcb_special.unat); 133 supply_register(IA64_FPSR_REGNUM, (char *)&pcb.pcb_special.fpsr); 134 if (pcb.pcb_special.__spare == ~0UL) 135 supply_register(IA64_PFS_REGNUM, (char *)&pcb.pcb_special.pfs); 136 supply_register(IA64_LC_REGNUM, (char *)&pcb.pcb_preserved.lc); 137} 138 139void 140kgdb_trgt_store_registers(int regno __unused) 141{ 142 fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); 143} 144 145void 146kgdb_trgt_new_objfile(struct objfile *objfile) 147{ 148} 149 150struct kgdb_frame_cache { 151 CORE_ADDR bsp; 152 CORE_ADDR ip; 153 CORE_ADDR sp; 154 CORE_ADDR saved_bsp; 155}; 156 157#define SPECIAL(x) offsetof(struct trapframe, tf_special) \ 158 + offsetof(struct _special, x) 159#define SCRATCH(x) offsetof(struct trapframe, tf_scratch) \ 160 + offsetof(struct _caller_saved, x) 161#define SCRATCH_FP(x) offsetof(struct trapframe, tf_scratch_fp) \ 162 + offsetof(struct _caller_saved_fp, x) 163 164static int kgdb_trgt_frame_ofs_gr[32] = { 165 -1, /* gr0 */ 166 SPECIAL(gp), 167 SCRATCH(gr2), SCRATCH(gr3), 168 -1, -1, -1, -1, /* gr4-gr7 */ 169 SCRATCH(gr8), SCRATCH(gr9), SCRATCH(gr10), SCRATCH(gr11), 170 SPECIAL(sp), SPECIAL(tp), 171 SCRATCH(gr14), SCRATCH(gr15), SCRATCH(gr16), SCRATCH(gr17), 172 SCRATCH(gr18), SCRATCH(gr19), SCRATCH(gr20), SCRATCH(gr21), 173 SCRATCH(gr22), SCRATCH(gr23), SCRATCH(gr24), SCRATCH(gr25), 174 SCRATCH(gr26), SCRATCH(gr27), SCRATCH(gr28), SCRATCH(gr29), 175 SCRATCH(gr30), SCRATCH(gr31) 176}; 177 178static int kgdb_trgt_frame_ofs_fr[32] = { 179 -1, /* fr0: constant 0.0 */ 180 -1, /* fr1: constant 1.0 */ 181 -1, -1, -1, -1, /* fr2-fr5 */ 182 SCRATCH_FP(fr6), SCRATCH_FP(fr7), SCRATCH_FP(fr8), SCRATCH_FP(fr9), 183 SCRATCH_FP(fr10), SCRATCH_FP(fr11), SCRATCH_FP(fr12), SCRATCH_FP(fr13), 184 SCRATCH_FP(fr14), SCRATCH_FP(fr15) 185}; 186 187static int kgdb_trgt_frame_ofs_br[8] = { 188 SPECIAL(rp), 189 -1, -1, -1, -1, -1, /* br1-br5 */ 190 SCRATCH(br6), SCRATCH(br7) 191}; 192 193static int kgdb_trgt_frame_ofs_ar[49] = { 194 /* ar0-ar15 */ 195 SPECIAL(rsc), 196 -1, /* ar.bsp */ 197 SPECIAL(bspstore), SPECIAL(rnat), 198 -1, -1, -1, -1, -1, /* ar20-ar24 */ 199 SCRATCH(csd), SCRATCH(ssd), 200 -1, -1, -1, -1, -1, /* ar27-ar31 */ 201 SCRATCH(ccv), 202 -1, -1, -1, /* ar33-ar35 */ 203 SPECIAL(unat), 204 -1, -1, -1, /* ar37-ar39 */ 205 SPECIAL(fpsr), 206 -1, -1, -1, -1, -1, -1, -1, /* ar41-ar47 */ 207 -1, -1, -1, -1, -1, -1, -1, -1, /* ar48-ar55 */ 208 -1, -1, -1, -1, -1, -1, -1, -1, /* ar56-ar63 */ 209 SPECIAL(pfs) 210}; 211 212static struct kgdb_frame_cache * 213kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) 214{ 215 char buf[MAX_REGISTER_SIZE]; 216 struct kgdb_frame_cache *cache; 217 218 cache = *this_cache; 219 if (cache == NULL) { 220 cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); 221 *this_cache = cache; 222 frame_unwind_register(next_frame, IA64_BSP_REGNUM, buf); 223 cache->bsp = extract_unsigned_integer(buf, 224 register_size(current_gdbarch, IA64_BSP_REGNUM)); 225 cache->ip = frame_func_unwind(next_frame); 226 frame_unwind_register(next_frame, SP_REGNUM, buf); 227 cache->sp = extract_unsigned_integer(buf, 228 register_size(current_gdbarch, SP_REGNUM)); 229 } 230 return (cache); 231} 232 233static void 234kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, 235 struct frame_id *this_id) 236{ 237 struct kgdb_frame_cache *cache; 238 239 cache = kgdb_trgt_frame_cache(next_frame, this_cache); 240 *this_id = frame_id_build_special(cache->sp, cache->ip, cache->bsp); 241} 242 243static void 244kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, 245 void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, 246 CORE_ADDR *addrp, int *realnump, void *valuep) 247{ 248 char buf[MAX_REGISTER_SIZE]; 249 char dummy_valuep[MAX_REGISTER_SIZE]; 250 struct kgdb_frame_cache *cache; 251 CORE_ADDR bsp; 252 int ofs, regsz; 253 254 regsz = register_size(current_gdbarch, regnum); 255 256 if (valuep == NULL) 257 valuep = dummy_valuep; 258 memset(valuep, 0, regsz); 259 *optimizedp = 0; 260 *addrp = 0; 261 *lvalp = not_lval; 262 *realnump = -1; 263 264 cache = kgdb_trgt_frame_cache(next_frame, this_cache); 265 266 if (regnum == IA64_BSP_REGNUM) { 267 if (cache->saved_bsp == 0) { 268 target_read_memory(cache->sp + 16 + SPECIAL(bspstore), 269 buf, regsz); 270 bsp = extract_unsigned_integer(buf, regsz); 271 target_read_memory(cache->sp + 16 + SPECIAL(ndirty), 272 buf, regsz); 273 bsp += extract_unsigned_integer(buf, regsz); 274 cache->saved_bsp = bsp; 275 } 276 store_unsigned_integer(valuep, regsz, cache->saved_bsp); 277 return; 278 } 279 if (regnum == IA64_PR_REGNUM) 280 ofs = SPECIAL(pr); 281 else if (regnum == IA64_IP_REGNUM) 282 ofs = SPECIAL(iip); 283 else if (regnum == IA64_PSR_REGNUM) 284 ofs = SPECIAL(psr); 285 else if (regnum == IA64_CFM_REGNUM) 286 ofs = SPECIAL(cfm); 287 else if (regnum >= IA64_GR0_REGNUM && regnum <= IA64_GR31_REGNUM) 288 ofs = kgdb_trgt_frame_ofs_gr[regnum - IA64_GR0_REGNUM]; 289 else if (regnum >= IA64_FR0_REGNUM && regnum <= IA64_FR15_REGNUM) 290 ofs = kgdb_trgt_frame_ofs_fr[regnum - IA64_FR0_REGNUM]; 291 else if (regnum >= IA64_BR0_REGNUM && regnum <= IA64_BR7_REGNUM) 292 ofs = kgdb_trgt_frame_ofs_br[regnum - IA64_BR0_REGNUM]; 293 else if (regnum >= IA64_RSC_REGNUM && regnum <= IA64_PFS_REGNUM) 294 ofs = kgdb_trgt_frame_ofs_ar[regnum - IA64_RSC_REGNUM]; 295 else 296 ofs = -1; 297 if (ofs == -1) 298 return; 299 300 *addrp = cache->sp + 16 + ofs; 301 *lvalp = lval_memory; 302 target_read_memory(*addrp, valuep, regsz); 303} 304 305static const struct frame_unwind kgdb_trgt_trapframe_unwind = { 306 UNKNOWN_FRAME, 307 &kgdb_trgt_trapframe_this_id, 308 &kgdb_trgt_trapframe_prev_register 309}; 310 311const struct frame_unwind * 312kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) 313{ 314 char *pname; 315 CORE_ADDR ip; 316 317 ip = frame_func_unwind(next_frame); 318 pname = NULL; 319 find_pc_partial_function(ip, &pname, NULL, NULL); 320 if (pname == NULL) 321 return (NULL); 322 if (strncmp(pname, "ivt_", 4) == 0) 323 return (&kgdb_trgt_trapframe_unwind); 324 /* printf("%s: %lx =%s\n", __func__, ip, pname); */ 325 return (NULL); 326} 327