aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/xmon
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-06-21 20:15:30 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-21 21:46:26 -0400
commit6879dc137ea4efad65cab8bf8a7c0b742bcf92cc (patch)
tree13ca02150a892e97f3da20ac9cc052508cc7e8a8 /arch/ppc/xmon
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')
-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 @@
9#include <linux/smp.h> 9#include <linux/smp.h>
10#include <linux/interrupt.h> 10#include <linux/interrupt.h>
11#include <linux/bitops.h> 11#include <linux/bitops.h>
12#include <linux/kallsyms.h>
12#include <asm/ptrace.h> 13#include <asm/ptrace.h>
13#include <asm/string.h> 14#include <asm/string.h>
14#include <asm/prom.h> 15#include <asm/prom.h>
@@ -93,8 +94,7 @@ static void take_input(char *);
93static unsigned read_spr(int); 94static unsigned read_spr(int);
94static void write_spr(int, unsigned); 95static void write_spr(int, unsigned);
95static void super_regs(void); 96static void super_regs(void);
96static void print_sysmap(void); 97static void symbol_lookup(void);
97static void sysmap_lookup(void);
98static void remove_bpts(void); 98static void remove_bpts(void);
99static void insert_bpts(void); 99static void insert_bpts(void);
100static struct bpt *at_breakpoint(unsigned pc); 100static struct bpt *at_breakpoint(unsigned pc);
@@ -103,7 +103,6 @@ static void cacheflush(void);
103#ifdef CONFIG_SMP 103#ifdef CONFIG_SMP
104static void cpu_cmd(void); 104static void cpu_cmd(void);
105#endif /* CONFIG_SMP */ 105#endif /* CONFIG_SMP */
106static int pretty_print_addr(unsigned long addr);
107static void csum(void); 106static void csum(void);
108#ifdef CONFIG_BOOTX_TEXT 107#ifdef CONFIG_BOOTX_TEXT
109static void vidcmds(void); 108static void vidcmds(void);
@@ -120,8 +119,6 @@ extern void longjmp(u_int *, int);
120 119
121extern void xmon_enter(void); 120extern void xmon_enter(void);
122extern void xmon_leave(void); 121extern void xmon_leave(void);
123extern char* xmon_find_symbol(unsigned long addr, unsigned long* saddr);
124extern unsigned long xmon_symbol_to_addr(char* symbol);
125 122
126static unsigned start_tb[NR_CPUS][2]; 123static unsigned start_tb[NR_CPUS][2];
127static unsigned stop_tb[NR_CPUS][2]; 124static unsigned stop_tb[NR_CPUS][2];
@@ -148,7 +145,6 @@ Commands:\n\
148 mm move a block of memory\n\ 145 mm move a block of memory\n\
149 ms set a block of memory\n\ 146 ms set a block of memory\n\
150 md compare two blocks of memory\n\ 147 md compare two blocks of memory\n\
151 M print System.map\n\
152 r print registers\n\ 148 r print registers\n\
153 S print special registers\n\ 149 S print special registers\n\
154 t print backtrace\n\ 150 t print backtrace\n\
@@ -175,6 +171,35 @@ extern inline void __delay(unsigned int loops)
175 "r" (loops) : "ctr"); 171 "r" (loops) : "ctr");
176} 172}
177 173
174/* Print an address in numeric and symbolic form (if possible) */
175static void xmon_print_symbol(unsigned long address, const char *mid,
176 const char *after)
177{
178 char *modname;
179 const char *name = NULL;
180 unsigned long offset, size;
181 static char tmpstr[128];
182
183 printf("%.8lx", address);
184 if (setjmp(bus_error_jmp) == 0) {
185 debugger_fault_handler = handle_fault;
186 sync();
187 name = kallsyms_lookup(address, &size, &offset, &modname,
188 tmpstr);
189 sync();
190 /* wait a little while to see if we get a machine check */
191 __delay(200);
192 }
193 debugger_fault_handler = NULL;
194
195 if (name) {
196 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
197 if (modname)
198 printf(" [%s]", modname);
199 }
200 printf("%s", after);
201}
202
178static void get_tb(unsigned *p) 203static void get_tb(unsigned *p)
179{ 204{
180 unsigned hi, lo, hiagain; 205 unsigned hi, lo, hiagain;
@@ -454,7 +479,7 @@ cmds(struct pt_regs *excp)
454 dump(); 479 dump();
455 break; 480 break;
456 case 'l': 481 case 'l':
457 sysmap_lookup(); 482 symbol_lookup();
458 break; 483 break;
459 case 'r': 484 case 'r':
460 if (excp != NULL) 485 if (excp != NULL)
@@ -466,9 +491,6 @@ cmds(struct pt_regs *excp)
466 else 491 else
467 excprint(excp); 492 excprint(excp);
468 break; 493 break;
469 case 'M':
470 print_sysmap();
471 break;
472 case 'S': 494 case 'S':
473 super_regs(); 495 super_regs();
474 break; 496 break;
@@ -825,20 +847,19 @@ backtrace(struct pt_regs *excp)
825 for (; sp != 0; sp = stack[0]) { 847 for (; sp != 0; sp = stack[0]) {
826 if (mread(sp, stack, sizeof(stack)) != sizeof(stack)) 848 if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
827 break; 849 break;
828 pretty_print_addr(stack[1]); 850 printf("[%.8lx] ", stack);
829 printf(" "); 851 xmon_print_symbol(stack[1], " ", "\n");
830 if (stack[1] == (unsigned) &ret_from_except 852 if (stack[1] == (unsigned) &ret_from_except
831 || stack[1] == (unsigned) &ret_from_except_full 853 || stack[1] == (unsigned) &ret_from_except_full
832 || stack[1] == (unsigned) &ret_from_syscall) { 854 || stack[1] == (unsigned) &ret_from_syscall) {
833 if (mread(sp+16, &regs, sizeof(regs)) != sizeof(regs)) 855 if (mread(sp+16, &regs, sizeof(regs)) != sizeof(regs))
834 break; 856 break;
835 printf("\nexception:%x [%x] %x ", regs.trap, sp+16, 857 printf("exception:%x [%x] %x\n", regs.trap, sp+16,
836 regs.nip); 858 regs.nip);
837 sp = regs.gpr[1]; 859 sp = regs.gpr[1];
838 if (mread(sp, stack, sizeof(stack)) != sizeof(stack)) 860 if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
839 break; 861 break;
840 } 862 }
841 printf("\n");
842 } 863 }
843} 864}
844 865
@@ -859,11 +880,10 @@ excprint(struct pt_regs *fp)
859#ifdef CONFIG_SMP 880#ifdef CONFIG_SMP
860 printf("cpu %d: ", smp_processor_id()); 881 printf("cpu %d: ", smp_processor_id());
861#endif /* CONFIG_SMP */ 882#endif /* CONFIG_SMP */
862 printf("vector: %x at pc = ", fp->trap); 883 printf("vector: %x at pc=", fp->trap);
863 pretty_print_addr(fp->nip); 884 xmon_print_symbol(fp->nip, ": ", ", lr=");
864 printf(", lr = "); 885 xmon_print_symbol(fp->link, ": ", "\n");
865 pretty_print_addr(fp->link); 886 printf("msr = %x, sp = %x [%x]\n", fp->msr, fp->gpr[1], fp);
866 printf("\nmsr = %x, sp = %x [%x]\n", fp->msr, fp->gpr[1], fp);
867 trap = TRAP(fp); 887 trap = TRAP(fp);
868 if (trap == 0x300 || trap == 0x600) 888 if (trap == 0x300 || trap == 0x600)
869 printf("dar = %x, dsisr = %x\n", fp->dar, fp->dsisr); 889 printf("dar = %x, dsisr = %x\n", fp->dar, fp->dsisr);
@@ -951,24 +971,6 @@ extern char exc_prolog;
951extern char dec_exc; 971extern char dec_exc;
952 972
953void 973void
954print_sysmap(void)
955{
956 extern char *sysmap;
957 if ( sysmap ) {
958 printf("System.map: \n");
959 if( setjmp(bus_error_jmp) == 0 ) {
960 debugger_fault_handler = handle_fault;
961 sync();
962 xmon_puts(sysmap);
963 sync();
964 }
965 debugger_fault_handler = NULL;
966 }
967 else
968 printf("No System.map\n");
969}
970
971void
972super_regs(void) 974super_regs(void)
973{ 975{
974 int i, cmd; 976 int i, cmd;
@@ -1738,7 +1740,7 @@ scanhex(unsigned *vp)
1738 printf("invalid register name '%%%s'\n", regname); 1740 printf("invalid register name '%%%s'\n", regname);
1739 return 0; 1741 return 0;
1740 } else if (c == '$') { 1742 } else if (c == '$') {
1741 static char symname[64]; 1743 static char symname[128];
1742 int i; 1744 int i;
1743 for (i=0; i<63; i++) { 1745 for (i=0; i<63; i++) {
1744 c = inchar(); 1746 c = inchar();
@@ -1749,7 +1751,14 @@ scanhex(unsigned *vp)
1749 symname[i] = c; 1751 symname[i] = c;
1750 } 1752 }
1751 symname[i++] = 0; 1753 symname[i++] = 0;
1752 *vp = xmon_symbol_to_addr(symname); 1754 *vp = 0;
1755 if (setjmp(bus_error_jmp) == 0) {
1756 debugger_fault_handler = handle_fault;
1757 sync();
1758 *vp = kallsyms_lookup_name(symname);
1759 sync();
1760 }
1761 debugger_fault_handler = NULL;
1753 if (!(*vp)) { 1762 if (!(*vp)) {
1754 printf("unknown symbol\n"); 1763 printf("unknown symbol\n");
1755 return 0; 1764 return 0;
@@ -1840,169 +1849,34 @@ take_input(char *str)
1840 lineptr = str; 1849 lineptr = str;
1841} 1850}
1842 1851
1843void 1852static void
1844sysmap_lookup(void) 1853symbol_lookup(void)
1845{ 1854{
1846 int type = inchar(); 1855 int type = inchar();
1847 unsigned addr; 1856 unsigned addr;
1848 static char tmp[64]; 1857 static char tmp[128];
1849 char* cur;
1850
1851 extern char *sysmap;
1852 extern unsigned long sysmap_size;
1853 if ( !sysmap || !sysmap_size )
1854 return;
1855
1856 switch(type) {
1857 case 'a':
1858 if (scanhex(&addr)) {
1859 pretty_print_addr(addr);
1860 printf("\n");
1861 }
1862 termch = 0;
1863 break;
1864 case 's':
1865 getstring(tmp, 64);
1866 if( setjmp(bus_error_jmp) == 0 ) {
1867 debugger_fault_handler = handle_fault;
1868 sync();
1869 cur = sysmap;
1870 do {
1871 cur = strstr(cur, tmp);
1872 if (cur) {
1873 static char res[64];
1874 char *p, *d;
1875 p = cur;
1876 while(p > sysmap && *p != 10)
1877 p--;
1878 if (*p == 10) p++;
1879 d = res;
1880 while(*p && p < (sysmap + sysmap_size) && *p != 10)
1881 *(d++) = *(p++);
1882 *(d++) = 0;
1883 printf("%s\n", res);
1884 cur++;
1885 }
1886 } while (cur);
1887 sync();
1888 }
1889 debugger_fault_handler = NULL;
1890 termch = 0;
1891 break;
1892 }
1893}
1894 1858
1895static int 1859 switch (type) {
1896pretty_print_addr(unsigned long addr) 1860 case 'a':
1897{ 1861 if (scanhex(&addr))
1898 char *sym; 1862 xmon_print_symbol(addr, ": ", "\n");
1899 unsigned long saddr; 1863 termch = 0;
1900 1864 break;
1901 printf("%08x", addr); 1865 case 's':
1902 sym = xmon_find_symbol(addr, &saddr); 1866 getstring(tmp, 64);
1903 if (sym) 1867 if (setjmp(bus_error_jmp) == 0) {
1904 printf(" (%s+0x%x)", sym, addr-saddr); 1868 debugger_fault_handler = handle_fault;
1905 return (sym != 0); 1869 sync();
1906} 1870 addr = kallsyms_lookup_name(tmp);
1907 1871 if (addr)
1908char* 1872 printf("%s: %lx\n", tmp, addr);
1909xmon_find_symbol(unsigned long addr, unsigned long* saddr) 1873 else
1910{ 1874 printf("Symbol '%s' not found.\n", tmp);
1911 static char rbuffer[64]; 1875 sync();
1912 char *p, *ep, *limit; 1876 }
1913 unsigned long prev, next; 1877 debugger_fault_handler = NULL;
1914 char* psym; 1878 termch = 0;
1915 1879 break;
1916 extern char *sysmap;
1917 extern unsigned long sysmap_size;
1918 if ( !sysmap || !sysmap_size )
1919 return NULL;
1920
1921 prev = 0;
1922 psym = NULL;
1923 p = sysmap;
1924 limit = p + sysmap_size;
1925 if( setjmp(bus_error_jmp) == 0 ) {
1926 debugger_fault_handler = handle_fault;
1927 sync();
1928 do {
1929 next = simple_strtoul(p, &p, 16);
1930 if (next > addr && prev <= addr) {
1931 if (!psym)
1932 goto bail;
1933 ep = rbuffer;
1934 p = psym;
1935 while(*p && p < limit && *p == 32)
1936 p++;
1937 while(*p && p < limit && *p != 10 && (ep - rbuffer) < 63)
1938 *(ep++) = *(p++);
1939 *(ep++) = 0;
1940 if (saddr)
1941 *saddr = prev;
1942 debugger_fault_handler = NULL;
1943 return rbuffer;
1944 }
1945 prev = next;
1946 psym = p;
1947 while(*p && p < limit && *p != 10)
1948 p++;
1949 if (*p) p++;
1950 } while(*p && p < limit && next);
1951bail:
1952 sync();
1953 } 1880 }
1954 debugger_fault_handler = NULL;
1955 return NULL;
1956} 1881}
1957 1882
1958unsigned long
1959xmon_symbol_to_addr(char* symbol)
1960{
1961 char *p, *cur;
1962 char *match = NULL;
1963 int goodness = 0;
1964 int result = 0;
1965
1966 extern char *sysmap;
1967 extern unsigned long sysmap_size;
1968 if ( !sysmap || !sysmap_size )
1969 return 0;
1970
1971 if( setjmp(bus_error_jmp) == 0 ) {
1972 debugger_fault_handler = handle_fault;
1973 sync();
1974 cur = sysmap;
1975 while(cur) {
1976 cur = strstr(cur, symbol);
1977 if (cur) {
1978 int gd = 1;
1979
1980 /* best match if equal, better match if
1981 * begins with
1982 */
1983 if (cur == sysmap || *(cur-1) == ' ') {
1984 gd++;
1985 if (cur[strlen(symbol)] == 10)
1986 gd++;
1987 }
1988 if (gd > goodness) {
1989 match = cur;
1990 goodness = gd;
1991 if (gd == 3)
1992 break;
1993 }
1994 cur++;
1995 }
1996 }
1997 if (goodness) {
1998 p = match;
1999 while(p > sysmap && *p != 10)
2000 p--;
2001 if (*p == 10) p++;
2002 result = simple_strtoul(p, &p, 16);
2003 }
2004 sync();
2005 }
2006 debugger_fault_handler = NULL;
2007 return result;
2008}