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:
dfr 2001-04-18 14:15:45 +00:00
parent a7c7f132de
commit 9bdbf65c26
3 changed files with 68 additions and 11 deletions

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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
*/