Replace arm/arm32/db_trace.c and arm26/arm26/db_trace.c with a unified version
in arm/arm. This version is based on the arm26 version, and includes dumping the contents of stack frames, with automatic determination of the save code pointer offset.
This commit is contained in:
parent
7276c20511
commit
95fe4db7e3
@ -1,6 +1,7 @@
|
||||
/* $NetBSD: db_trace.c,v 1.7 2001/03/11 16:31:05 bjh21 Exp $ */
|
||||
/* $NetBSD: db_trace.c,v 1.1 2001/06/05 09:25:05 bjh21 Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Ben Harris
|
||||
* Copyright (c) 1996 Scott K. Stevens
|
||||
*
|
||||
* Mach Operating System
|
||||
@ -30,17 +31,20 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
__RCSID("$NetBSD: db_trace.c,v 1.7 2001/03/11 16:31:05 bjh21 Exp $");
|
||||
__RCSID("$NetBSD: db_trace.c,v 1.1 2001/06/05 09:25:05 bjh21 Exp $");
|
||||
|
||||
#include <sys/proc.h>
|
||||
#include <sys/user.h>
|
||||
#include <arm/armreg.h>
|
||||
#include <arm/cpufunc.h>
|
||||
#include <machine/db_machdep.h>
|
||||
|
||||
#include <ddb/db_access.h>
|
||||
#include <ddb/db_interface.h>
|
||||
#include <ddb/db_sym.h>
|
||||
#include <ddb/db_output.h>
|
||||
|
||||
#include "opt_progmode.h"
|
||||
|
||||
#define INKERNEL(va) (((vm_offset_t)(va)) >= VM_MIN_KERNEL_ADDRESS)
|
||||
|
||||
@ -48,7 +52,7 @@ __RCSID("$NetBSD: db_trace.c,v 1.7 2001/03/11 16:31:05 bjh21 Exp $");
|
||||
* APCS stack frames are awkward beasts, so I don't think even trying to use
|
||||
* a structure to represent them is a good idea.
|
||||
*
|
||||
* Here's the diagram from the APCS. Incresing address is _up_ the page.
|
||||
* Here's the diagram from the APCS. Increasing address is _up_ the page.
|
||||
*
|
||||
* save code pointer [fp] <- fp points to here
|
||||
* return link value [fp, #-4]
|
||||
@ -89,6 +93,7 @@ db_stack_trace_print(addr, have_addr, count, modif, pr)
|
||||
char c, *cp = modif;
|
||||
boolean_t kernel_only = TRUE;
|
||||
boolean_t trace_thread = FALSE;
|
||||
int scp_offset;
|
||||
|
||||
while ((c = *cp++) != 0) {
|
||||
if (c == 'u')
|
||||
@ -114,12 +119,17 @@ db_stack_trace_print(addr, have_addr, count, modif, pr)
|
||||
return;
|
||||
}
|
||||
u = p->p_addr;
|
||||
#ifdef arm26
|
||||
frame = (u_int32_t *)(u->u_pcb.pcb_sf->sf_r11);
|
||||
#else
|
||||
frame = (u_int32_t *)(u->u_pcb.pcb_r11);
|
||||
#endif
|
||||
(*pr)("at %p\n", frame);
|
||||
} else
|
||||
frame = (u_int32_t *)(addr);
|
||||
}
|
||||
lastframe = NULL;
|
||||
scp_offset = -(get_pc_str_offset() >> 2);
|
||||
|
||||
while (count-- && frame != NULL) {
|
||||
db_expr_t offset;
|
||||
@ -133,7 +143,11 @@ db_stack_trace_print(addr, have_addr, count, modif, pr)
|
||||
* In theory, the SCP isn't guaranteed to be in the function
|
||||
* that generated the stack frame. We hope for the best.
|
||||
*/
|
||||
#ifdef PROG26
|
||||
scp = frame[FR_SCP] & R15_PC;
|
||||
#else
|
||||
scp = frame[FR_SCP];
|
||||
#endif
|
||||
|
||||
db_find_sym_and_offset(scp, &name, &offset);
|
||||
if (name == NULL)
|
||||
@ -143,11 +157,15 @@ db_stack_trace_print(addr, have_addr, count, modif, pr)
|
||||
(*pr)("(scp=0x%x(", frame[FR_SCP]);
|
||||
db_printsym(scp, DB_STGY_PROC, pr);
|
||||
(*pr)("), rlv=0x%x(", frame[FR_RLV]);
|
||||
#ifdef PROG26
|
||||
db_printsym(frame[FR_RLV] & R15_PC, DB_STGY_PROC, pr);
|
||||
#else
|
||||
db_printsym(frame[FR_RLV], DB_STGY_PROC, pr);
|
||||
#endif
|
||||
(*pr)("),\n\trsp=0x%x", frame[FR_RSP]);
|
||||
(*pr)(", rfp=0x%x", frame[FR_RFP]);
|
||||
|
||||
savecode = ((u_int32_t *)scp)[-3];
|
||||
savecode = ((u_int32_t *)scp)[scp_offset];
|
||||
if ((savecode & 0x0e100000) == 0x08000000) {
|
||||
/* Looks like an STM */
|
||||
rp = frame - 4;
|
@ -1,149 +0,0 @@
|
||||
/* $NetBSD: db_trace.c,v 1.1 2001/03/04 05:11:41 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Scott K. Stevens
|
||||
*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/user.h>
|
||||
#include <machine/db_machdep.h>
|
||||
|
||||
#include <ddb/db_access.h>
|
||||
#include <ddb/db_sym.h>
|
||||
#include <ddb/db_output.h>
|
||||
|
||||
#define INKERNEL(va) (((vm_offset_t)(va)) >= VM_MIN_KERNEL_ADDRESS)
|
||||
|
||||
void
|
||||
db_stack_trace_print(addr, have_addr, count, modif, pr)
|
||||
db_expr_t addr;
|
||||
int have_addr;
|
||||
db_expr_t count;
|
||||
char *modif;
|
||||
void (*pr) __P((const char *, ...));
|
||||
{
|
||||
struct frame *frame, *lastframe;
|
||||
char c, *cp = modif;
|
||||
boolean_t kernel_only = TRUE;
|
||||
boolean_t trace_thread = FALSE;
|
||||
|
||||
while ((c = *cp++) != 0) {
|
||||
if (c == 'u')
|
||||
kernel_only = FALSE;
|
||||
if (c == 't')
|
||||
trace_thread = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* The frame pointer points to the top word of the stack frame so we
|
||||
* need to adjust it by sizeof(struct frame) - sizeof(u_int))
|
||||
* to get the address of the start of the frame structure.
|
||||
*/
|
||||
|
||||
if (!have_addr)
|
||||
frame = (struct frame *)(DDB_REGS->tf_r11
|
||||
- (sizeof(struct frame) - sizeof(u_int)));
|
||||
else {
|
||||
if (trace_thread) {
|
||||
struct proc *p;
|
||||
struct user *u;
|
||||
(*pr)("trace: pid %d ", (int)addr);
|
||||
p = pfind(addr);
|
||||
if (p == NULL) {
|
||||
(*pr)("not found\n");
|
||||
return;
|
||||
}
|
||||
if (!(p->p_flag & P_INMEM)) {
|
||||
(*pr)("swapped out\n");
|
||||
return;
|
||||
}
|
||||
u = p->p_addr;
|
||||
frame = (struct frame *) (u->u_pcb.pcb_r11
|
||||
- (sizeof(struct frame) - sizeof(u_int)));
|
||||
(*pr)("at %p\n", frame);
|
||||
} else
|
||||
frame = (struct frame *)(addr - (sizeof(struct frame)
|
||||
- sizeof(u_int)));
|
||||
}
|
||||
lastframe = NULL;
|
||||
|
||||
while (count--) {
|
||||
db_expr_t offset;
|
||||
char *name;
|
||||
db_addr_t pc;
|
||||
|
||||
/* (*pr)("fp=%08x: fp=%08x sp=%08x lr=%08x pc=%08x\n",
|
||||
(u_int)frame, frame->fr_fp, frame->fr_sp, frame->fr_lr,
|
||||
frame->fr_pc);*/
|
||||
|
||||
pc = frame->fr_pc;
|
||||
/* Adjust the PC so the same address is printed no matter what CPU */
|
||||
if (cputype == CPU_ID_SA110 || cputype == CPU_ID_ARM810)
|
||||
pc += 4;
|
||||
if (!INKERNEL(pc))
|
||||
break;
|
||||
|
||||
db_find_sym_and_offset(pc, &name, &offset);
|
||||
if (name == NULL)
|
||||
name = "?";
|
||||
|
||||
(*pr)("%s(", name);
|
||||
db_printsym(pc, DB_STGY_PROC, pr);
|
||||
(*pr)(")");
|
||||
(*pr)("\n");
|
||||
|
||||
/*
|
||||
* Switch to next frame up
|
||||
*/
|
||||
lastframe = frame;
|
||||
frame = (struct frame *)(frame->fr_fp - (sizeof(struct frame)
|
||||
- sizeof(u_int)));
|
||||
|
||||
if (frame == NULL)
|
||||
break;
|
||||
|
||||
if (INKERNEL((int)frame)) {
|
||||
/* staying in kernel */
|
||||
if (frame <= lastframe) {
|
||||
(*pr)("Bad frame pointer: %p\n", frame);
|
||||
break;
|
||||
}
|
||||
} else if (INKERNEL((int)lastframe)) {
|
||||
/* switch from user to kernel */
|
||||
if (kernel_only)
|
||||
break; /* kernel stack only */
|
||||
} else {
|
||||
/* in user */
|
||||
if (frame <= lastframe) {
|
||||
(*pr)("Bad user frame pointer: %p\n",
|
||||
frame);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.arm,v 1.30 2001/06/03 18:32:33 chris Exp $
|
||||
# $NetBSD: files.arm,v 1.31 2001/06/05 09:25:06 bjh21 Exp $
|
||||
|
||||
# temporary define to allow easy moving to ../arch/arm/arm32
|
||||
defopt ARM32
|
||||
@ -26,7 +26,7 @@ file netns/ns_cksum.c ns
|
||||
# DDB
|
||||
file arch/arm/arm/db_disasm.c ddb
|
||||
file arch/arm/arm32/db_interface.c ddb & arm32
|
||||
file arch/arm/arm32/db_trace.c ddb & arm32
|
||||
file arch/arm/arm/db_trace.c ddb
|
||||
file arch/arm/arm32/db_machdep.c ddb & arm32
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.arm26,v 1.30 2001/04/22 15:26:07 bjh21 Exp $
|
||||
# $NetBSD: files.arm26,v 1.31 2001/06/05 09:25:07 bjh21 Exp $
|
||||
|
||||
# Copyright (c) 1997, 1998, 2000 Ben Harris
|
||||
# All rights reserved.
|
||||
@ -196,7 +196,6 @@ file dev/cninit.c
|
||||
|
||||
file arch/arm26/arm26/db_interface.c ddb
|
||||
file arch/arm26/arm26/db_machdep.c ddb
|
||||
file arch/arm26/arm26/db_trace.c ddb
|
||||
|
||||
file arch/arm26/arm26/start.c
|
||||
file arch/arm26/arm26/autoconf.c
|
||||
|
Loading…
Reference in New Issue
Block a user