197403Sobrien/*- 297403Sobrien * Copyright (c) 2003-2005 Marcel Moolenaar 397403Sobrien * Copyright (c) 2000-2001 Doug Rabson 497403Sobrien * All rights reserved. 597403Sobrien * 697403Sobrien * Redistribution and use in source and binary forms, with or without 797403Sobrien * modification, are permitted provided that the following conditions 897403Sobrien * are met: 997403Sobrien * 1097403Sobrien * 1. Redistributions of source code must retain the above copyright 1197403Sobrien * notice, this list of conditions and the following disclaimer. 1297403Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1397403Sobrien * notice, this list of conditions and the following disclaimer in the 1497403Sobrien * documentation and/or other materials provided with the distribution. 1597403Sobrien * 1697403Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1797403Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1897403Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1997403Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2097403Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2197403Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2297403Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2397403Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2497403Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2597403Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2697403Sobrien * SUCH DAMAGE. 2797403Sobrien */ 2897403Sobrien 2997403Sobrien#include "opt_xtrace.h" 3097403Sobrien 3197403Sobrien#include <sys/cdefs.h> 3297403Sobrien__FBSDID("$FreeBSD$"); 3397403Sobrien 3497403Sobrien#include <sys/param.h> 3597403Sobrien#include <sys/systm.h> 3697403Sobrien#include <sys/cons.h> 3797403Sobrien#include <sys/kdb.h> 3897403Sobrien#include <sys/ktr.h> 3997403Sobrien#include <sys/kernel.h> 4097403Sobrien#include <sys/proc.h> 4197403Sobrien#include <sys/reboot.h> 4297403Sobrien#include <sys/smp.h> 4397403Sobrien#include <sys/stack.h> 4497403Sobrien 4597403Sobrien#include <vm/vm.h> 4697403Sobrien 4797403Sobrien#include <machine/db_machdep.h> 4897403Sobrien#include <machine/frame.h> 4997403Sobrien#include <machine/kdb.h> 5097403Sobrien#include <machine/md_var.h> 5197403Sobrien#include <machine/pcb.h> 5297403Sobrien#include <machine/setjmp.h> 5397403Sobrien#include <machine/unwind.h> 5497403Sobrien#include <machine/vmparam.h> 5597403Sobrien 5697403Sobrien#include <ddb/ddb.h> 5797403Sobrien#include <ddb/db_access.h> 5897403Sobrien#include <ddb/db_output.h> 5997403Sobrien#include <ddb/db_sym.h> 6097403Sobrien#include <ddb/db_variables.h> 6197403Sobrien 6297403Sobrien#include <ia64/disasm/disasm.h> 6397403Sobrien 6497403Sobrien#define TMPL_BITS 5 6597403Sobrien#define TMPL_MASK ((1 << TMPL_BITS) - 1) 6697403Sobrien#define SLOT_BITS 41 6797403Sobrien#define SLOT_COUNT 3 6897403Sobrien#define SLOT_MASK ((1ULL << SLOT_BITS) - 1ULL) 6997403Sobrien#define SLOT_SHIFT(i) (TMPL_BITS+((i)<<3)+(i)) 7097403Sobrien 7197403Sobrientypedef db_expr_t __db_f(db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t, 7297403Sobrien db_expr_t, db_expr_t, db_expr_t); 7397403Sobrien 7497403Sobrienregister uint64_t __db_gp __asm__("gp"); 7597403Sobrien 7697403Sobrienstatic db_varfcn_t db_frame; 7797403Sobrienstatic db_varfcn_t db_getip; 7897403Sobrienstatic db_varfcn_t db_getrse; 7997403Sobrien 8097403Sobrien#define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x) 8197403Sobrienstruct db_variable db_regs[] = { 8297403Sobrien {"ip", NULL, db_getip}, 8397403Sobrien {"cr.ifs", DB_OFFSET(tf_special.cfm), db_frame}, 8497403Sobrien {"cr.ifa", DB_OFFSET(tf_special.ifa), db_frame}, 8597403Sobrien {"ar.bspstore", DB_OFFSET(tf_special.bspstore), db_frame}, 8697403Sobrien {"ndirty", DB_OFFSET(tf_special.ndirty), db_frame}, 8797403Sobrien {"rp", DB_OFFSET(tf_special.rp), db_frame}, 8897403Sobrien {"ar.pfs", DB_OFFSET(tf_special.pfs), db_frame}, 8997403Sobrien {"psr", DB_OFFSET(tf_special.psr), db_frame}, 9097403Sobrien {"cr.isr", DB_OFFSET(tf_special.isr), db_frame}, 9197403Sobrien {"pr", DB_OFFSET(tf_special.pr), db_frame}, 9297403Sobrien {"ar.rsc", DB_OFFSET(tf_special.rsc), db_frame}, 9397403Sobrien {"ar.rnat", DB_OFFSET(tf_special.rnat), db_frame}, 9497403Sobrien {"ar.unat", DB_OFFSET(tf_special.unat), db_frame}, 9597403Sobrien {"ar.fpsr", DB_OFFSET(tf_special.fpsr), db_frame}, 9697403Sobrien {"gp", DB_OFFSET(tf_special.gp), db_frame}, 9797403Sobrien {"sp", DB_OFFSET(tf_special.sp), db_frame}, 9897403Sobrien {"tp", DB_OFFSET(tf_special.tp), db_frame}, 9997403Sobrien {"b6", DB_OFFSET(tf_scratch.br6), db_frame}, 10097403Sobrien {"b7", DB_OFFSET(tf_scratch.br7), db_frame}, 10197403Sobrien {"r2", DB_OFFSET(tf_scratch.gr2), db_frame}, 10297403Sobrien {"r3", DB_OFFSET(tf_scratch.gr3), db_frame}, 10397403Sobrien {"r8", DB_OFFSET(tf_scratch.gr8), db_frame}, 10497403Sobrien {"r9", DB_OFFSET(tf_scratch.gr9), db_frame}, 10597403Sobrien {"r10", DB_OFFSET(tf_scratch.gr10), db_frame}, 10697403Sobrien {"r11", DB_OFFSET(tf_scratch.gr11), db_frame}, 10797403Sobrien {"r14", DB_OFFSET(tf_scratch.gr14), db_frame}, 10897403Sobrien {"r15", DB_OFFSET(tf_scratch.gr15), db_frame}, 10997403Sobrien {"r16", DB_OFFSET(tf_scratch.gr16), db_frame}, 11097403Sobrien {"r17", DB_OFFSET(tf_scratch.gr17), db_frame}, 11197403Sobrien {"r18", DB_OFFSET(tf_scratch.gr18), db_frame}, 11297403Sobrien {"r19", DB_OFFSET(tf_scratch.gr19), db_frame}, 11397403Sobrien {"r20", DB_OFFSET(tf_scratch.gr20), db_frame}, 11497403Sobrien {"r21", DB_OFFSET(tf_scratch.gr21), db_frame}, 11597403Sobrien {"r22", DB_OFFSET(tf_scratch.gr22), db_frame}, 11697403Sobrien {"r23", DB_OFFSET(tf_scratch.gr23), db_frame}, 11797403Sobrien {"r24", DB_OFFSET(tf_scratch.gr24), db_frame}, 11897403Sobrien {"r25", DB_OFFSET(tf_scratch.gr25), db_frame}, 11997403Sobrien {"r26", DB_OFFSET(tf_scratch.gr26), db_frame}, 12097403Sobrien {"r27", DB_OFFSET(tf_scratch.gr27), db_frame}, 12197403Sobrien {"r28", DB_OFFSET(tf_scratch.gr28), db_frame}, 12297403Sobrien {"r29", DB_OFFSET(tf_scratch.gr29), db_frame}, 12397403Sobrien {"r30", DB_OFFSET(tf_scratch.gr30), db_frame}, 12497403Sobrien {"r31", DB_OFFSET(tf_scratch.gr31), db_frame}, 12597403Sobrien {"r32", (db_expr_t*)0, db_getrse}, 12697403Sobrien {"r33", (db_expr_t*)1, db_getrse}, 12797403Sobrien {"r34", (db_expr_t*)2, db_getrse}, 12897403Sobrien {"r35", (db_expr_t*)3, db_getrse}, 12997403Sobrien {"r36", (db_expr_t*)4, db_getrse}, 13097403Sobrien {"r37", (db_expr_t*)5, db_getrse}, 13197403Sobrien {"r38", (db_expr_t*)6, db_getrse}, 13297403Sobrien {"r39", (db_expr_t*)7, db_getrse}, 13397403Sobrien {"r40", (db_expr_t*)8, db_getrse}, 13497403Sobrien {"r41", (db_expr_t*)9, db_getrse}, 13597403Sobrien {"r42", (db_expr_t*)10, db_getrse}, 13697403Sobrien {"r43", (db_expr_t*)11, db_getrse}, 13797403Sobrien {"r44", (db_expr_t*)12, db_getrse}, 13897403Sobrien {"r45", (db_expr_t*)13, db_getrse}, 13997403Sobrien {"r46", (db_expr_t*)14, db_getrse}, 14097403Sobrien {"r47", (db_expr_t*)15, db_getrse}, 14197403Sobrien {"r48", (db_expr_t*)16, db_getrse}, 14297403Sobrien {"r49", (db_expr_t*)17, db_getrse}, 14397403Sobrien {"r50", (db_expr_t*)18, db_getrse}, 14497403Sobrien {"r51", (db_expr_t*)19, db_getrse}, 14597403Sobrien {"r52", (db_expr_t*)20, db_getrse}, 14697403Sobrien {"r53", (db_expr_t*)21, db_getrse}, 14797403Sobrien {"r54", (db_expr_t*)22, db_getrse}, 14897403Sobrien {"r55", (db_expr_t*)23, db_getrse}, 14997403Sobrien {"r56", (db_expr_t*)24, db_getrse}, 150 {"r57", (db_expr_t*)25, db_getrse}, 151 {"r58", (db_expr_t*)26, db_getrse}, 152 {"r59", (db_expr_t*)27, db_getrse}, 153 {"r60", (db_expr_t*)28, db_getrse}, 154 {"r61", (db_expr_t*)29, db_getrse}, 155 {"r62", (db_expr_t*)30, db_getrse}, 156 {"r63", (db_expr_t*)31, db_getrse}, 157 {"r64", (db_expr_t*)32, db_getrse}, 158 {"r65", (db_expr_t*)33, db_getrse}, 159 {"r66", (db_expr_t*)34, db_getrse}, 160 {"r67", (db_expr_t*)35, db_getrse}, 161 {"r68", (db_expr_t*)36, db_getrse}, 162 {"r69", (db_expr_t*)37, db_getrse}, 163 {"r70", (db_expr_t*)38, db_getrse}, 164 {"r71", (db_expr_t*)39, db_getrse}, 165 {"r72", (db_expr_t*)40, db_getrse}, 166 {"r73", (db_expr_t*)41, db_getrse}, 167 {"r74", (db_expr_t*)42, db_getrse}, 168 {"r75", (db_expr_t*)43, db_getrse}, 169 {"r76", (db_expr_t*)44, db_getrse}, 170 {"r77", (db_expr_t*)45, db_getrse}, 171 {"r78", (db_expr_t*)46, db_getrse}, 172 {"r79", (db_expr_t*)47, db_getrse}, 173 {"r80", (db_expr_t*)48, db_getrse}, 174 {"r81", (db_expr_t*)49, db_getrse}, 175 {"r82", (db_expr_t*)50, db_getrse}, 176 {"r83", (db_expr_t*)51, db_getrse}, 177 {"r84", (db_expr_t*)52, db_getrse}, 178 {"r85", (db_expr_t*)53, db_getrse}, 179 {"r86", (db_expr_t*)54, db_getrse}, 180 {"r87", (db_expr_t*)55, db_getrse}, 181 {"r88", (db_expr_t*)56, db_getrse}, 182 {"r89", (db_expr_t*)57, db_getrse}, 183 {"r90", (db_expr_t*)58, db_getrse}, 184 {"r91", (db_expr_t*)59, db_getrse}, 185 {"r92", (db_expr_t*)60, db_getrse}, 186 {"r93", (db_expr_t*)61, db_getrse}, 187 {"r94", (db_expr_t*)62, db_getrse}, 188 {"r95", (db_expr_t*)63, db_getrse}, 189 {"r96", (db_expr_t*)64, db_getrse}, 190 {"r97", (db_expr_t*)65, db_getrse}, 191 {"r98", (db_expr_t*)66, db_getrse}, 192 {"r99", (db_expr_t*)67, db_getrse}, 193 {"r100", (db_expr_t*)68, db_getrse}, 194 {"r101", (db_expr_t*)69, db_getrse}, 195 {"r102", (db_expr_t*)70, db_getrse}, 196 {"r103", (db_expr_t*)71, db_getrse}, 197 {"r104", (db_expr_t*)72, db_getrse}, 198 {"r105", (db_expr_t*)73, db_getrse}, 199 {"r106", (db_expr_t*)74, db_getrse}, 200 {"r107", (db_expr_t*)75, db_getrse}, 201 {"r108", (db_expr_t*)76, db_getrse}, 202 {"r109", (db_expr_t*)77, db_getrse}, 203 {"r110", (db_expr_t*)78, db_getrse}, 204 {"r111", (db_expr_t*)79, db_getrse}, 205 {"r112", (db_expr_t*)80, db_getrse}, 206 {"r113", (db_expr_t*)81, db_getrse}, 207 {"r114", (db_expr_t*)82, db_getrse}, 208 {"r115", (db_expr_t*)83, db_getrse}, 209 {"r116", (db_expr_t*)84, db_getrse}, 210 {"r117", (db_expr_t*)85, db_getrse}, 211 {"r118", (db_expr_t*)86, db_getrse}, 212 {"r119", (db_expr_t*)87, db_getrse}, 213 {"r120", (db_expr_t*)88, db_getrse}, 214 {"r121", (db_expr_t*)89, db_getrse}, 215 {"r122", (db_expr_t*)90, db_getrse}, 216 {"r123", (db_expr_t*)91, db_getrse}, 217 {"r124", (db_expr_t*)92, db_getrse}, 218 {"r125", (db_expr_t*)93, db_getrse}, 219 {"r126", (db_expr_t*)94, db_getrse}, 220 {"r127", (db_expr_t*)95, db_getrse}, 221}; 222struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]); 223 224static int 225db_backtrace(struct thread *td, struct pcb *pcb, int count) 226{ 227 struct unw_regstate rs; 228 struct trapframe *tf; 229 const char *name; 230 db_expr_t offset; 231 uint64_t bsp, cfm, ip, pfs, reg, sp; 232 c_db_sym_t sym; 233 int args, error, i; 234 235 error = unw_create_from_pcb(&rs, pcb); 236 while (!error && count-- && !db_pager_quit) { 237 error = unw_get_cfm(&rs, &cfm); 238 if (!error) 239 error = unw_get_bsp(&rs, &bsp); 240 if (!error) 241 error = unw_get_ip(&rs, &ip); 242 if (!error) 243 error = unw_get_sp(&rs, &sp); 244 if (error) 245 break; 246 247 args = IA64_CFM_SOL(cfm); 248 if (args > 8) 249 args = 8; 250 251 error = unw_step(&rs); 252 if (!error) { 253 if (!unw_get_cfm(&rs, &pfs)) { 254 i = IA64_CFM_SOF(pfs) - IA64_CFM_SOL(pfs); 255 if (args > i) 256 args = i; 257 } 258 } 259 260 sym = db_search_symbol(ip, DB_STGY_ANY, &offset); 261 db_symbol_values(sym, &name, NULL); 262 db_printf("%s(", name); 263 if (bsp >= VM_MAXUSER_ADDRESS) { 264 for (i = 0; i < args; i++) { 265 if ((bsp & 0x1ff) == 0x1f8) 266 bsp += 8; 267 db_read_bytes(bsp, sizeof(reg), (void*)®); 268 if (i > 0) 269 db_printf(", "); 270 db_printf("0x%lx", reg); 271 bsp += 8; 272 } 273 } else 274 db_printf("..."); 275 db_printf(") at "); 276 277 db_printsym(ip, DB_STGY_PROC); 278 db_printf("\n"); 279 280 if (error != ERESTART) 281 continue; 282 if (sp < VM_MAXUSER_ADDRESS) 283 break; 284 285 tf = (struct trapframe *)(sp + 16); 286 if ((tf->tf_flags & FRAME_SYSCALL) != 0 || 287 tf->tf_special.iip < VM_MAXUSER_ADDRESS) 288 break; 289 290 /* XXX ask if we should unwind across the trapframe. */ 291 db_printf("--- trapframe at %p\n", tf); 292 unw_delete(&rs); 293 error = unw_create_from_frame(&rs, tf); 294 } 295 296 unw_delete(&rs); 297 /* 298 * EJUSTRETURN and ERESTART signal the end of a trace and 299 * are not really errors. 300 */ 301 return ((error > 0) ? error : 0); 302} 303 304void 305db_bkpt_clear(db_addr_t addr, BKPT_INST_TYPE *storage) 306{ 307 BKPT_INST_TYPE tmp; 308 db_addr_t loc; 309 int slot; 310 311 slot = addr & 0xfUL; 312 if (slot >= SLOT_COUNT) 313 return; 314 loc = (addr & ~0xfUL) + (slot << 2); 315 316 db_read_bytes(loc, sizeof(BKPT_INST_TYPE), (char *)&tmp); 317 tmp &= ~(SLOT_MASK << SLOT_SHIFT(slot)); 318 tmp |= *storage << SLOT_SHIFT(slot); 319 db_write_bytes(loc, sizeof(BKPT_INST_TYPE), (char *)&tmp); 320} 321 322void 323db_bkpt_skip(void) 324{ 325 326 if (kdb_frame == NULL) 327 return; 328 329 kdb_frame->tf_special.psr += IA64_PSR_RI_1; 330 if ((kdb_frame->tf_special.psr & IA64_PSR_RI) > IA64_PSR_RI_2) { 331 kdb_frame->tf_special.psr &= ~IA64_PSR_RI; 332 kdb_frame->tf_special.iip += 16; 333 } 334} 335 336void 337db_bkpt_write(db_addr_t addr, BKPT_INST_TYPE *storage) 338{ 339 BKPT_INST_TYPE tmp; 340 db_addr_t loc; 341 int slot; 342 343 slot = addr & 0xfUL; 344 if (slot >= SLOT_COUNT) 345 return; 346 loc = (addr & ~0xfUL) + (slot << 2); 347 348 db_read_bytes(loc, sizeof(BKPT_INST_TYPE), (char *)&tmp); 349 *storage = (tmp >> SLOT_SHIFT(slot)) & SLOT_MASK; 350 351 tmp &= ~(SLOT_MASK << SLOT_SHIFT(slot)); 352 tmp |= (0x84000 << 6) << SLOT_SHIFT(slot); 353 db_write_bytes(loc, sizeof(BKPT_INST_TYPE), (char *)&tmp); 354} 355 356db_addr_t 357db_disasm(db_addr_t loc, boolean_t altfmt) 358{ 359 char buf[32]; 360 struct asm_bundle bundle; 361 const struct asm_inst *i; 362 const char *tmpl; 363 int n, slot; 364 365 slot = loc & 0xf; 366 loc &= ~0xful; 367 db_read_bytes(loc, 16, buf); 368 if (asm_decode((uintptr_t)buf, &bundle)) { 369 i = bundle.b_inst + slot; 370 tmpl = bundle.b_templ + slot; 371 if (*tmpl == ';' || (slot == 2 && bundle.b_templ[1] == ';')) 372 tmpl++; 373 if (*tmpl == 'L' || i->i_op == ASM_OP_NONE) { 374 db_printf("\n"); 375 goto out; 376 } 377 378 /* Unit + slot. */ 379 db_printf("[%c%d] ", *tmpl, slot); 380 381 /* Predicate. */ 382 if (i->i_oper[0].o_value != 0) { 383 asm_operand(i->i_oper+0, buf, loc); 384 db_printf("(%s) ", buf); 385 } else 386 db_printf(" "); 387 388 /* Mnemonic & completers. */ 389 asm_mnemonic(i->i_op, buf); 390 db_printf(buf); 391 n = 0; 392 while (n < i->i_ncmpltrs) { 393 asm_completer(i->i_cmpltr + n, buf); 394 db_printf(buf); 395 n++; 396 } 397 db_printf(" "); 398 399 /* Operands. */ 400 n = 1; 401 while (n < 7 && i->i_oper[n].o_type != ASM_OPER_NONE) { 402 if (n > 1) { 403 if (n == i->i_srcidx) 404 db_printf("="); 405 else 406 db_printf(","); 407 } 408 asm_operand(i->i_oper + n, buf, loc); 409 db_printf(buf); 410 n++; 411 } 412 if (tmpl[1] == ';') 413 db_printf(" ;;"); 414 } else { 415 tmpl = NULL; 416 slot = 2; 417 } 418 db_printf("\n"); 419 420out: 421 slot++; 422 if (slot == 1 && tmpl[1] == 'L') 423 slot++; 424 if (slot > 2) 425 slot = 16; 426 return (loc + slot); 427} 428 429int 430db_fncall_ia64(db_expr_t addr, db_expr_t *rv, int nargs, db_expr_t args[]) 431{ 432 struct ia64_fdesc fdesc; 433 __db_f *f; 434 435 f = (__db_f *)&fdesc; 436 fdesc.func = addr; 437 fdesc.gp = __db_gp; /* XXX doesn't work for modules. */ 438 *rv = (*f)(args[0], args[1], args[2], args[3], args[4], args[5], 439 args[6], args[7]); 440 return (1); 441} 442 443static int 444db_frame(struct db_variable *vp, db_expr_t *valuep, int op) 445{ 446 uint64_t *reg; 447 448 if (kdb_frame == NULL) 449 return (0); 450 reg = (uint64_t*)((uintptr_t)kdb_frame + (uintptr_t)vp->valuep); 451 if (op == DB_VAR_GET) 452 *valuep = *reg; 453 else 454 *reg = *valuep; 455 return (1); 456} 457 458static int 459db_getip(struct db_variable *vp, db_expr_t *valuep, int op) 460{ 461 u_long iip, slot; 462 463 if (kdb_frame == NULL) 464 return (0); 465 466 if (op == DB_VAR_GET) { 467 iip = kdb_frame->tf_special.iip; 468 slot = (kdb_frame->tf_special.psr >> 41) & 3; 469 *valuep = iip + slot; 470 } else { 471 iip = *valuep & ~0xf; 472 slot = *valuep & 0xf; 473 if (slot > 2) 474 return (0); 475 kdb_frame->tf_special.iip = iip; 476 kdb_frame->tf_special.psr &= ~IA64_PSR_RI; 477 kdb_frame->tf_special.psr |= slot << 41; 478 } 479 return (1); 480} 481 482static int 483db_getrse(struct db_variable *vp, db_expr_t *valuep, int op) 484{ 485 u_int64_t *reg; 486 uint64_t bsp; 487 int nats, regno, sof; 488 489 if (kdb_frame == NULL) 490 return (0); 491 492 regno = (int)(intptr_t)valuep; 493 bsp = kdb_frame->tf_special.bspstore + kdb_frame->tf_special.ndirty; 494 sof = (int)(kdb_frame->tf_special.cfm & 0x7f); 495 496 if (regno >= sof) 497 return (0); 498 499 nats = (sof - regno + 63 - ((int)(bsp >> 3) & 0x3f)) / 63; 500 reg = (void*)(bsp - ((sof - regno + nats) << 3)); 501 if (op == DB_VAR_GET) 502 *valuep = *reg; 503 else 504 *reg = *valuep; 505 return (1); 506} 507 508int 509db_md_clr_watchpoint(db_expr_t addr, db_expr_t size) 510{ 511 512 return (-1); 513} 514 515void 516db_md_list_watchpoints() 517{ 518 519 return; 520} 521 522int 523db_md_set_watchpoint(db_expr_t addr, db_expr_t size) 524{ 525 526 return (-1); 527} 528 529/* 530 * Read bytes from kernel address space for debugger. 531 */ 532int 533db_read_bytes(vm_offset_t addr, size_t size, char *data) 534{ 535 jmp_buf jb; 536 void *prev_jb; 537 char *src; 538 int ret; 539 540 prev_jb = kdb_jmpbuf(jb); 541 ret = setjmp(jb); 542 if (ret == 0) { 543 src = (char *)addr; 544 while (size-- > 0) 545 *data++ = *src++; 546 } 547 (void)kdb_jmpbuf(prev_jb); 548 return (ret); 549} 550 551/* 552 * Write bytes to kernel address space for debugger. 553 */ 554int 555db_write_bytes(vm_offset_t addr, size_t size, char *data) 556{ 557 jmp_buf jb; 558 void *prev_jb; 559 size_t cnt; 560 char *dst; 561 int ret; 562 563 prev_jb = kdb_jmpbuf(jb); 564 ret = setjmp(jb); 565 if (ret == 0) { 566 dst = (char *)addr; 567 cnt = size; 568 while (cnt-- > 0) 569 *dst++ = *data++; 570 kdb_cpu_sync_icache((void *)addr, size); 571 } 572 (void)kdb_jmpbuf(prev_jb); 573 return (ret); 574} 575 576void 577db_show_mdpcpu(struct pcpu *pc) 578{ 579 struct pcpu_md *md = &pc->pc_md; 580 581 db_printf("MD: vhpt = %#lx\n", md->vhpt); 582 db_printf("MD: lid = %#lx\n", md->lid); 583 db_printf("MD: clock = %#lx\n", md->clock); 584 db_printf("MD: clock_mode = %u\n", md->clock_mode); 585 db_printf("MD: clock_load = %#lx\n", md->clock_load); 586 db_printf("MD: stats = %p\n", &md->stats); 587 db_printf("MD: pmap = %p\n", md->current_pmap); 588#ifdef XTRACE 589 db_printf("MD: xtrace_buffer = %p\n", md->xtrace_buffer); 590 db_printf("MD: xtrace_tail = %#lx\n", md->xtrace_tail); 591#endif 592} 593 594void 595db_trace_self(void) 596{ 597 struct pcb pcb; 598 599 savectx(&pcb); 600 db_backtrace(curthread, &pcb, -1); 601} 602 603int 604db_trace_thread(struct thread *td, int count) 605{ 606 struct pcb *ctx; 607 608 ctx = kdb_thr_ctx(td); 609 return (db_backtrace(td, ctx, count)); 610} 611