Add some stack backtrace support. Pretty fragile but its a start.
This commit is contained in:
parent
258cfd2226
commit
9b0f23e482
@ -97,6 +97,13 @@ typedef union {
|
||||
} jump_format;
|
||||
|
||||
|
||||
struct {
|
||||
signed int offset : 16;
|
||||
unsigned rb : 5;
|
||||
unsigned ra : 5;
|
||||
unsigned opcode : 6;
|
||||
} memory_format;
|
||||
|
||||
/*
|
||||
* Operate instructions are of two types, with
|
||||
* a second source register or with a literal
|
||||
|
@ -13,13 +13,94 @@
|
||||
#include <ddb/db_access.h>
|
||||
#include <ddb/db_variables.h>
|
||||
#include <ddb/db_output.h>
|
||||
#include <alpha/alpha/db_instruction.h>
|
||||
|
||||
struct alpha_proc {
|
||||
int pcreg; /* index of return pc register */
|
||||
int frame_size; /* size of stack frame */
|
||||
u_int32_t reg_mask;
|
||||
int regs[32]; /* offsets from sp to saved regs */
|
||||
};
|
||||
|
||||
static void
|
||||
parse_proc(db_expr_t addr, struct alpha_proc* frame)
|
||||
{
|
||||
db_sym_t sym;
|
||||
db_expr_t func;
|
||||
db_expr_t junk, pc, limit;
|
||||
int frame_size;
|
||||
int reg_mask;
|
||||
int got_frame;
|
||||
|
||||
frame->pcreg = -1;
|
||||
frame->reg_mask = 0;
|
||||
frame->frame_size = 0;
|
||||
|
||||
sym = db_search_symbol(addr, DB_STGY_PROC, &junk);
|
||||
if (!sym)
|
||||
return;
|
||||
db_symbol_values(sym, 0, &func);
|
||||
|
||||
pc = func;
|
||||
limit = addr;
|
||||
if (limit - pc > 200)
|
||||
limit = pc + 200;
|
||||
for (; pc < limit; pc += 4) {
|
||||
alpha_instruction ins;
|
||||
ins.bits = *(u_int32_t*) pc;
|
||||
if (ins.memory_format.opcode == op_lda
|
||||
&& ins.memory_format.ra == 30) {
|
||||
frame->frame_size += -ins.memory_format.offset;
|
||||
} else if (ins.memory_format.opcode == op_stq
|
||||
&& ins.memory_format.rb == 30
|
||||
&& ins.memory_format.ra != 31) {
|
||||
int reg = ins.memory_format.ra;
|
||||
frame->reg_mask |= 1 << reg;
|
||||
frame->regs[reg] = ins.memory_format.offset;
|
||||
if (frame->pcreg == -1 && reg == 26)
|
||||
frame->pcreg = reg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
db_stack_trace_cmd(addr, have_addr, count, modif)
|
||||
db_expr_t addr;
|
||||
boolean_t have_addr;
|
||||
db_expr_t count;
|
||||
char *modif;
|
||||
db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif)
|
||||
{
|
||||
/* nothing, yet. */
|
||||
struct alpha_proc proc;
|
||||
db_addr_t callpc;
|
||||
db_addr_t frame;
|
||||
|
||||
if (count == -1)
|
||||
count = 65535;
|
||||
|
||||
if (!have_addr) {
|
||||
frame = (db_addr_t) ddb_regs.tf_regs[FRAME_SP];
|
||||
callpc = (db_addr_t)ddb_regs.tf_regs[FRAME_PC];
|
||||
} else {
|
||||
frame = (db_addr_t)addr;
|
||||
callpc = (db_addr_t)db_get_value(frame, 8, FALSE);
|
||||
}
|
||||
|
||||
while (count--) {
|
||||
u_int64_t *actframe;
|
||||
char * name;
|
||||
db_expr_t offset;
|
||||
db_sym_t sym;
|
||||
struct alpha_proc proc;
|
||||
|
||||
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");
|
||||
|
||||
parse_proc(callpc, &proc);
|
||||
|
||||
if (proc.pcreg == -1)
|
||||
break;
|
||||
|
||||
callpc = db_get_value(frame + proc.regs[proc.pcreg], 8, FALSE);
|
||||
frame = frame + proc.frame_size;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: swtch.s,v 1.1 1998/06/10 10:53:23 dfr Exp $ */
|
||||
/* $Id: swtch.s,v 1.2 1998/06/11 11:51:26 dfr Exp $ */
|
||||
/* $NetBSD: locore.s,v 1.47 1998/03/22 07:26:32 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
@ -356,6 +356,10 @@ LEAF(exception_save_regs, 0)
|
||||
stq t10,(FRAME_T10*8)(sp)
|
||||
stq t11,(FRAME_T11*8)(sp)
|
||||
stq t12,(FRAME_T12*8)(sp)
|
||||
.set noat
|
||||
lda at_reg,(FRAME_SIZE*8)(sp)
|
||||
stq at_reg,(FRAME_SP*8)(sp)
|
||||
.set at
|
||||
RET
|
||||
END(exception_save_regs)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user