Implement a simple stack trace for DDB. This will have to be redone
if/when we change to a more modern toolchain.
This commit is contained in:
parent
a7c7f132de
commit
9bdbf65c26
@ -239,8 +239,8 @@ rse_slot(u_int64_t *bsp)
|
||||
* Return the address of register regno (regno >= 32) given that bsp
|
||||
* points at the base of the register stack frame.
|
||||
*/
|
||||
static u_int64_t *
|
||||
rse_register_address(u_int64_t *bsp, int regno)
|
||||
u_int64_t *
|
||||
db_rse_register_address(u_int64_t *bsp, int regno)
|
||||
{
|
||||
int off = regno - 32;
|
||||
u_int64_t rnats = (rse_slot(bsp) + off) / 63;
|
||||
@ -248,8 +248,17 @@ rse_register_address(u_int64_t *bsp, int regno)
|
||||
return p;
|
||||
}
|
||||
|
||||
static u_int64_t *
|
||||
rse_previous_frame(u_int64_t *bsp, int sof)
|
||||
u_int64_t *
|
||||
db_rse_current_frame()
|
||||
{
|
||||
int sof = ddb_regs.tf_cr_ifs & 0x7f;
|
||||
u_int64_t *bsp = (u_int64_t *)
|
||||
(ddb_regs.tf_ar_bspstore + ddb_regs.tf_ndirty);
|
||||
return db_rse_previous_frame(bsp, sof);
|
||||
}
|
||||
|
||||
u_int64_t *
|
||||
db_rse_previous_frame(u_int64_t *bsp, int sof)
|
||||
{
|
||||
int slot = rse_slot(bsp);
|
||||
int rnats = 0;
|
||||
@ -266,7 +275,7 @@ rse_previous_frame(u_int64_t *bsp, int sof)
|
||||
static int
|
||||
db_get_rse_reg(struct db_variable *vp, db_expr_t *valuep, int op)
|
||||
{
|
||||
int sof = ddb_regs.tf_cr_ifs & 0xff;
|
||||
int sof = ddb_regs.tf_cr_ifs & 0x7f;
|
||||
int regno = (db_expr_t) vp->valuep;
|
||||
u_int64_t *bsp = (u_int64_t *) (ddb_regs.tf_ar_bspstore + ddb_regs.tf_ndirty);
|
||||
u_int64_t *reg;
|
||||
@ -275,8 +284,8 @@ db_get_rse_reg(struct db_variable *vp, db_expr_t *valuep, int op)
|
||||
if (op == DB_VAR_GET)
|
||||
*valuep = 0xdeadbeefdeadbeef;
|
||||
} else {
|
||||
bsp = rse_previous_frame(bsp, sof);
|
||||
reg = rse_register_address(bsp, regno);
|
||||
bsp = db_rse_previous_frame(bsp, sof);
|
||||
reg = db_rse_register_address(bsp, regno);
|
||||
if (op == DB_VAR_GET)
|
||||
*valuep = *reg;
|
||||
else
|
||||
@ -444,15 +453,15 @@ db_register_value(regs, regno)
|
||||
if (regno < 32) {
|
||||
return (regs->tf_r[regno - 1]);
|
||||
} else {
|
||||
int sof = ddb_regs.tf_cr_ifs & 0xff;
|
||||
int sof = ddb_regs.tf_cr_ifs & 0x7f;
|
||||
u_int64_t *bsp = (u_int64_t *) (ddb_regs.tf_ar_bspstore + ddb_regs.tf_ndirty);
|
||||
u_int64_t *reg;
|
||||
|
||||
if (regno - 32 >= sof) {
|
||||
return 0xdeadbeefdeadbeef;
|
||||
} else {
|
||||
bsp = rse_previous_frame(bsp, sof);
|
||||
reg = rse_register_address(bsp, regno);
|
||||
bsp = db_rse_previous_frame(bsp, sof);
|
||||
reg = db_rse_register_address(bsp, regno);
|
||||
return *reg;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2000 Doug Rabson
|
||||
* Copyright (c) 2000-2001 Doug Rabson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -39,4 +39,48 @@
|
||||
void
|
||||
db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif)
|
||||
{
|
||||
db_addr_t callpc;
|
||||
u_int64_t *bsp;
|
||||
int sof, sol;
|
||||
|
||||
if (count == -1)
|
||||
count = 65535;
|
||||
|
||||
if (!have_addr) {
|
||||
callpc = (db_addr_t)ddb_regs.tf_cr_iip;
|
||||
bsp = db_rse_current_frame();
|
||||
sof = ddb_regs.tf_cr_ifs & 0x7f;
|
||||
sol = (ddb_regs.tf_cr_ifs >> 7) & 0x7f;
|
||||
} else {
|
||||
callpc = 0; /* XXX */
|
||||
bsp = 0; /* XXX */
|
||||
sof = 0; /* XXX */
|
||||
sol = 0; /* XXX */
|
||||
}
|
||||
|
||||
while (count--) {
|
||||
const char * name;
|
||||
db_expr_t offset;
|
||||
c_db_sym_t sym;
|
||||
u_int64_t ar_pfs;
|
||||
|
||||
sym = db_search_symbol(callpc, DB_STGY_ANY, &offset);
|
||||
db_symbol_values(sym, &name, NULL);
|
||||
|
||||
db_printf("%s() at ", name);
|
||||
db_printsym(callpc, DB_STGY_PROC);
|
||||
db_printf("\n");
|
||||
|
||||
/*
|
||||
* XXX this assumes the simplistic stack frames used
|
||||
* by the old toolchain.
|
||||
*/
|
||||
ar_pfs = *db_rse_register_address(bsp, 32 + sol - 1);
|
||||
callpc = *db_rse_register_address(bsp, 32 + sol - 2);
|
||||
sof = ar_pfs & 0x7f;
|
||||
sol = (ar_pfs >> 7) & 0x7f;
|
||||
bsp = db_rse_previous_frame(bsp, sol);
|
||||
if (!callpc)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -82,6 +82,10 @@ db_regs_t ddb_regs; /* register state */
|
||||
u_long db_register_value(db_regs_t *, int);
|
||||
int kdb_trap(int vector, struct trapframe *regs);
|
||||
|
||||
u_int64_t *db_rse_current_frame(void);
|
||||
u_int64_t *db_rse_previous_frame(u_int64_t *bsp, int sof);
|
||||
u_int64_t *db_rse_register_address(u_int64_t *bsp, int regno);
|
||||
|
||||
/*
|
||||
* Pretty arbitrary
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user