aboutsummaryrefslogtreecommitdiff
path: root/arch/ppc/xmon/xmon.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-06-21 17:15:30 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-21 18:46:26 -0700
commit6879dc137ea4efad65cab8bf8a7c0b742bcf92cc (patch)
tree13ca02150a892e97f3da20ac9cc052508cc7e8a8 /arch/ppc/xmon/xmon.c
parenta70d439345875d476ede258094356e2acd09b1a1 (diff)
[PATCH] ppc32: Kill embedded system.map, use kallsyms
This patch kills the whole embedded System.map mecanism and the bootloader-passed System.map that was used to provide symbol resolution in xmon. Instead, xmon now uses kallsyms like ppc64 does. No hurry getting that in Linus tree, let it be tested in -mm for a while first and make sure it doesn't break various embedded configs. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc/xmon/xmon.c')
-rw-r--r--arch/ppc/xmon/xmon.c270
1 files changed, 72 insertions, 198 deletions
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
index 8565f49b8b0b..be7869e39465 100644
--- a/arch/ppc/xmon/xmon.c
+++ b/arch/ppc/xmon/xmon.c
@@ -9,6 +9,7 @@
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
+#include <linux/kallsyms.h>
#include <asm/ptrace.h>
#include <asm/string.h>
#include <asm/prom.h>
@@ -93,8 +94,7 @@ static void take_input(char *);
static unsigned read_spr(int);
static void write_spr(int, unsigned);
static void super_regs(void);
-static void print_sysmap(void);
-static void sysmap_lookup(void);
+static void symbol_lookup(void);
static void remove_bpts(void);
static void insert_bpts(void);
static struct bpt *at_breakpoint(unsigned pc);
@@ -103,7 +103,6 @@ static void cacheflush(void);
#ifdef CONFIG_SMP
static void cpu_cmd(void);
#endif /* CONFIG_SMP */
-static int pretty_print_addr(unsigned long addr);
static void csum(void);
#ifdef CONFIG_BOOTX_TEXT
static void vidcmds(void);
@@ -120,8 +119,6 @@ extern void longjmp(u_int *, int);
extern void xmon_enter(void);
extern void xmon_leave(void);
-extern char* xmon_find_symbol(unsigned long addr, unsigned long* saddr);
-extern unsigned long xmon_symbol_to_addr(char* symbol);
static unsigned start_tb[NR_CPUS][2];
static unsigned stop_tb[NR_CPUS][2];
@@ -148,7 +145,6 @@ Commands:\n\
mm move a block of memory\n\
ms set a block of memory\n\
md compare two blocks of memory\n\
- M print System.map\n\
r print registers\n\
S print special registers\n\
t print backtrace\n\
@@ -175,6 +171,35 @@ extern inline void __delay(unsigned int loops)
"r" (loops) : "ctr");
}
+/* Print an address in numeric and symbolic form (if possible) */
+static void xmon_print_symbol(unsigned long address, const char *mid,
+ const char *after)
+{
+ char *modname;
+ const char *name = NULL;
+ unsigned long offset, size;
+ static char tmpstr[128];
+
+ printf("%.8lx", address);
+ if (setjmp(bus_error_jmp) == 0) {
+ debugger_fault_handler = handle_fault;
+ sync();
+ name = kallsyms_lookup(address, &size, &offset, &modname,
+ tmpstr);
+ sync();
+ /* wait a little while to see if we get a machine check */
+ __delay(200);
+ }
+ debugger_fault_handler = NULL;
+
+ if (name) {
+ printf("%s%s+%#lx/%#lx", mid, name, offset, size);
+ if (modname)
+ printf(" [%s]", modname);
+ }
+ printf("%s", after);
+}
+
static void get_tb(unsigned *p)
{
unsigned hi, lo, hiagain;
@@ -454,7 +479,7 @@ cmds(struct pt_regs *excp)
dump();
break;
case 'l':
- sysmap_lookup();
+ symbol_lookup();
break;
case 'r':
if (excp != NULL)
@@ -466,9 +491,6 @@ cmds(struct pt_regs *excp)
else
excprint(excp);
break;
- case 'M':
- print_sysmap();
- break;
case 'S':
super_regs();
break;
@@ -825,20 +847,19 @@ backtrace(struct pt_regs *excp)
for (; sp != 0; sp = stack[0]) {
if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
break;
- pretty_print_addr(stack[1]);
- printf(" ");
+ printf("[%.8lx] ", stack);
+ xmon_print_symbol(stack[1], " ", "\n");
if (stack[1] == (unsigned) &ret_from_except
|| stack[1] == (unsigned) &ret_from_except_full
|| stack[1] == (unsigned) &ret_from_syscall) {
if (mread(sp+16, &regs, sizeof(regs)) != sizeof(regs))
break;
- printf("\nexception:%x [%x] %x ", regs.trap, sp+16,
+ printf("exception:%x [%x] %x\n", regs.trap, sp+16,
regs.nip);
sp = regs.gpr[1];
if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
break;
}
- printf("\n");
}
}
@@ -859,11 +880,10 @@ excprint(struct pt_regs *fp)
#ifdef CONFIG_SMP
printf("cpu %d: ", smp_processor_id());
#endif /* CONFIG_SMP */
- printf("vector: %x at pc = ", fp->trap);
- pretty_print_addr(fp->nip);
- printf(", lr = ");
- pretty_print_addr(fp->link);
- printf("\nmsr = %x, sp = %x [%x]\n", fp->msr, fp->gpr[1], fp);
+ printf("vector: %x at pc=", fp->trap);
+ xmon_print_symbol(fp->nip, ": ", ", lr=");
+ xmon_print_symbol(fp->link, ": ", "\n");
+ printf("msr = %x, sp = %x [%x]\n", fp->msr, fp->gpr[1], fp);
trap = TRAP(fp);
if (trap == 0x300 || trap == 0x600)
printf("dar = %x, dsisr = %x\n", fp->dar, fp->dsisr);
@@ -951,24 +971,6 @@ extern char exc_prolog;
extern char dec_exc;
void
-print_sysmap(void)
-{
- extern char *sysmap;
- if ( sysmap ) {
- printf("System.map: \n");
- if( setjmp(bus_error_jmp) == 0 ) {
- debugger_fault_handler = handle_fault;
- sync();
- xmon_puts(sysmap);
- sync();
- }
- debugger_fault_handler = NULL;
- }
- else
- printf("No System.map\n");
-}
-
-void
super_regs(void)
{
int i, cmd;
@@ -1738,7 +1740,7 @@ scanhex(unsigned *vp)
printf("invalid register name '%%%s'\n", regname);
return 0;
} else if (c == '$') {
- static char symname[64];
+ static char symname[128];
int i;
for (i=0; i<63; i++) {
c = inchar();
@@ -1749,7 +1751,14 @@ scanhex(unsigned *vp)
symname[i] = c;
}
symname[i++] = 0;
- *vp = xmon_symbol_to_addr(symname);
+ *vp = 0;
+ if (setjmp(bus_error_jmp) == 0) {
+ debugger_fault_handler = handle_fault;
+ sync();
+ *vp = kallsyms_lookup_name(symname);
+ sync();
+ }
+ debugger_fault_handler = NULL;
if (!(*vp)) {
printf("unknown symbol\n");
return 0;
@@ -1840,169 +1849,34 @@ take_input(char *str)
lineptr = str;
}
-void
-sysmap_lookup(void)
+static void
+symbol_lookup(void)
{
int type = inchar();
unsigned addr;
- static char tmp[64];
- char* cur;
-
- extern char *sysmap;
- extern unsigned long sysmap_size;
- if ( !sysmap || !sysmap_size )
- return;
-
- switch(type) {
- case 'a':
- if (scanhex(&addr)) {
- pretty_print_addr(addr);
- printf("\n");
- }
- termch = 0;
- break;
- case 's':
- getstring(tmp, 64);
- if( setjmp(bus_error_jmp) == 0 ) {
- debugger_fault_handler = handle_fault;
- sync();
- cur = sysmap;
- do {
- cur = strstr(cur, tmp);
- if (cur) {
- static char res[64];
- char *p, *d;
- p = cur;
- while(p > sysmap && *p != 10)
- p--;
- if (*p == 10) p++;
- d = res;
- while(*p && p < (sysmap + sysmap_size) && *p != 10)
- *(d++) = *(p++);
- *(d++) = 0;
- printf("%s\n", res);
- cur++;
- }
- } while (cur);
- sync();
- }
- debugger_fault_handler = NULL;
- termch = 0;
- break;
- }
-}
+ static char tmp[128];
-static int
-pretty_print_addr(unsigned long addr)
-{
- char *sym;
- unsigned long saddr;
-
- printf("%08x", addr);
- sym = xmon_find_symbol(addr, &saddr);
- if (sym)
- printf(" (%s+0x%x)", sym, addr-saddr);
- return (sym != 0);
-}
-
-char*
-xmon_find_symbol(unsigned long addr, unsigned long* saddr)
-{
- static char rbuffer[64];
- char *p, *ep, *limit;
- unsigned long prev, next;
- char* psym;
-
- extern char *sysmap;
- extern unsigned long sysmap_size;
- if ( !sysmap || !sysmap_size )
- return NULL;
-
- prev = 0;
- psym = NULL;
- p = sysmap;
- limit = p + sysmap_size;
- if( setjmp(bus_error_jmp) == 0 ) {
- debugger_fault_handler = handle_fault;
- sync();
- do {
- next = simple_strtoul(p, &p, 16);
- if (next > addr && prev <= addr) {
- if (!psym)
- goto bail;
- ep = rbuffer;
- p = psym;
- while(*p && p < limit && *p == 32)
- p++;
- while(*p && p < limit && *p != 10 && (ep - rbuffer) < 63)
- *(ep++) = *(p++);
- *(ep++) = 0;
- if (saddr)
- *saddr = prev;
- debugger_fault_handler = NULL;
- return rbuffer;
- }
- prev = next;
- psym = p;
- while(*p && p < limit && *p != 10)
- p++;
- if (*p) p++;
- } while(*p && p < limit && next);
-bail:
- sync();
+ switch (type) {
+ case 'a':
+ if (scanhex(&addr))
+ xmon_print_symbol(addr, ": ", "\n");
+ termch = 0;
+ break;
+ case 's':
+ getstring(tmp, 64);
+ if (setjmp(bus_error_jmp) == 0) {
+ debugger_fault_handler = handle_fault;
+ sync();
+ addr = kallsyms_lookup_name(tmp);
+ if (addr)
+ printf("%s: %lx\n", tmp, addr);
+ else
+ printf("Symbol '%s' not found.\n", tmp);
+ sync();
+ }
+ debugger_fault_handler = NULL;
+ termch = 0;
+ break;
}
- debugger_fault_handler = NULL;
- return NULL;
}
-unsigned long
-xmon_symbol_to_addr(char* symbol)
-{
- char *p, *cur;
- char *match = NULL;
- int goodness = 0;
- int result = 0;
-
- extern char *sysmap;
- extern unsigned long sysmap_size;
- if ( !sysmap || !sysmap_size )
- return 0;
-
- if( setjmp(bus_error_jmp) == 0 ) {
- debugger_fault_handler = handle_fault;
- sync();
- cur = sysmap;
- while(cur) {
- cur = strstr(cur, symbol);
- if (cur) {
- int gd = 1;
-
- /* best match if equal, better match if
- * begins with
- */
- if (cur == sysmap || *(cur-1) == ' ') {
- gd++;
- if (cur[strlen(symbol)] == 10)
- gd++;
- }
- if (gd > goodness) {
- match = cur;
- goodness = gd;
- if (gd == 3)
- break;
- }
- cur++;
- }
- }
- if (goodness) {
- p = match;
- while(p > sysmap && *p != 10)
- p--;
- if (*p == 10) p++;
- result = simple_strtoul(p, &p, 16);
- }
- sync();
- }
- debugger_fault_handler = NULL;
- return result;
-}