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:
Axel Dörfler
2002-08-13 21:42:53 +00:00
parent ef8d7092e8
commit 5ca8da7a4b
10 changed files with 301 additions and 90 deletions
+5 -4
View File
@@ -1,9 +1,10 @@
/* /*
** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. ** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License. ** Distributed under the terms of the NewOS License.
*/ */
#ifndef _NEWOS_KERNEL_ARCH_DEBUG #ifndef _KERNEL_ARCH_DEBUG_H
#define _NEWOS_KERNEL_ARCH_DEBUG #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; unsigned int addr:20;
} pdentry; } 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"::) #define nop() __asm__ ("nop"::)
void setup_system_time(unsigned int cv_factor); 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_fsave_swap(void *old_fpu_state, void *new_fpu_state);
void i386_fxsave_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) \ #define read_dr3(value) \
__asm__("movl %%dr3,%0" : "=r" (value)) __asm__("movl %%dr3,%0" : "=r" (value))
@@ -11,6 +11,11 @@ extern "C" {
#include <arch/cpu.h> #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) { extern inline struct thread *arch_thread_get_current_thread(void) {
struct thread *t; struct thread *t;
read_dr3(t); read_dr3(t);
@@ -10,10 +10,17 @@ struct farcall {
unsigned int *ss; unsigned int *ss;
}; };
#define IFRAME_TRACE_DEPTH 4
// architecture specific thread info // architecture specific thread info
struct arch_thread { struct arch_thread {
struct farcall current_stack; struct farcall current_stack;
struct farcall interrupt_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 // 512 byte floating point save point
uint8 fpu_state[512]; uint8 fpu_state[512];
}; };
@@ -22,5 +29,4 @@ struct arch_team {
// nothing here // nothing here
}; };
#endif #endif /* _KERNEL_ARCH_x86_THREAD_STRUCT_H */
+2 -2
View File
@@ -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); image_id elf_load_kspace(const char *path, const char *sym_prepend);
int elf_unload_kspace( const char *path); int elf_unload_kspace( const char *path);
addr elf_lookup_symbol(image_id id, const char *symbol); 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); int elf_init(kernel_args *ka);
#endif #endif /* _KERNEL_ELF_H */
+88 -1
View File
@@ -2,8 +2,95 @@
** Copyright 2001, Travis Geiselbrecht. All rights reserved. ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License. ** Distributed under the terms of the NewOS License.
*/ */
#include <kernel.h> #include <kernel.h>
#include <debug.h> #include <debug.h>
#include <arch/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
+54 -39
View File
@@ -2,6 +2,7 @@
** Copyright 2001, Travis Geiselbrecht. All rights reserved. ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License. ** Distributed under the terms of the NewOS License.
*/ */
#include <kernel.h> #include <kernel.h>
#include <vm.h> #include <vm.h>
#include <debug.h> #include <debug.h>
@@ -30,31 +31,11 @@
#define MAX_ARGS 16 #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 desc_table *idt = NULL;
static void interrupt_ack(int n)
static void
interrupt_ack(int n)
{ {
if(n >= 0x20 && n < 0x30) { if(n >= 0x20 && n < 0x30) {
// 8239 controlled interrupt // 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 gate1; // first byte of gate desc
unsigned int gate2; // second 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; 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) if (irq < 0 || irq >= 0x10)
return; 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 this is a external interrupt via 8239, enable it here */
if (irq < 8) if (irq < 8)
out8(in8(0x21) & ~(1 << irq), 0x21); 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); 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 */ /* never disable slave pic line IRQ 2 */
if (irq < 0 || irq >= 0x10 || 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); 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); _set_gate(&idt[n], (unsigned int)addr, 14, 0);
} }
/* XXX - currently unused and static... /* 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); _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); _set_gate(&idt[n], (unsigned int)addr, 15, 3);
} }
void arch_int_enable_interrupts(void)
void
arch_int_enable_interrupts(void)
{ {
asm("sti"); asm("sti");
} }
int arch_int_disable_interrupts(void)
int
arch_int_disable_interrupts(void)
{ {
int flags; int flags;
@@ -132,7 +130,9 @@ int arch_int_disable_interrupts(void)
return flags & 0x200 ? 1 : 0; return flags & 0x200 ? 1 : 0;
} }
void arch_int_restore_interrupts(int oldstate)
void
arch_int_restore_interrupts(int oldstate)
{ {
int flags = oldstate ? 0x200 : 0; int flags = oldstate ? 0x200 : 0;
@@ -146,7 +146,9 @@ void arch_int_restore_interrupts(int oldstate)
: : "r" (flags), "r" (0)); : : "r" (flags), "r" (0));
} }
bool arch_int_is_interrupts_enabled(void)
bool
arch_int_is_interrupts_enabled(void)
{ {
int flags; int flags;
@@ -155,10 +157,16 @@ bool arch_int_is_interrupts_enabled(void)
return flags & 0x200 ? 1 : 0; 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; int ret = B_HANDLED_INTERRUPT;
struct thread *thread = thread_get_current_thread();
if (thread)
i386_push_iframe(thread, &frame);
// if(frame.vector != 0x20) // 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()); // 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); restore_interrupts(state);
} }
if(frame.cs == USER_CODE_SEG || frame.vector == 99) { if (frame.cs == USER_CODE_SEG || frame.vector == 99) {
thread_atkernel_exit(); thread_atkernel_exit();
} }
// dprintf("0x%x cpu %d!\n", thread_get_current_thread_id(), smp_get_current_cpu()); // 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; idt = (desc_table *)ka->arch_args.vir_idt;
@@ -320,7 +333,9 @@ int arch_int_init(kernel_args *ka)
return 0; return 0;
} }
int arch_int_init2(kernel_args *ka)
int
arch_int_init2(kernel_args *ka)
{ {
idt = (desc_table *)ka->arch_args.vir_idt; idt = (desc_table *)ka->arch_args.vir_idt;
vm_create_anonymous_region(vm_get_kernel_aspace_id(), "idt", (void *)&idt, vm_create_anonymous_region(vm_get_kernel_aspace_id(), "idt", (void *)&idt,
+42 -10
View File
@@ -2,6 +2,7 @@
** Copyright 2001, Travis Geiselbrecht. All rights reserved. ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License. ** Distributed under the terms of the NewOS License.
*/ */
#include <kernel.h> #include <kernel.h>
#include <stage2.h> #include <stage2.h>
#include <debug.h> #include <debug.h>
@@ -12,15 +13,36 @@
#include <int.h> #include <int.h>
#include <string.h> #include <string.h>
int arch_team_init_team_struct(struct team *p, bool kernel)
{
return 0;
}
// from arch_interrupts.S // from arch_interrupts.S
extern void i386_stack_init( struct farcall *interrupt_stack_offset ); 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) // set up an initial state (stack & fpu)
memset(&t->arch_info, 0, sizeof(t->arch_info)); memset(&t->arch_info, 0, sizeof(t->arch_info));
@@ -32,7 +54,9 @@ int arch_thread_init_thread_struct(struct thread *t)
return 0; 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 = (unsigned int *)t->kernel_stack_base;
unsigned int kstack_size = KSTACK_SIZE; 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; 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); 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; addr new_pgdir;
#if 0 #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); 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; 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); 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", dprintf("arch_thread_entry_uspace: entry 0x%lx, args %p, ustack_top 0x%lx\n",
entry, args, ustack_top); entry, args, ustack_top);
+53 -19
View File
@@ -4,6 +4,7 @@
** Copyright 2001, Travis Geiselbrecht. All rights reserved. ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License. ** Distributed under the terms of the NewOS License.
*/ */
#include <kernel.h> #include <kernel.h>
#include <debug.h> #include <debug.h>
#include <arch/int.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)) #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; char c;
int ptr = 0; int ptr = 0;
@@ -160,21 +163,23 @@ static int debug_read_line(char *buf, int max_len)
return ptr; 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; int pos = 0;
strcpy(parse_line, buf); strcpy(parse_line, buf);
if(!isspace(parse_line[0])) { if (!isspace(parse_line[0])) {
argv[0] = parse_line; argv[0] = parse_line;
*argc = 1; *argc = 1;
} else { } else {
*argc = 0; *argc = 0;
} }
while(parse_line[pos] != '\0') { while (parse_line[pos] != '\0') {
if(isspace(parse_line[pos])) { if (isspace(parse_line[pos])) {
parse_line[pos] = '\0'; parse_line[pos] = '\0';
// scan all of the whitespace out of this // scan all of the whitespace out of this
while(isspace(parse_line[++pos])) 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; return *argc;
} }
static void kernel_debugger_loop()
static void
kernel_debugger_loop()
{ {
int argc; int argc;
struct debugger_command *cmd; 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])); dbg_save_registers(&(dbg_register_file[smp_get_current_cpu()][0]));
@@ -239,7 +248,9 @@ void kernel_debugger(const char * message)
kernel_debugger_loop(); kernel_debugger_loop();
} }
int panic(const char *fmt, ...)
int
panic(const char *fmt, ...)
{ {
int ret = 0; int ret = 0;
va_list args; va_list args;
@@ -270,7 +281,9 @@ int panic(const char *fmt, ...)
return ret; return ret;
} }
int dprintf(const char *fmt, ...)
int
dprintf(const char *fmt, ...)
{ {
va_list args; va_list args;
char temp[512]; char temp[512];
@@ -286,7 +299,9 @@ int dprintf(const char *fmt, ...)
return ret; return ret;
} }
char dbg_putch(char c)
char
dbg_putch(char c)
{ {
char ret; char ret;
int flags = disable_interrupts(); int flags = disable_interrupts();
@@ -303,7 +318,9 @@ char dbg_putch(char c)
return ret; return ret;
} }
void dbg_puts(const char *s)
void
dbg_puts(const char *s)
{ {
int flags = disable_interrupts(); int flags = disable_interrupts();
acquire_spinlock(&dbg_spinlock); acquire_spinlock(&dbg_spinlock);
@@ -315,7 +332,9 @@ void dbg_puts(const char *s)
restore_interrupts(flags); 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; int flags;
struct debugger_command *cmd; 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; 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; int flags;
struct debugger_command *cmd; 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(); reboot();
return 0; // I'll be really suprised if this line ever run! ;-) 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; struct debugger_command *cmd;
@@ -398,30 +422,40 @@ static int cmd_help(int argc, char **argv)
return 0; return 0;
} }
int dbg_init(kernel_args *ka)
int
dbg_init(kernel_args *ka)
{ {
commands = NULL; commands = NULL;
return arch_dbg_con_init(ka); 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("help", &cmd_help, "List all debugger commands");
add_debugger_command("reboot", &cmd_reboot, "Reboot"); add_debugger_command("reboot", &cmd_reboot, "Reboot");
add_debugger_command("gdb", &cmd_gdb, "Connect to remote gdb"); add_debugger_command("gdb", &cmd_gdb, "Connect to remote gdb");
dbg_init(ka);
return B_NO_ERROR; 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; int temp = serial_debug_on;
serial_debug_on = new_val; serial_debug_on = new_val;
return temp; return temp;
} }
bool dbg_get_serial_debug()
bool
dbg_get_serial_debug()
{ {
return serial_debug_on; return serial_debug_on;
} }
+19 -13
View File
@@ -84,8 +84,8 @@ static image_id next_image_id = 0;
#define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)]) #define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)])
static int int
get_address_symbol_info(addr address, char *text, int maxtextlen) elf_lookup_symbol_address(addr address, addr *baseAddress, char *text, size_t length)
{ {
struct elf_image_info **ptr; struct elf_image_info **ptr;
struct elf_image_info *image; struct elf_image_info *image;
@@ -102,7 +102,8 @@ get_address_symbol_info(addr address, char *text, int maxtextlen)
found_sym = 0; found_sym = 0;
found_image = 0; found_image = 0;
found_delta = 0x7fffffff; found_delta = 0x7fffffff;
for(ptr = &kernel_images; *ptr; ptr = &(*ptr)->next) {
for (ptr = &kernel_images; *ptr; ptr = &(*ptr)->next) {
image = *ptr; image = *ptr;
PRINT((" image %p, base = %p, size = %p\n", image, (void *)image->regions[0].start, (void *)image->regions[0].size)); 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")); PRINT((" searching...\n"));
found_image = image; found_image = image;
for (i = 0; i < HASHTABSIZE(image); i++) { 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; long d;
sym = &image->syms[j]; sym = &image->syms[j];
@@ -131,17 +132,22 @@ get_address_symbol_info(addr address, char *text, int maxtextlen)
} }
break; break;
} }
if (found_sym == 0) {
PRINT(("symbol not found!\n")); if (found_sym != 0) {
strlcpy(text, "symbol not found", maxtextlen);
rv = -1;
} else {
PRINT(("symbol at %p, in image %p, name = %s\n", found_sym, found_image, found_image->name)); 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(("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)); 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; rv = 0;
} else {
PRINT(("symbol not found!\n"));
strlcpy(text, "symbol not found", length);
rv = -1;
} }
mutex_unlock(&image_lock); mutex_unlock(&image_lock);
@@ -161,8 +167,8 @@ print_address_info(int argc, char **argv)
} }
address = atoul(argv[1]); 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); dprintf("%p = %s\n",(void *)address,text);
return 0; return 0;
} }