Merge db_interface.c and db_trace.c into db_machdep.c.
This commit is contained in:
parent
216e80c2ba
commit
8115693121
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=149926
@ -96,8 +96,7 @@ ia64/ia64/autoconf.c standard
|
||||
ia64/ia64/busdma_machdep.c standard
|
||||
ia64/ia64/clock.c standard
|
||||
ia64/ia64/context.S standard
|
||||
ia64/ia64/db_interface.c optional ddb
|
||||
ia64/ia64/db_trace.c optional ddb
|
||||
ia64/ia64/db_machdep.c optional ddb
|
||||
ia64/ia64/dump_machdep.c standard
|
||||
ia64/ia64/efi.c standard
|
||||
ia64/ia64/elf_machdep.c standard
|
||||
|
@ -1,37 +1,34 @@
|
||||
/*-
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1992,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
|
||||
* 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.
|
||||
* Copyright (c) 2003-2005 Marcel Moolenaar
|
||||
* Copyright (c) 2000-2001 Doug Rabson
|
||||
* All rights reserved.
|
||||
*
|
||||
* db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU)
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Interface to DDB.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/cons.h>
|
||||
@ -41,6 +38,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/proc.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/stack.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
|
||||
@ -48,10 +46,14 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/frame.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/mutex.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/setjmp.h>
|
||||
#include <machine/unwind.h>
|
||||
#include <machine/vmparam.h>
|
||||
|
||||
#include <ddb/ddb.h>
|
||||
#include <ddb/db_access.h>
|
||||
#include <ddb/db_output.h>
|
||||
#include <ddb/db_sym.h>
|
||||
#include <ddb/db_variables.h>
|
||||
|
||||
@ -64,9 +66,14 @@ __FBSDID("$FreeBSD$");
|
||||
#define SLOT_MASK ((1ULL << SLOT_BITS) - 1ULL)
|
||||
#define SLOT_SHIFT(i) (TMPL_BITS+((i)<<3)+(i))
|
||||
|
||||
typedef db_expr_t __db_f(db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t,
|
||||
db_expr_t, db_expr_t, db_expr_t);
|
||||
|
||||
register uint64_t __db_gp __asm__("gp");
|
||||
|
||||
static db_varfcn_t db_frame;
|
||||
static db_varfcn_t db_getrse;
|
||||
static db_varfcn_t db_getip;
|
||||
static db_varfcn_t db_getrse;
|
||||
|
||||
#define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x)
|
||||
struct db_variable db_regs[] = {
|
||||
@ -213,132 +220,85 @@ struct db_variable db_regs[] = {
|
||||
struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
|
||||
|
||||
static int
|
||||
db_frame(struct db_variable *vp, db_expr_t *valuep, int op)
|
||||
db_backtrace(struct thread *td, struct pcb *pcb, int count)
|
||||
{
|
||||
uint64_t *reg;
|
||||
struct unw_regstate rs;
|
||||
struct trapframe *tf;
|
||||
const char *name;
|
||||
db_expr_t offset;
|
||||
uint64_t bsp, cfm, ip, pfs, reg, sp;
|
||||
c_db_sym_t sym;
|
||||
int args, error, i, quit;
|
||||
|
||||
if (kdb_frame == NULL)
|
||||
return (0);
|
||||
reg = (uint64_t*)((uintptr_t)kdb_frame + (uintptr_t)vp->valuep);
|
||||
if (op == DB_VAR_GET)
|
||||
*valuep = *reg;
|
||||
else
|
||||
*reg = *valuep;
|
||||
return (1);
|
||||
}
|
||||
quit = 0;
|
||||
db_setup_paging(db_simple_pager, &quit, db_lines_per_page);
|
||||
error = unw_create_from_pcb(&rs, pcb);
|
||||
while (!error && count-- && !quit) {
|
||||
error = unw_get_cfm(&rs, &cfm);
|
||||
if (!error)
|
||||
error = unw_get_bsp(&rs, &bsp);
|
||||
if (!error)
|
||||
error = unw_get_ip(&rs, &ip);
|
||||
if (!error)
|
||||
error = unw_get_sp(&rs, &sp);
|
||||
if (error)
|
||||
break;
|
||||
|
||||
static int
|
||||
db_getrse(struct db_variable *vp, db_expr_t *valuep, int op)
|
||||
{
|
||||
u_int64_t *reg;
|
||||
uint64_t bsp;
|
||||
int nats, regno, sof;
|
||||
args = IA64_CFM_SOL(cfm);
|
||||
if (args > 8)
|
||||
args = 8;
|
||||
|
||||
if (kdb_frame == NULL)
|
||||
return (0);
|
||||
error = unw_step(&rs);
|
||||
if (!error) {
|
||||
if (!unw_get_cfm(&rs, &pfs)) {
|
||||
i = IA64_CFM_SOF(pfs) - IA64_CFM_SOL(pfs);
|
||||
if (args > i)
|
||||
args = i;
|
||||
}
|
||||
}
|
||||
|
||||
regno = (int)(intptr_t)valuep;
|
||||
bsp = kdb_frame->tf_special.bspstore + kdb_frame->tf_special.ndirty;
|
||||
sof = (int)(kdb_frame->tf_special.cfm & 0x7f);
|
||||
sym = db_search_symbol(ip, DB_STGY_ANY, &offset);
|
||||
db_symbol_values(sym, &name, NULL);
|
||||
db_printf("%s(", name);
|
||||
if (bsp >= IA64_RR_BASE(5)) {
|
||||
for (i = 0; i < args; i++) {
|
||||
if ((bsp & 0x1ff) == 0x1f8)
|
||||
bsp += 8;
|
||||
db_read_bytes(bsp, sizeof(reg), (void*)®);
|
||||
if (i > 0)
|
||||
db_printf(", ");
|
||||
db_printf("0x%lx", reg);
|
||||
bsp += 8;
|
||||
}
|
||||
} else
|
||||
db_printf("...");
|
||||
db_printf(") at ");
|
||||
|
||||
if (regno >= sof)
|
||||
return (0);
|
||||
db_printsym(ip, DB_STGY_PROC);
|
||||
db_printf("\n");
|
||||
|
||||
nats = (sof - regno + 63 - ((int)(bsp >> 3) & 0x3f)) / 63;
|
||||
reg = (void*)(bsp - ((sof - regno + nats) << 3));
|
||||
if (op == DB_VAR_GET)
|
||||
*valuep = *reg;
|
||||
else
|
||||
*reg = *valuep;
|
||||
return (1);
|
||||
}
|
||||
if (error != ERESTART)
|
||||
continue;
|
||||
if (sp < IA64_RR_BASE(5))
|
||||
break;
|
||||
|
||||
static int
|
||||
db_getip(struct db_variable *vp, db_expr_t *valuep, int op)
|
||||
{
|
||||
u_long iip, slot;
|
||||
tf = (struct trapframe *)(sp + 16);
|
||||
if ((tf->tf_flags & FRAME_SYSCALL) != 0 ||
|
||||
tf->tf_special.iip < IA64_RR_BASE(5))
|
||||
break;
|
||||
|
||||
if (kdb_frame == NULL)
|
||||
return (0);
|
||||
|
||||
if (op == DB_VAR_GET) {
|
||||
iip = kdb_frame->tf_special.iip;
|
||||
slot = (kdb_frame->tf_special.psr >> 41) & 3;
|
||||
*valuep = iip + slot;
|
||||
} else {
|
||||
iip = *valuep & ~0xf;
|
||||
slot = *valuep & 0xf;
|
||||
if (slot > 2)
|
||||
return (0);
|
||||
kdb_frame->tf_special.iip = iip;
|
||||
kdb_frame->tf_special.psr &= ~IA64_PSR_RI;
|
||||
kdb_frame->tf_special.psr |= slot << 41;
|
||||
/* XXX ask if we should unwind across the trapframe. */
|
||||
db_printf("--- trapframe at %p\n", tf);
|
||||
unw_delete(&rs);
|
||||
error = unw_create_from_frame(&rs, tf);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read bytes from kernel address space for debugger.
|
||||
*/
|
||||
int
|
||||
db_read_bytes(vm_offset_t addr, size_t size, char *data)
|
||||
{
|
||||
jmp_buf jb;
|
||||
void *prev_jb;
|
||||
char *src;
|
||||
int ret;
|
||||
|
||||
prev_jb = kdb_jmpbuf(jb);
|
||||
ret = setjmp(jb);
|
||||
if (ret == 0) {
|
||||
src = (char *)addr;
|
||||
while (size-- > 0)
|
||||
*data++ = *src++;
|
||||
}
|
||||
(void)kdb_jmpbuf(prev_jb);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write bytes to kernel address space for debugger.
|
||||
*/
|
||||
int
|
||||
db_write_bytes(vm_offset_t addr, size_t size, char *data)
|
||||
{
|
||||
jmp_buf jb;
|
||||
void *prev_jb;
|
||||
char *dst;
|
||||
int ret;
|
||||
|
||||
prev_jb = kdb_jmpbuf(jb);
|
||||
ret = setjmp(jb);
|
||||
if (ret == 0) {
|
||||
dst = (char *)addr;
|
||||
while (size-- > 0)
|
||||
*dst++ = *data++;
|
||||
}
|
||||
(void)kdb_jmpbuf(prev_jb);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
db_bkpt_write(db_addr_t addr, BKPT_INST_TYPE *storage)
|
||||
{
|
||||
BKPT_INST_TYPE tmp;
|
||||
db_addr_t loc;
|
||||
int slot;
|
||||
|
||||
slot = addr & 0xfUL;
|
||||
if (slot >= SLOT_COUNT)
|
||||
return;
|
||||
loc = (addr & ~0xfUL) + (slot << 2);
|
||||
|
||||
db_read_bytes(loc, sizeof(BKPT_INST_TYPE), (char *)&tmp);
|
||||
*storage = (tmp >> SLOT_SHIFT(slot)) & SLOT_MASK;
|
||||
|
||||
tmp &= ~(SLOT_MASK << SLOT_SHIFT(slot));
|
||||
tmp |= (0x84000 << 6) << SLOT_SHIFT(slot);
|
||||
db_write_bytes(loc, sizeof(BKPT_INST_TYPE), (char *)&tmp);
|
||||
unw_delete(&rs);
|
||||
/*
|
||||
* EJUSTRETURN and ERESTART signal the end of a trace and
|
||||
* are not really errors.
|
||||
*/
|
||||
return ((error > 0) ? error : 0);
|
||||
}
|
||||
|
||||
void
|
||||
@ -373,6 +333,26 @@ db_bkpt_skip(void)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
db_bkpt_write(db_addr_t addr, BKPT_INST_TYPE *storage)
|
||||
{
|
||||
BKPT_INST_TYPE tmp;
|
||||
db_addr_t loc;
|
||||
int slot;
|
||||
|
||||
slot = addr & 0xfUL;
|
||||
if (slot >= SLOT_COUNT)
|
||||
return;
|
||||
loc = (addr & ~0xfUL) + (slot << 2);
|
||||
|
||||
db_read_bytes(loc, sizeof(BKPT_INST_TYPE), (char *)&tmp);
|
||||
*storage = (tmp >> SLOT_SHIFT(slot)) & SLOT_MASK;
|
||||
|
||||
tmp &= ~(SLOT_MASK << SLOT_SHIFT(slot));
|
||||
tmp |= (0x84000 << 6) << SLOT_SHIFT(slot);
|
||||
db_write_bytes(loc, sizeof(BKPT_INST_TYPE), (char *)&tmp);
|
||||
}
|
||||
|
||||
db_addr_t
|
||||
db_disasm(db_addr_t loc, boolean_t altfmt)
|
||||
{
|
||||
@ -444,11 +424,6 @@ db_disasm(db_addr_t loc, boolean_t altfmt)
|
||||
return (loc + slot);
|
||||
}
|
||||
|
||||
typedef db_expr_t __db_f(db_expr_t, db_expr_t, db_expr_t, db_expr_t, db_expr_t,
|
||||
db_expr_t, db_expr_t, db_expr_t);
|
||||
|
||||
register uint64_t __db_gp __asm__("gp");
|
||||
|
||||
int
|
||||
db_fncall_ia64(db_expr_t addr, db_expr_t *rv, int nargs, db_expr_t args[])
|
||||
{
|
||||
@ -463,7 +438,167 @@ db_fncall_ia64(db_expr_t addr, db_expr_t *rv, int nargs, db_expr_t args[])
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
db_frame(struct db_variable *vp, db_expr_t *valuep, int op)
|
||||
{
|
||||
uint64_t *reg;
|
||||
|
||||
if (kdb_frame == NULL)
|
||||
return (0);
|
||||
reg = (uint64_t*)((uintptr_t)kdb_frame + (uintptr_t)vp->valuep);
|
||||
if (op == DB_VAR_GET)
|
||||
*valuep = *reg;
|
||||
else
|
||||
*reg = *valuep;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
db_getip(struct db_variable *vp, db_expr_t *valuep, int op)
|
||||
{
|
||||
u_long iip, slot;
|
||||
|
||||
if (kdb_frame == NULL)
|
||||
return (0);
|
||||
|
||||
if (op == DB_VAR_GET) {
|
||||
iip = kdb_frame->tf_special.iip;
|
||||
slot = (kdb_frame->tf_special.psr >> 41) & 3;
|
||||
*valuep = iip + slot;
|
||||
} else {
|
||||
iip = *valuep & ~0xf;
|
||||
slot = *valuep & 0xf;
|
||||
if (slot > 2)
|
||||
return (0);
|
||||
kdb_frame->tf_special.iip = iip;
|
||||
kdb_frame->tf_special.psr &= ~IA64_PSR_RI;
|
||||
kdb_frame->tf_special.psr |= slot << 41;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
db_getrse(struct db_variable *vp, db_expr_t *valuep, int op)
|
||||
{
|
||||
u_int64_t *reg;
|
||||
uint64_t bsp;
|
||||
int nats, regno, sof;
|
||||
|
||||
if (kdb_frame == NULL)
|
||||
return (0);
|
||||
|
||||
regno = (int)(intptr_t)valuep;
|
||||
bsp = kdb_frame->tf_special.bspstore + kdb_frame->tf_special.ndirty;
|
||||
sof = (int)(kdb_frame->tf_special.cfm & 0x7f);
|
||||
|
||||
if (regno >= sof)
|
||||
return (0);
|
||||
|
||||
nats = (sof - regno + 63 - ((int)(bsp >> 3) & 0x3f)) / 63;
|
||||
reg = (void*)(bsp - ((sof - regno + nats) << 3));
|
||||
if (op == DB_VAR_GET)
|
||||
*valuep = *reg;
|
||||
else
|
||||
*reg = *valuep;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
db_md_clr_watchpoint(db_expr_t addr, db_expr_t size)
|
||||
{
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
void
|
||||
db_md_list_watchpoints()
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
db_md_set_watchpoint(db_expr_t addr, db_expr_t size)
|
||||
{
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read bytes from kernel address space for debugger.
|
||||
*/
|
||||
int
|
||||
db_read_bytes(vm_offset_t addr, size_t size, char *data)
|
||||
{
|
||||
jmp_buf jb;
|
||||
void *prev_jb;
|
||||
char *src;
|
||||
int ret;
|
||||
|
||||
prev_jb = kdb_jmpbuf(jb);
|
||||
ret = setjmp(jb);
|
||||
if (ret == 0) {
|
||||
src = (char *)addr;
|
||||
while (size-- > 0)
|
||||
*data++ = *src++;
|
||||
}
|
||||
(void)kdb_jmpbuf(prev_jb);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write bytes to kernel address space for debugger.
|
||||
*/
|
||||
int
|
||||
db_write_bytes(vm_offset_t addr, size_t size, char *data)
|
||||
{
|
||||
jmp_buf jb;
|
||||
void *prev_jb;
|
||||
char *dst;
|
||||
int ret;
|
||||
|
||||
prev_jb = kdb_jmpbuf(jb);
|
||||
ret = setjmp(jb);
|
||||
if (ret == 0) {
|
||||
dst = (char *)addr;
|
||||
while (size-- > 0)
|
||||
*dst++ = *data++;
|
||||
}
|
||||
(void)kdb_jmpbuf(prev_jb);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
db_show_mdpcpu(struct pcpu *pc)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
db_trace_self(void)
|
||||
{
|
||||
struct pcb pcb;
|
||||
|
||||
savectx(&pcb);
|
||||
db_backtrace(curthread, &pcb, -1);
|
||||
}
|
||||
|
||||
int
|
||||
db_trace_thread(struct thread *td, int count)
|
||||
{
|
||||
struct pcb *ctx;
|
||||
|
||||
ctx = kdb_thr_ctx(td);
|
||||
return (db_backtrace(td, ctx, count));
|
||||
}
|
||||
|
||||
void
|
||||
stack_save(struct stack *st)
|
||||
{
|
||||
|
||||
stack_zero(st);
|
||||
/*
|
||||
* Nothing for now.
|
||||
* Is libuwx reentrant?
|
||||
* Can unw_create* sleep?
|
||||
*/
|
||||
}
|
@ -1,182 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2003, 2004 Marcel Moolenaar
|
||||
* Copyright (c) 2000-2001 Doug Rabson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/stack.h>
|
||||
|
||||
#include <machine/db_machdep.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/unwind.h>
|
||||
#include <machine/vmparam.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>
|
||||
|
||||
static int
|
||||
db_backtrace(struct thread *td, struct pcb *pcb, int count)
|
||||
{
|
||||
struct unw_regstate rs;
|
||||
struct trapframe *tf;
|
||||
const char *name;
|
||||
db_expr_t offset;
|
||||
uint64_t bsp, cfm, ip, pfs, reg, sp;
|
||||
c_db_sym_t sym;
|
||||
int args, error, i, quit;
|
||||
|
||||
quit = 0;
|
||||
db_setup_paging(db_simple_pager, &quit, db_lines_per_page);
|
||||
error = unw_create_from_pcb(&rs, pcb);
|
||||
while (!error && count-- && !quit) {
|
||||
error = unw_get_cfm(&rs, &cfm);
|
||||
if (!error)
|
||||
error = unw_get_bsp(&rs, &bsp);
|
||||
if (!error)
|
||||
error = unw_get_ip(&rs, &ip);
|
||||
if (!error)
|
||||
error = unw_get_sp(&rs, &sp);
|
||||
if (error)
|
||||
break;
|
||||
|
||||
args = IA64_CFM_SOL(cfm);
|
||||
if (args > 8)
|
||||
args = 8;
|
||||
|
||||
error = unw_step(&rs);
|
||||
if (!error) {
|
||||
if (!unw_get_cfm(&rs, &pfs)) {
|
||||
i = IA64_CFM_SOF(pfs) - IA64_CFM_SOL(pfs);
|
||||
if (args > i)
|
||||
args = i;
|
||||
}
|
||||
}
|
||||
|
||||
sym = db_search_symbol(ip, DB_STGY_ANY, &offset);
|
||||
db_symbol_values(sym, &name, NULL);
|
||||
db_printf("%s(", name);
|
||||
if (bsp >= IA64_RR_BASE(5)) {
|
||||
for (i = 0; i < args; i++) {
|
||||
if ((bsp & 0x1ff) == 0x1f8)
|
||||
bsp += 8;
|
||||
db_read_bytes(bsp, sizeof(reg), (void*)®);
|
||||
if (i > 0)
|
||||
db_printf(", ");
|
||||
db_printf("0x%lx", reg);
|
||||
bsp += 8;
|
||||
}
|
||||
} else
|
||||
db_printf("...");
|
||||
db_printf(") at ");
|
||||
|
||||
db_printsym(ip, DB_STGY_PROC);
|
||||
db_printf("\n");
|
||||
|
||||
if (error != ERESTART)
|
||||
continue;
|
||||
if (sp < IA64_RR_BASE(5))
|
||||
break;
|
||||
|
||||
tf = (struct trapframe *)(sp + 16);
|
||||
if ((tf->tf_flags & FRAME_SYSCALL) != 0 ||
|
||||
tf->tf_special.iip < IA64_RR_BASE(5))
|
||||
break;
|
||||
|
||||
/* XXX ask if we should unwind across the trapframe. */
|
||||
db_printf("--- trapframe at %p\n", tf);
|
||||
unw_delete(&rs);
|
||||
error = unw_create_from_frame(&rs, tf);
|
||||
}
|
||||
|
||||
unw_delete(&rs);
|
||||
/*
|
||||
* EJUSTRETURN and ERESTART signal the end of a trace and
|
||||
* are not really errors.
|
||||
*/
|
||||
return ((error > 0) ? error : 0);
|
||||
}
|
||||
|
||||
void
|
||||
db_trace_self(void)
|
||||
{
|
||||
struct pcb pcb;
|
||||
|
||||
savectx(&pcb);
|
||||
db_backtrace(curthread, &pcb, -1);
|
||||
}
|
||||
|
||||
int
|
||||
db_trace_thread(struct thread *td, int count)
|
||||
{
|
||||
struct pcb *ctx;
|
||||
|
||||
ctx = kdb_thr_ctx(td);
|
||||
return (db_backtrace(td, ctx, count));
|
||||
}
|
||||
|
||||
void
|
||||
stack_save(struct stack *st)
|
||||
{
|
||||
|
||||
stack_zero(st);
|
||||
/*
|
||||
* Nothing for now.
|
||||
* Is libuwx reentrant?
|
||||
* Can unw_create* sleep?
|
||||
*/
|
||||
}
|
||||
|
||||
int
|
||||
db_md_set_watchpoint(addr, size)
|
||||
db_expr_t addr;
|
||||
db_expr_t size;
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
db_md_clr_watchpoint(addr, size)
|
||||
db_expr_t addr;
|
||||
db_expr_t size;
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
db_md_list_watchpoints()
|
||||
{
|
||||
return;
|
||||
}
|
Loading…
Reference in New Issue
Block a user