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 55CORE_ADDR 56kgdb_trgt_core_pcb(u_int cpuid) 57{ 58 CORE_ADDR addr; 59 char *expr; 60 61 asprintf(&expr, "&cpuid_to_pcpu[%d]->pc_md.pcb", cpuid); 62 addr = kgdb_parse(expr); 63 free(expr); 64 return (addr); 65} 66 67void 68kgdb_trgt_fetch_registers(int regno __unused) 69{ 70 struct kthr *kt; 71 struct pcb pcb; 72 uint64_t r; 73 74 kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); 75 if (kt == NULL) 76 return; 77 if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) { 78 warnx("kvm_read: %s", kvm_geterr(kvm)); 79 memset(&pcb, 0, sizeof(pcb)); 80 } 81 82 /* Registers 0-127: general registers. */ 83 supply_register(IA64_GR1_REGNUM, (char *)&pcb.pcb_special.gp); 84 supply_register(IA64_GR4_REGNUM, (char *)&pcb.pcb_preserved.gr4); 85 supply_register(IA64_GR5_REGNUM, (char *)&pcb.pcb_preserved.gr5); 86 supply_register(IA64_GR6_REGNUM, (char *)&pcb.pcb_preserved.gr6); 87 supply_register(IA64_GR7_REGNUM, (char *)&pcb.pcb_preserved.gr7); 88 supply_register(IA64_GR12_REGNUM, (char *)&pcb.pcb_special.sp); 89 supply_register(IA64_GR12_REGNUM+1, (char *)&pcb.pcb_special.tp); 90 91 /* Registers 128-255: floating-point registers. */ 92 supply_register(IA64_FR2_REGNUM, (char *)&pcb.pcb_preserved_fp.fr2); 93 supply_register(IA64_FR2_REGNUM+1, (char *)&pcb.pcb_preserved_fp.fr3); 94 supply_register(IA64_FR2_REGNUM+2, (char *)&pcb.pcb_preserved_fp.fr4); 95 supply_register(IA64_FR2_REGNUM+3, (char *)&pcb.pcb_preserved_fp.fr5); 96 supply_register(IA64_FR16_REGNUM, (char *)&pcb.pcb_preserved_fp.fr16); 97 supply_register(IA64_FR16_REGNUM+1, (char*)&pcb.pcb_preserved_fp.fr17); 98 supply_register(IA64_FR16_REGNUM+2, (char*)&pcb.pcb_preserved_fp.fr18); 99 supply_register(IA64_FR16_REGNUM+3, (char*)&pcb.pcb_preserved_fp.fr19); 100 supply_register(IA64_FR16_REGNUM+4, (char*)&pcb.pcb_preserved_fp.fr20); 101 supply_register(IA64_FR16_REGNUM+5, (char*)&pcb.pcb_preserved_fp.fr21); 102 supply_register(IA64_FR16_REGNUM+6, (char*)&pcb.pcb_preserved_fp.fr22); 103 supply_register(IA64_FR16_REGNUM+7, (char*)&pcb.pcb_preserved_fp.fr23); 104 supply_register(IA64_FR16_REGNUM+8, (char*)&pcb.pcb_preserved_fp.fr24); 105 supply_register(IA64_FR16_REGNUM+9, (char*)&pcb.pcb_preserved_fp.fr25); 106 supply_register(IA64_FR16_REGNUM+10,(char*)&pcb.pcb_preserved_fp.fr26); 107 supply_register(IA64_FR16_REGNUM+11,(char*)&pcb.pcb_preserved_fp.fr27); 108 supply_register(IA64_FR16_REGNUM+12,(char*)&pcb.pcb_preserved_fp.fr28); 109 supply_register(IA64_FR16_REGNUM+13,(char*)&pcb.pcb_preserved_fp.fr29); 110 supply_register(IA64_FR16_REGNUM+14,(char*)&pcb.pcb_preserved_fp.fr30); 111 supply_register(IA64_FR16_REGNUM+15,(char*)&pcb.pcb_preserved_fp.fr31); 112 113 /* Registers 320-327: branch registers. */ 114 if (pcb.pcb_special.__spare == ~0UL) 115 supply_register(IA64_BR0_REGNUM, (char *)&pcb.pcb_special.rp); 116 supply_register(IA64_BR1_REGNUM, (char *)&pcb.pcb_preserved.br1); 117 supply_register(IA64_BR2_REGNUM, (char *)&pcb.pcb_preserved.br2); 118 supply_register(IA64_BR3_REGNUM, (char *)&pcb.pcb_preserved.br3); 119 supply_register(IA64_BR4_REGNUM, (char *)&pcb.pcb_preserved.br4); 120 supply_register(IA64_BR5_REGNUM, (char *)&pcb.pcb_preserved.br5); 121 122 /* Registers 328-333: misc. other registers. */ 123 supply_register(IA64_PR_REGNUM, (char *)&pcb.pcb_special.pr); 124 if (pcb.pcb_special.__spare == ~0UL) { 125 r = pcb.pcb_special.iip + ((pcb.pcb_special.psr >> 41) & 3); 126 supply_register(IA64_IP_REGNUM, (char *)&r); 127 supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.cfm); 128 } else { 129 supply_register(IA64_IP_REGNUM, (char *)&pcb.pcb_special.rp); 130 supply_register(IA64_CFM_REGNUM, (char *)&pcb.pcb_special.pfs); 131 } 132 133 /* Registers 334-461: application registers. */ 134 supply_register(IA64_RSC_REGNUM, (char *)&pcb.pcb_special.rsc); 135 r = pcb.pcb_special.bspstore; 136 if (pcb.pcb_special.__spare == ~0UL) 137 r += pcb.pcb_special.ndirty; 138 else 139 r = ia64_bsp_adjust(r, IA64_CFM_SOF(pcb.pcb_special.pfs) - 140 IA64_CFM_SOL(pcb.pcb_special.pfs)); 141 supply_register(IA64_BSP_REGNUM, (char *)&r); 142 supply_register(IA64_BSPSTORE_REGNUM, (char *)&r); 143 supply_register(IA64_RNAT_REGNUM, (char *)&pcb.pcb_special.rnat); 144 supply_register(IA64_UNAT_REGNUM, (char *)&pcb.pcb_special.unat); 145 supply_register(IA64_FPSR_REGNUM, (char *)&pcb.pcb_special.fpsr); 146 if (pcb.pcb_special.__spare == ~0UL) 147 supply_register(IA64_PFS_REGNUM, (char *)&pcb.pcb_special.pfs); 148 supply_register(IA64_LC_REGNUM, (char *)&pcb.pcb_preserved.lc); 149} 150 151void 152kgdb_trgt_store_registers(int regno __unused) 153{ 154 fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__); 155} 156 157void 158kgdb_trgt_new_objfile(struct objfile *objfile) 159{ 160} 161 162struct kgdb_frame_cache { 163 CORE_ADDR bsp; 164 CORE_ADDR ip; 165 CORE_ADDR sp; 166 CORE_ADDR saved_bsp; 167}; 168 169#define SPECIAL(x) offsetof(struct trapframe, tf_special) \ 170 + offsetof(struct _special, x) 171#define SCRATCH(x) offsetof(struct trapframe, tf_scratch) \ 172 + offsetof(struct _caller_saved, x) 173#define SCRATCH_FP(x) offsetof(struct trapframe, tf_scratch_fp) \ 174 + offsetof(struct _caller_saved_fp, x) 175 176static int kgdb_trgt_frame_ofs_gr[32] = { 177 -1, /* gr0 */ 178 SPECIAL(gp), 179 SCRATCH(gr2), SCRATCH(gr3), 180 -1, -1, -1, -1, /* gr4-gr7 */ 181 SCRATCH(gr8), SCRATCH(gr9), SCRATCH(gr10), SCRATCH(gr11), 182 SPECIAL(sp), SPECIAL(tp), 183 SCRATCH(gr14), SCRATCH(gr15), SCRATCH(gr16), SCRATCH(gr17), 184 SCRATCH(gr18), SCRATCH(gr19), SCRATCH(gr20), SCRATCH(gr21), 185 SCRATCH(gr22), SCRATCH(gr23), SCRATCH(gr24), SCRATCH(gr25), 186 SCRATCH(gr26), SCRATCH(gr27), SCRATCH(gr28), SCRATCH(gr29), 187 SCRATCH(gr30), SCRATCH(gr31) 188}; 189 190static int kgdb_trgt_frame_ofs_fr[32] = { 191 -1, /* fr0: constant 0.0 */ 192 -1, /* fr1: constant 1.0 */ 193 -1, -1, -1, -1, /* fr2-fr5 */ 194 SCRATCH_FP(fr6), SCRATCH_FP(fr7), SCRATCH_FP(fr8), SCRATCH_FP(fr9), 195 SCRATCH_FP(fr10), SCRATCH_FP(fr11), SCRATCH_FP(fr12), SCRATCH_FP(fr13), 196 SCRATCH_FP(fr14), SCRATCH_FP(fr15) 197}; 198 199static int kgdb_trgt_frame_ofs_br[8] = { 200 SPECIAL(rp), 201 -1, -1, -1, -1, -1, /* br1-br5 */ 202 SCRATCH(br6), SCRATCH(br7) 203}; 204 205static int kgdb_trgt_frame_ofs_ar[49] = { 206 /* ar0-ar15 */ 207 SPECIAL(rsc), 208 -1, /* ar.bsp */ 209 SPECIAL(bspstore), SPECIAL(rnat), 210 -1, -1, -1, -1, -1, /* ar20-ar24 */ 211 SCRATCH(csd), SCRATCH(ssd), 212 -1, -1, -1, -1, -1, /* ar27-ar31 */ 213 SCRATCH(ccv), 214 -1, -1, -1, /* ar33-ar35 */ 215 SPECIAL(unat), 216 -1, -1, -1, /* ar37-ar39 */ 217 SPECIAL(fpsr), 218 -1, -1, -1, -1, -1, -1, -1, /* ar41-ar47 */ 219 -1, -1, -1, -1, -1, -1, -1, -1, /* ar48-ar55 */ 220 -1, -1, -1, -1, -1, -1, -1, -1, /* ar56-ar63 */ 221 SPECIAL(pfs) 222}; 223 224static struct kgdb_frame_cache * 225kgdb_trgt_frame_cache(struct frame_info *next_frame, void **this_cache) 226{ 227 char buf[MAX_REGISTER_SIZE]; 228 struct kgdb_frame_cache *cache; 229 230 cache = *this_cache; 231 if (cache == NULL) { 232 cache = FRAME_OBSTACK_ZALLOC(struct kgdb_frame_cache); 233 *this_cache = cache; 234 frame_unwind_register(next_frame, IA64_BSP_REGNUM, buf); 235 cache->bsp = extract_unsigned_integer(buf, 236 register_size(current_gdbarch, IA64_BSP_REGNUM)); 237 cache->ip = frame_func_unwind(next_frame); 238 frame_unwind_register(next_frame, SP_REGNUM, buf); 239 cache->sp = extract_unsigned_integer(buf, 240 register_size(current_gdbarch, SP_REGNUM)); 241 } 242 return (cache); 243} 244 245static void 246kgdb_trgt_trapframe_this_id(struct frame_info *next_frame, void **this_cache, 247 struct frame_id *this_id) 248{ 249 struct kgdb_frame_cache *cache; 250 251 cache = kgdb_trgt_frame_cache(next_frame, this_cache); 252 *this_id = frame_id_build_special(cache->sp, cache->ip, cache->bsp); 253} 254 255static void 256kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame, 257 void **this_cache, int regnum, int *optimizedp, enum lval_type *lvalp, 258 CORE_ADDR *addrp, int *realnump, void *valuep) 259{ 260 char buf[MAX_REGISTER_SIZE]; 261 char dummy_valuep[MAX_REGISTER_SIZE]; 262 struct kgdb_frame_cache *cache; 263 CORE_ADDR bsp; 264 int ofs, regsz; 265 266 regsz = register_size(current_gdbarch, regnum); 267 268 if (valuep == NULL) 269 valuep = dummy_valuep; 270 memset(valuep, 0, regsz); 271 *optimizedp = 0; 272 *addrp = 0; 273 *lvalp = not_lval; 274 *realnump = -1; 275 276 cache = kgdb_trgt_frame_cache(next_frame, this_cache); 277 278 if (regnum == IA64_BSP_REGNUM) { 279 if (cache->saved_bsp == 0) { 280 target_read_memory(cache->sp + 16 + SPECIAL(bspstore), 281 buf, regsz); 282 bsp = extract_unsigned_integer(buf, regsz); 283 target_read_memory(cache->sp + 16 + SPECIAL(ndirty), 284 buf, regsz); 285 bsp += extract_unsigned_integer(buf, regsz); 286 cache->saved_bsp = bsp; 287 } 288 store_unsigned_integer(valuep, regsz, cache->saved_bsp); 289 return; 290 } 291 if (regnum == IA64_PR_REGNUM) 292 ofs = SPECIAL(pr); 293 else if (regnum == IA64_IP_REGNUM) 294 ofs = SPECIAL(iip); 295 else if (regnum == IA64_PSR_REGNUM) 296 ofs = SPECIAL(psr); 297 else if (regnum == IA64_CFM_REGNUM) 298 ofs = SPECIAL(cfm); 299 else if (regnum >= IA64_GR0_REGNUM && regnum <= IA64_GR31_REGNUM) 300 ofs = kgdb_trgt_frame_ofs_gr[regnum - IA64_GR0_REGNUM]; 301 else if (regnum >= IA64_FR0_REGNUM && regnum <= IA64_FR15_REGNUM) 302 ofs = kgdb_trgt_frame_ofs_fr[regnum - IA64_FR0_REGNUM]; 303 else if (regnum >= IA64_BR0_REGNUM && regnum <= IA64_BR7_REGNUM) 304 ofs = kgdb_trgt_frame_ofs_br[regnum - IA64_BR0_REGNUM]; 305 else if (regnum >= IA64_RSC_REGNUM && regnum <= IA64_PFS_REGNUM) 306 ofs = kgdb_trgt_frame_ofs_ar[regnum - IA64_RSC_REGNUM]; 307 else 308 ofs = -1; 309 if (ofs == -1) 310 return; 311 312 *addrp = cache->sp + 16 + ofs; 313 *lvalp = lval_memory; 314 target_read_memory(*addrp, valuep, regsz); 315} 316 317static const struct frame_unwind kgdb_trgt_trapframe_unwind = { 318 UNKNOWN_FRAME, 319 &kgdb_trgt_trapframe_this_id, 320 &kgdb_trgt_trapframe_prev_register 321}; 322 323const struct frame_unwind * 324kgdb_trgt_trapframe_sniffer(struct frame_info *next_frame) 325{ 326 char *pname; 327 CORE_ADDR ip; 328 329 ip = frame_func_unwind(next_frame); 330 pname = NULL; 331 find_pc_partial_function(ip, &pname, NULL, NULL); 332 if (pname == NULL) 333 return (NULL); 334 if (strncmp(pname, "ivt_", 4) == 0) 335 return (&kgdb_trgt_trapframe_unwind); 336 /* printf("%s: %lx =%s\n", __func__, ip, pname); */ 337 return (NULL); 338} 339