mirror of
https://github.com/opnsense/src.git
synced 2026-04-27 09:06:49 -04:00
108 lines
2.6 KiB
C
108 lines
2.6 KiB
C
/* $FreeBSD$ */
|
|
/* $NetBSD: db_trace.c,v 1.1 1997/09/06 02:00:50 thorpej Exp $ */
|
|
|
|
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
|
|
|
/* __KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.1 1997/09/06 02:00:50 thorpej Exp $"); */
|
|
|
|
#include <sys/param.h>
|
|
#include <sys/proc.h>
|
|
#include <machine/db_machdep.h>
|
|
|
|
#include <ddb/ddb.h>
|
|
#include <ddb/db_sym.h>
|
|
#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)
|
|
{
|
|
c_db_sym_t sym;
|
|
db_expr_t func;
|
|
db_expr_t junk, pc, limit;
|
|
|
|
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) {
|
|
/* gcc 2.7 */
|
|
frame->frame_size += -ins.memory_format.offset;
|
|
} else if (ins.operate_lit_format.opcode == op_arit
|
|
&& ins.operate_lit_format.function == op_subq
|
|
&& ins.operate_lit_format.rs == 30) {
|
|
/* egcs */
|
|
frame->frame_size += ins.operate_lit_format.literal;
|
|
} 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(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif)
|
|
{
|
|
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--) {
|
|
const char * name;
|
|
db_expr_t offset;
|
|
c_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;
|
|
}
|
|
}
|