From 5142414afb649a6a8880ebb85cc1fcdd47cc7373 Mon Sep 17 00:00:00 2001 From: dfr Date: Wed, 18 Apr 2001 14:15:45 +0000 Subject: Implement a simple stack trace for DDB. This will have to be redone if/when we change to a more modern toolchain. --- sys/ia64/ia64/db_interface.c | 29 +++++++++++++++++---------- sys/ia64/ia64/db_trace.c | 46 ++++++++++++++++++++++++++++++++++++++++++- sys/ia64/include/db_machdep.h | 4 ++++ 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 */ -- cgit v1.1