diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2005-06-21 20:15:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-21 21:46:26 -0400 |
commit | 6879dc137ea4efad65cab8bf8a7c0b742bcf92cc (patch) | |
tree | 13ca02150a892e97f3da20ac9cc052508cc7e8a8 /arch/ppc/xmon | |
parent | a70d439345875d476ede258094356e2acd09b1a1 (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.c | 270 |
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 *); | |||
93 | static unsigned read_spr(int); | 94 | static unsigned read_spr(int); |
94 | static void write_spr(int, unsigned); | 95 | static void write_spr(int, unsigned); |
95 | static void super_regs(void); | 96 | static void super_regs(void); |
96 | static void print_sysmap(void); | 97 | static void symbol_lookup(void); |
97 | static void sysmap_lookup(void); | ||
98 | static void remove_bpts(void); | 98 | static void remove_bpts(void); |
99 | static void insert_bpts(void); | 99 | static void insert_bpts(void); |
100 | static struct bpt *at_breakpoint(unsigned pc); | 100 | static struct bpt *at_breakpoint(unsigned pc); |
@@ -103,7 +103,6 @@ static void cacheflush(void); | |||
103 | #ifdef CONFIG_SMP | 103 | #ifdef CONFIG_SMP |
104 | static void cpu_cmd(void); | 104 | static void cpu_cmd(void); |
105 | #endif /* CONFIG_SMP */ | 105 | #endif /* CONFIG_SMP */ |
106 | static int pretty_print_addr(unsigned long addr); | ||
107 | static void csum(void); | 106 | static void csum(void); |
108 | #ifdef CONFIG_BOOTX_TEXT | 107 | #ifdef CONFIG_BOOTX_TEXT |
109 | static void vidcmds(void); | 108 | static void vidcmds(void); |
@@ -120,8 +119,6 @@ extern void longjmp(u_int *, int); | |||
120 | 119 | ||
121 | extern void xmon_enter(void); | 120 | extern void xmon_enter(void); |
122 | extern void xmon_leave(void); | 121 | extern void xmon_leave(void); |
123 | extern char* xmon_find_symbol(unsigned long addr, unsigned long* saddr); | ||
124 | extern unsigned long xmon_symbol_to_addr(char* symbol); | ||
125 | 122 | ||
126 | static unsigned start_tb[NR_CPUS][2]; | 123 | static unsigned start_tb[NR_CPUS][2]; |
127 | static unsigned stop_tb[NR_CPUS][2]; | 124 | static 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) */ | ||
175 | static 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 | |||
178 | static void get_tb(unsigned *p) | 203 | static 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, ®s, sizeof(regs)) != sizeof(regs)) | 855 | if (mread(sp+16, ®s, 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; | |||
951 | extern char dec_exc; | 971 | extern char dec_exc; |
952 | 972 | ||
953 | void | 973 | void |
954 | print_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 | |||
971 | void | ||
972 | super_regs(void) | 974 | super_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 | ||
1843 | void | 1852 | static void |
1844 | sysmap_lookup(void) | 1853 | symbol_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 | ||
1895 | static int | 1859 | switch (type) { |
1896 | pretty_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) | |
1908 | char* | 1872 | printf("%s: %lx\n", tmp, addr); |
1909 | xmon_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); | ||
1951 | bail: | ||
1952 | sync(); | ||
1953 | } | 1880 | } |
1954 | debugger_fault_handler = NULL; | ||
1955 | return NULL; | ||
1956 | } | 1881 | } |
1957 | 1882 | ||
1958 | unsigned long | ||
1959 | xmon_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 | } | ||