summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2001-04-18 14:15:45 +0000
committerdfr <dfr@FreeBSD.org>2001-04-18 14:15:45 +0000
commit5142414afb649a6a8880ebb85cc1fcdd47cc7373 (patch)
treed0b1494558e6f1a149732f10420e317baaf75034
parent4ecfe212ec4a78464d1d07549d584f64478c5dfa (diff)
downloadFreeBSD-src-5142414afb649a6a8880ebb85cc1fcdd47cc7373.zip
FreeBSD-src-5142414afb649a6a8880ebb85cc1fcdd47cc7373.tar.gz
Implement a simple stack trace for DDB. This will have to be redone
if/when we change to a more modern toolchain.
-rw-r--r--sys/ia64/ia64/db_interface.c29
-rw-r--r--sys/ia64/ia64/db_trace.c46
-rw-r--r--sys/ia64/include/db_machdep.h4
3 files changed, 68 insertions, 11 deletions
diff --git a/sys/ia64/ia64/db_interface.c b/sys/ia64/ia64/db_interface.c
index 36e6e17..3750189 100644
--- a/sys/ia64/ia64/db_interface.c
+++ b/sys/ia64/ia64/db_interface.c
@@ -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;
}
}
diff --git a/sys/ia64/ia64/db_trace.c b/sys/ia64/ia64/db_trace.c
index 8b0fba7..289446a 100644
--- a/sys/ia64/ia64/db_trace.c
+++ b/sys/ia64/ia64/db_trace.c
@@ -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;
+ }
}
diff --git a/sys/ia64/include/db_machdep.h b/sys/ia64/include/db_machdep.h
index b807b37..3ac65d7 100644
--- a/sys/ia64/include/db_machdep.h
+++ b/sys/ia64/include/db_machdep.h
@@ -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
*/
OpenPOWER on IntegriCloud