Backported the new stack crawl command ("sc", not "bt" like in NewOS) from
NewOS. Untested yet, though. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@750 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
/*
|
||||
/*
|
||||
** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
** Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
#ifndef _NEWOS_KERNEL_ARCH_DEBUG
|
||||
#define _NEWOS_KERNEL_ARCH_DEBUG
|
||||
#ifndef _KERNEL_ARCH_DEBUG_H
|
||||
#define _KERNEL_ARCH_DEBUG_H
|
||||
|
||||
#endif
|
||||
int arch_dbg_init(kernel_args *ka);
|
||||
|
||||
#endif /* _KERNEL_ARCH_DEBUG_H */
|
||||
|
||||
@@ -82,6 +82,28 @@ typedef struct pdentry {
|
||||
unsigned int addr:20;
|
||||
} pdentry;
|
||||
|
||||
struct iframe {
|
||||
unsigned int gs;
|
||||
unsigned int fs;
|
||||
unsigned int es;
|
||||
unsigned int ds;
|
||||
unsigned int edi;
|
||||
unsigned int esi;
|
||||
unsigned int ebp;
|
||||
unsigned int esp;
|
||||
unsigned int ebx;
|
||||
unsigned int edx;
|
||||
unsigned int ecx;
|
||||
unsigned int eax;
|
||||
unsigned int vector;
|
||||
unsigned int error_code;
|
||||
unsigned int eip;
|
||||
unsigned int cs;
|
||||
unsigned int flags;
|
||||
unsigned int user_esp;
|
||||
unsigned int user_ss;
|
||||
};
|
||||
|
||||
#define nop() __asm__ ("nop"::)
|
||||
|
||||
void setup_system_time(unsigned int cv_factor);
|
||||
@@ -93,6 +115,9 @@ void i386_swap_pgdir(addr new_pgdir);
|
||||
void i386_fsave_swap(void *old_fpu_state, void *new_fpu_state);
|
||||
void i386_fxsave_swap(void *old_fpu_state, void *new_fpu_state);
|
||||
|
||||
#define read_ebp(value) \
|
||||
__asm__("movl %%ebp,%0" : "=r" (value))
|
||||
|
||||
#define read_dr3(value) \
|
||||
__asm__("movl %%dr3,%0" : "=r" (value))
|
||||
|
||||
|
||||
@@ -11,6 +11,11 @@ extern "C" {
|
||||
|
||||
#include <arch/cpu.h>
|
||||
|
||||
|
||||
void i386_push_iframe(struct thread *t, struct iframe *frame);
|
||||
void i386_pop_iframe(struct thread *t);
|
||||
|
||||
|
||||
extern inline struct thread *arch_thread_get_current_thread(void) {
|
||||
struct thread *t;
|
||||
read_dr3(t);
|
||||
|
||||
@@ -10,10 +10,17 @@ struct farcall {
|
||||
unsigned int *ss;
|
||||
};
|
||||
|
||||
#define IFRAME_TRACE_DEPTH 4
|
||||
|
||||
// architecture specific thread info
|
||||
struct arch_thread {
|
||||
struct farcall current_stack;
|
||||
struct farcall interrupt_stack;
|
||||
|
||||
// used to track interrupts on this thread
|
||||
struct iframe *iframes[IFRAME_TRACE_DEPTH];
|
||||
int iframe_ptr;
|
||||
|
||||
// 512 byte floating point save point
|
||||
uint8 fpu_state[512];
|
||||
};
|
||||
@@ -22,5 +29,4 @@ struct arch_team {
|
||||
// nothing here
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _KERNEL_ARCH_x86_THREAD_STRUCT_H */
|
||||
|
||||
@@ -11,7 +11,7 @@ int elf_load_uspace(const char *path, struct team *t, int flags, addr *entry);
|
||||
image_id elf_load_kspace(const char *path, const char *sym_prepend);
|
||||
int elf_unload_kspace( const char *path);
|
||||
addr elf_lookup_symbol(image_id id, const char *symbol);
|
||||
int elf_lookup_symbol_address(addr address, addr *baseAddress, char *text, size_t length);
|
||||
int elf_init(kernel_args *ka);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _KERNEL_ELF_H */
|
||||
|
||||
@@ -2,8 +2,95 @@
|
||||
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||
** Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
|
||||
#include <kernel.h>
|
||||
#include <debug.h>
|
||||
#include <arch/debug.h>
|
||||
#include <Errors.h>
|
||||
|
||||
#include <kernel.h>
|
||||
#include <thread.h>
|
||||
#include <debug.h>
|
||||
#include <elf.h>
|
||||
#include <arch/debug.h>
|
||||
#include <arch/x86/arch_cpu.h>
|
||||
|
||||
|
||||
static int
|
||||
dbg_stack_trace(int argc, char **argv)
|
||||
{
|
||||
struct thread *t;
|
||||
uint32 ebp;
|
||||
int i;
|
||||
|
||||
if (argc < 2)
|
||||
t = thread_get_current_thread();
|
||||
else {
|
||||
dprintf("not supported\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < t->arch_info.iframe_ptr; i++) {
|
||||
char *temp = (char *)t->arch_info.iframes[i];
|
||||
dprintf("iframe %p %p %p\n", temp, temp + sizeof(struct iframe), temp + sizeof(struct iframe) - 8);
|
||||
}
|
||||
|
||||
dprintf("stack trace for thread 0x%x '%s'\n", t->id, t->name);
|
||||
dprintf("frame \tcaller:<base function+offset>\n");
|
||||
dprintf("-------------------------------\n");
|
||||
|
||||
read_ebp(ebp);
|
||||
for (;;) {
|
||||
bool is_iframe = false;
|
||||
// see if the ebp matches the iframe
|
||||
for (i = 0; i < t->arch_info.iframe_ptr; i++) {
|
||||
if (ebp == ((uint32) t->arch_info.iframes[i] - 8)) {
|
||||
// it's an iframe
|
||||
is_iframe = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_iframe) {
|
||||
struct iframe *frame = (struct iframe *)(ebp + 8);
|
||||
|
||||
dprintf("iframe at %p\n", frame);
|
||||
dprintf(" eax\t0x%x\tebx\t0x%x\tecx\t0x%x\tedx\t0x%x\n", frame->eax, frame->ebx, frame->ecx, frame->edx);
|
||||
dprintf(" esi\t0x%x\tedi\t0x%x\tebp\t0x%x\tesp\t0x%x\n", frame->esi, frame->edi, frame->ebp, frame->esp);
|
||||
dprintf(" eip\t0x%x\teflags\t0x%x", frame->eip, frame->flags);
|
||||
if ((frame->error_code & 0x4) != 0) {
|
||||
// from user space
|
||||
dprintf("\tuser esp\t0x%x", frame->user_esp);
|
||||
}
|
||||
dprintf("\n");
|
||||
dprintf(" vector\t0x%x\terror code\t0x%x\n", frame->vector, frame->error_code);
|
||||
ebp = frame->ebp;
|
||||
} else {
|
||||
uint32 eip = *((uint32 *)ebp + 1);
|
||||
char symname[256];
|
||||
addr base_address;
|
||||
|
||||
if (eip == 0 || ebp == 0)
|
||||
break;
|
||||
|
||||
if (elf_lookup_symbol_address(eip, &base_address, symname, sizeof(symname)) >= 0)
|
||||
dprintf("%p\t%p:<%p+%p>\t'%s'\n", (void *)ebp, (void *)eip, (void *)base_address, (void *)(eip - base_address), symname);
|
||||
else
|
||||
dprintf("%p\t%p\n", (void *)ebp, (void *)eip);
|
||||
|
||||
ebp = *(uint32 *)ebp;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
arch_dbg_init(kernel_args *ka)
|
||||
{
|
||||
// at this stage, the debugger command system is alive
|
||||
|
||||
add_debugger_command("sc", &dbg_stack_trace, "Stack crawl for current thread");
|
||||
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
|
||||
// XXX will put stack trace and disassembly routines here
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||
** Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
|
||||
#include <kernel.h>
|
||||
#include <vm.h>
|
||||
#include <debug.h>
|
||||
@@ -30,31 +31,11 @@
|
||||
|
||||
#define MAX_ARGS 16
|
||||
|
||||
struct int_frame {
|
||||
unsigned int gs;
|
||||
unsigned int fs;
|
||||
unsigned int es;
|
||||
unsigned int ds;
|
||||
unsigned int edi;
|
||||
unsigned int esi;
|
||||
unsigned int ebp;
|
||||
unsigned int esp;
|
||||
unsigned int ebx;
|
||||
unsigned int edx;
|
||||
unsigned int ecx;
|
||||
unsigned int eax;
|
||||
unsigned int vector;
|
||||
unsigned int error_code;
|
||||
unsigned int eip;
|
||||
unsigned int cs;
|
||||
unsigned int flags;
|
||||
unsigned int user_esp;
|
||||
unsigned int user_ss;
|
||||
};
|
||||
|
||||
static desc_table *idt = NULL;
|
||||
|
||||
static void interrupt_ack(int n)
|
||||
|
||||
static void
|
||||
interrupt_ack(int n)
|
||||
{
|
||||
if(n >= 0x20 && n < 0x30) {
|
||||
// 8239 controlled interrupt
|
||||
@@ -64,7 +45,9 @@ static void interrupt_ack(int n)
|
||||
}
|
||||
}
|
||||
|
||||
static void _set_gate(desc_table *gate_addr, unsigned int addr, int type, int dpl)
|
||||
|
||||
static void
|
||||
_set_gate(desc_table *gate_addr, unsigned int addr, int type, int dpl)
|
||||
{
|
||||
unsigned int gate1; // first byte of gate desc
|
||||
unsigned int gate2; // second byte of gate desc
|
||||
@@ -76,11 +59,14 @@ static void _set_gate(desc_table *gate_addr, unsigned int addr, int type, int dp
|
||||
gate_addr->b = gate2;
|
||||
}
|
||||
|
||||
void arch_int_enable_io_interrupt(int irq)
|
||||
|
||||
void
|
||||
arch_int_enable_io_interrupt(int irq)
|
||||
{
|
||||
if (irq < 0 || irq >= 0x10)
|
||||
return;
|
||||
dprintf("arch_int_enable_io_interrupt: irq %d\n", irq);
|
||||
|
||||
dprintf("arch_int_enable_io_interrupt: irq %d\n", irq);
|
||||
/* if this is a external interrupt via 8239, enable it here */
|
||||
if (irq < 8)
|
||||
out8(in8(0x21) & ~(1 << irq), 0x21);
|
||||
@@ -88,7 +74,9 @@ dprintf("arch_int_enable_io_interrupt: irq %d\n", irq);
|
||||
out8(in8(0xa1) & ~(1 << (irq - 8)), 0xa1);
|
||||
}
|
||||
|
||||
void arch_int_disable_io_interrupt(int irq)
|
||||
|
||||
void
|
||||
arch_int_disable_io_interrupt(int irq)
|
||||
{
|
||||
/* never disable slave pic line IRQ 2 */
|
||||
if (irq < 0 || irq >= 0x10 || irq == 2)
|
||||
@@ -100,29 +88,39 @@ void arch_int_disable_io_interrupt(int irq)
|
||||
out8(in8(0xa1) | (1 << (irq - 8)), 0xa1);
|
||||
}
|
||||
|
||||
static void set_intr_gate(int n, void *addr)
|
||||
|
||||
static void
|
||||
set_intr_gate(int n, void *addr)
|
||||
{
|
||||
_set_gate(&idt[n], (unsigned int)addr, 14, 0);
|
||||
}
|
||||
|
||||
|
||||
/* XXX - currently unused and static...
|
||||
static void set_trap_gate(int n, void *addr)
|
||||
static void
|
||||
set_trap_gate(int n, void *addr)
|
||||
{
|
||||
_set_gate(&idt[n], (unsigned int)addr, 15, 0);
|
||||
}
|
||||
*/
|
||||
|
||||
static void set_system_gate(int n, void *addr)
|
||||
|
||||
static void
|
||||
set_system_gate(int n, void *addr)
|
||||
{
|
||||
_set_gate(&idt[n], (unsigned int)addr, 15, 3);
|
||||
}
|
||||
|
||||
void arch_int_enable_interrupts(void)
|
||||
|
||||
void
|
||||
arch_int_enable_interrupts(void)
|
||||
{
|
||||
asm("sti");
|
||||
}
|
||||
|
||||
int arch_int_disable_interrupts(void)
|
||||
|
||||
int
|
||||
arch_int_disable_interrupts(void)
|
||||
{
|
||||
int flags;
|
||||
|
||||
@@ -132,7 +130,9 @@ int arch_int_disable_interrupts(void)
|
||||
return flags & 0x200 ? 1 : 0;
|
||||
}
|
||||
|
||||
void arch_int_restore_interrupts(int oldstate)
|
||||
|
||||
void
|
||||
arch_int_restore_interrupts(int oldstate)
|
||||
{
|
||||
int flags = oldstate ? 0x200 : 0;
|
||||
|
||||
@@ -146,7 +146,9 @@ void arch_int_restore_interrupts(int oldstate)
|
||||
: : "r" (flags), "r" (0));
|
||||
}
|
||||
|
||||
bool arch_int_is_interrupts_enabled(void)
|
||||
|
||||
bool
|
||||
arch_int_is_interrupts_enabled(void)
|
||||
{
|
||||
int flags;
|
||||
|
||||
@@ -155,10 +157,16 @@ bool arch_int_is_interrupts_enabled(void)
|
||||
return flags & 0x200 ? 1 : 0;
|
||||
}
|
||||
|
||||
void i386_handle_trap(struct int_frame frame); /* keep the compiler happy, this function must be called only from assembly */
|
||||
void i386_handle_trap(struct int_frame frame)
|
||||
|
||||
void i386_handle_trap(struct iframe frame); /* keep the compiler happy, this function must be called only from assembly */
|
||||
void
|
||||
i386_handle_trap(struct iframe frame)
|
||||
{
|
||||
int ret = B_HANDLED_INTERRUPT;
|
||||
struct thread *thread = thread_get_current_thread();
|
||||
|
||||
if (thread)
|
||||
i386_push_iframe(thread, &frame);
|
||||
|
||||
// if(frame.vector != 0x20)
|
||||
// dprintf("i386_handle_trap: vector 0x%x, ip 0x%x, cpu %d\n", frame.vector, frame.eip, smp_get_current_cpu());
|
||||
@@ -250,13 +258,18 @@ void i386_handle_trap(struct int_frame frame)
|
||||
restore_interrupts(state);
|
||||
}
|
||||
|
||||
if(frame.cs == USER_CODE_SEG || frame.vector == 99) {
|
||||
if (frame.cs == USER_CODE_SEG || frame.vector == 99) {
|
||||
thread_atkernel_exit();
|
||||
}
|
||||
// dprintf("0x%x cpu %d!\n", thread_get_current_thread_id(), smp_get_current_cpu());
|
||||
|
||||
if (thread)
|
||||
i386_pop_iframe(thread);
|
||||
}
|
||||
|
||||
int arch_int_init(kernel_args *ka)
|
||||
|
||||
int
|
||||
arch_int_init(kernel_args *ka)
|
||||
{
|
||||
idt = (desc_table *)ka->arch_args.vir_idt;
|
||||
|
||||
@@ -320,7 +333,9 @@ int arch_int_init(kernel_args *ka)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int arch_int_init2(kernel_args *ka)
|
||||
|
||||
int
|
||||
arch_int_init2(kernel_args *ka)
|
||||
{
|
||||
idt = (desc_table *)ka->arch_args.vir_idt;
|
||||
vm_create_anonymous_region(vm_get_kernel_aspace_id(), "idt", (void *)&idt,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||
** Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
|
||||
#include <kernel.h>
|
||||
#include <stage2.h>
|
||||
#include <debug.h>
|
||||
@@ -12,15 +13,36 @@
|
||||
#include <int.h>
|
||||
#include <string.h>
|
||||
|
||||
int arch_team_init_team_struct(struct team *p, bool kernel)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// from arch_interrupts.S
|
||||
extern void i386_stack_init( struct farcall *interrupt_stack_offset );
|
||||
|
||||
int arch_thread_init_thread_struct(struct thread *t)
|
||||
|
||||
void
|
||||
i386_push_iframe(struct thread *thread, struct iframe *frame)
|
||||
{
|
||||
ASSERT(thread->arch_info.iframe_ptr < IFRAME_TRACE_DEPTH);
|
||||
thread->arch_info.iframes[thread->arch_info.iframe_ptr++] = frame;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
i386_pop_iframe(struct thread *thread)
|
||||
{
|
||||
ASSERT(thread->arch_info.iframe_ptr > 0);
|
||||
thread->arch_info.iframe_ptr--;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
arch_team_init_team_struct(struct team *p, bool kernel)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
arch_thread_init_thread_struct(struct thread *t)
|
||||
{
|
||||
// set up an initial state (stack & fpu)
|
||||
memset(&t->arch_info, 0, sizeof(t->arch_info));
|
||||
@@ -32,7 +54,9 @@ int arch_thread_init_thread_struct(struct thread *t)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int arch_thread_initialize_kthread_stack(struct thread *t, int (*start_func)(void), void (*entry_func)(void), void (*exit_func)(void))
|
||||
|
||||
int
|
||||
arch_thread_initialize_kthread_stack(struct thread *t, int (*start_func)(void), void (*entry_func)(void), void (*exit_func)(void))
|
||||
{
|
||||
unsigned int *kstack = (unsigned int *)t->kernel_stack_base;
|
||||
unsigned int kstack_size = KSTACK_SIZE;
|
||||
@@ -74,12 +98,16 @@ int arch_thread_initialize_kthread_stack(struct thread *t, int (*start_func)(voi
|
||||
return 0;
|
||||
}
|
||||
|
||||
void arch_thread_switch_kstack_and_call(struct thread *t, addr new_kstack, void (*func)(void *), void *arg)
|
||||
|
||||
void
|
||||
arch_thread_switch_kstack_and_call(struct thread *t, addr new_kstack, void (*func)(void *), void *arg)
|
||||
{
|
||||
i386_switch_stack_and_call(new_kstack, func, arg);
|
||||
}
|
||||
|
||||
void arch_thread_context_switch(struct thread *t_from, struct thread *t_to)
|
||||
|
||||
void
|
||||
arch_thread_context_switch(struct thread *t_from, struct thread *t_to)
|
||||
{
|
||||
addr new_pgdir;
|
||||
#if 0
|
||||
@@ -138,7 +166,9 @@ void arch_thread_context_switch(struct thread *t_from, struct thread *t_to)
|
||||
i386_context_switch(&t_from->arch_info, &t_to->arch_info, new_pgdir);
|
||||
}
|
||||
|
||||
void arch_thread_dump_info(void *info)
|
||||
|
||||
void
|
||||
arch_thread_dump_info(void *info)
|
||||
{
|
||||
struct arch_thread *at = (struct arch_thread *)info;
|
||||
|
||||
@@ -147,7 +177,9 @@ void arch_thread_dump_info(void *info)
|
||||
dprintf("\tfpu_state at %p\n", at->fpu_state);
|
||||
}
|
||||
|
||||
void arch_thread_enter_uspace(addr entry, void *args, addr ustack_top)
|
||||
|
||||
void
|
||||
arch_thread_enter_uspace(addr entry, void *args, addr ustack_top)
|
||||
{
|
||||
dprintf("arch_thread_entry_uspace: entry 0x%lx, args %p, ustack_top 0x%lx\n",
|
||||
entry, args, ustack_top);
|
||||
|
||||
+53
-19
@@ -4,6 +4,7 @@
|
||||
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||
** Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
|
||||
#include <kernel.h>
|
||||
#include <debug.h>
|
||||
#include <arch/int.h>
|
||||
@@ -52,7 +53,9 @@ static char *args[MAX_ARGS] = { NULL, };
|
||||
|
||||
#define distance(a, b) ((a) < (b) ? (b) - (a) : (a) - (b))
|
||||
|
||||
static int debug_read_line(char *buf, int max_len)
|
||||
|
||||
static int
|
||||
debug_read_line(char *buf, int max_len)
|
||||
{
|
||||
char c;
|
||||
int ptr = 0;
|
||||
@@ -160,21 +163,23 @@ static int debug_read_line(char *buf, int max_len)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static int debug_parse_line(char *buf, char **argv, int *argc, int max_args)
|
||||
|
||||
static int
|
||||
debug_parse_line(char *buf, char **argv, int *argc, int max_args)
|
||||
{
|
||||
int pos = 0;
|
||||
|
||||
strcpy(parse_line, buf);
|
||||
|
||||
if(!isspace(parse_line[0])) {
|
||||
if (!isspace(parse_line[0])) {
|
||||
argv[0] = parse_line;
|
||||
*argc = 1;
|
||||
} else {
|
||||
*argc = 0;
|
||||
}
|
||||
|
||||
while(parse_line[pos] != '\0') {
|
||||
if(isspace(parse_line[pos])) {
|
||||
while (parse_line[pos] != '\0') {
|
||||
if (isspace(parse_line[pos])) {
|
||||
parse_line[pos] = '\0';
|
||||
// scan all of the whitespace out of this
|
||||
while(isspace(parse_line[++pos]))
|
||||
@@ -193,7 +198,9 @@ static int debug_parse_line(char *buf, char **argv, int *argc, int max_args)
|
||||
return *argc;
|
||||
}
|
||||
|
||||
static void kernel_debugger_loop()
|
||||
|
||||
static void
|
||||
kernel_debugger_loop()
|
||||
{
|
||||
int argc;
|
||||
struct debugger_command *cmd;
|
||||
@@ -226,7 +233,9 @@ static void kernel_debugger_loop()
|
||||
}
|
||||
}
|
||||
|
||||
void kernel_debugger(const char * message)
|
||||
|
||||
void
|
||||
kernel_debugger(const char * message)
|
||||
{
|
||||
dbg_save_registers(&(dbg_register_file[smp_get_current_cpu()][0]));
|
||||
|
||||
@@ -239,7 +248,9 @@ void kernel_debugger(const char * message)
|
||||
kernel_debugger_loop();
|
||||
}
|
||||
|
||||
int panic(const char *fmt, ...)
|
||||
|
||||
int
|
||||
panic(const char *fmt, ...)
|
||||
{
|
||||
int ret = 0;
|
||||
va_list args;
|
||||
@@ -270,7 +281,9 @@ int panic(const char *fmt, ...)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dprintf(const char *fmt, ...)
|
||||
|
||||
int
|
||||
dprintf(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char temp[512];
|
||||
@@ -286,7 +299,9 @@ int dprintf(const char *fmt, ...)
|
||||
return ret;
|
||||
}
|
||||
|
||||
char dbg_putch(char c)
|
||||
|
||||
char
|
||||
dbg_putch(char c)
|
||||
{
|
||||
char ret;
|
||||
int flags = disable_interrupts();
|
||||
@@ -303,7 +318,9 @@ char dbg_putch(char c)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dbg_puts(const char *s)
|
||||
|
||||
void
|
||||
dbg_puts(const char *s)
|
||||
{
|
||||
int flags = disable_interrupts();
|
||||
acquire_spinlock(&dbg_spinlock);
|
||||
@@ -315,7 +332,9 @@ void dbg_puts(const char *s)
|
||||
restore_interrupts(flags);
|
||||
}
|
||||
|
||||
int add_debugger_command(const char * name, int (*func)(int, char **), const char * desc)
|
||||
|
||||
int
|
||||
add_debugger_command(const char * name, int (*func)(int, char **), const char * desc)
|
||||
{
|
||||
int flags;
|
||||
struct debugger_command *cmd;
|
||||
@@ -340,7 +359,9 @@ int add_debugger_command(const char * name, int (*func)(int, char **), const cha
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
|
||||
int remove_debugger_command(const char * name, int (*func)(int, char **))
|
||||
|
||||
int
|
||||
remove_debugger_command(const char * name, int (*func)(int, char **))
|
||||
{
|
||||
int flags;
|
||||
struct debugger_command *cmd;
|
||||
@@ -378,13 +399,16 @@ int remove_debugger_command(const char * name, int (*func)(int, char **))
|
||||
}
|
||||
|
||||
|
||||
static int cmd_reboot(int argc, char **argv)
|
||||
static int
|
||||
cmd_reboot(int argc, char **argv)
|
||||
{
|
||||
reboot();
|
||||
return 0; // I'll be really suprised if this line ever run! ;-)
|
||||
}
|
||||
|
||||
static int cmd_help(int argc, char **argv)
|
||||
|
||||
static int
|
||||
cmd_help(int argc, char **argv)
|
||||
{
|
||||
struct debugger_command *cmd;
|
||||
|
||||
@@ -398,30 +422,40 @@ static int cmd_help(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dbg_init(kernel_args *ka)
|
||||
|
||||
int
|
||||
dbg_init(kernel_args *ka)
|
||||
{
|
||||
commands = NULL;
|
||||
|
||||
return arch_dbg_con_init(ka);
|
||||
}
|
||||
|
||||
int dbg_init2(kernel_args *ka)
|
||||
|
||||
int
|
||||
dbg_init2(kernel_args *ka)
|
||||
{
|
||||
add_debugger_command("help", &cmd_help, "List all debugger commands");
|
||||
add_debugger_command("reboot", &cmd_reboot, "Reboot");
|
||||
add_debugger_command("gdb", &cmd_gdb, "Connect to remote gdb");
|
||||
|
||||
dbg_init(ka);
|
||||
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
|
||||
bool dbg_set_serial_debug(bool new_val)
|
||||
|
||||
bool
|
||||
dbg_set_serial_debug(bool new_val)
|
||||
{
|
||||
int temp = serial_debug_on;
|
||||
serial_debug_on = new_val;
|
||||
return temp;
|
||||
}
|
||||
|
||||
bool dbg_get_serial_debug()
|
||||
|
||||
bool
|
||||
dbg_get_serial_debug()
|
||||
{
|
||||
return serial_debug_on;
|
||||
}
|
||||
|
||||
+19
-13
@@ -84,8 +84,8 @@ static image_id next_image_id = 0;
|
||||
#define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)])
|
||||
|
||||
|
||||
static int
|
||||
get_address_symbol_info(addr address, char *text, int maxtextlen)
|
||||
int
|
||||
elf_lookup_symbol_address(addr address, addr *baseAddress, char *text, size_t length)
|
||||
{
|
||||
struct elf_image_info **ptr;
|
||||
struct elf_image_info *image;
|
||||
@@ -102,7 +102,8 @@ get_address_symbol_info(addr address, char *text, int maxtextlen)
|
||||
found_sym = 0;
|
||||
found_image = 0;
|
||||
found_delta = 0x7fffffff;
|
||||
for(ptr = &kernel_images; *ptr; ptr = &(*ptr)->next) {
|
||||
|
||||
for (ptr = &kernel_images; *ptr; ptr = &(*ptr)->next) {
|
||||
image = *ptr;
|
||||
|
||||
PRINT((" image %p, base = %p, size = %p\n", image, (void *)image->regions[0].start, (void *)image->regions[0].size));
|
||||
@@ -112,7 +113,7 @@ get_address_symbol_info(addr address, char *text, int maxtextlen)
|
||||
PRINT((" searching...\n"));
|
||||
found_image = image;
|
||||
for (i = 0; i < HASHTABSIZE(image); i++) {
|
||||
for(j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) {
|
||||
for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) {
|
||||
long d;
|
||||
sym = &image->syms[j];
|
||||
|
||||
@@ -131,17 +132,22 @@ get_address_symbol_info(addr address, char *text, int maxtextlen)
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (found_sym == 0) {
|
||||
PRINT(("symbol not found!\n"));
|
||||
strlcpy(text, "symbol not found", maxtextlen);
|
||||
rv = -1;
|
||||
} else {
|
||||
|
||||
if (found_sym != 0) {
|
||||
PRINT(("symbol at %p, in image %p, name = %s\n", found_sym, found_image, found_image->name));
|
||||
PRINT(("name index %d, '%s'\n", found_sym->st_name, SYMNAME(found_image, found_sym)));
|
||||
PRINT(("addr = %#lx, offset = %#lx\n",(found_sym->st_value + found_image->regions[0].delta),found_delta));
|
||||
// XXX should honor maxtextlen here
|
||||
sprintf(text, "<%#lx:%s + %#lx> %s", (found_sym->st_value + found_image->regions[0].delta), SYMNAME(found_image, found_sym), found_delta, found_image->name);
|
||||
|
||||
strlcpy(text, SYMNAME(found_image, found_sym), length);
|
||||
|
||||
if (baseAddress)
|
||||
*baseAddress = found_sym->st_value + found_image->regions[0].delta;
|
||||
|
||||
rv = 0;
|
||||
} else {
|
||||
PRINT(("symbol not found!\n"));
|
||||
strlcpy(text, "symbol not found", length);
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
mutex_unlock(&image_lock);
|
||||
@@ -161,8 +167,8 @@ print_address_info(int argc, char **argv)
|
||||
}
|
||||
|
||||
address = atoul(argv[1]);
|
||||
|
||||
get_address_symbol_info(address, text, sizeof(text));
|
||||
|
||||
elf_lookup_symbol_address(address, NULL, text, sizeof(text));
|
||||
dprintf("%p = %s\n",(void *)address,text);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user