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 | |
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')
-rw-r--r-- | arch/ppc/boot/ld.script | 3 | ||||
-rw-r--r-- | arch/ppc/boot/openfirmware/Makefile | 5 | ||||
-rw-r--r-- | arch/ppc/boot/openfirmware/common.c | 16 | ||||
-rw-r--r-- | arch/ppc/boot/simple/Makefile | 4 | ||||
-rw-r--r-- | arch/ppc/boot/utils/addSystemMap.c | 186 | ||||
-rw-r--r-- | arch/ppc/kernel/setup.c | 7 | ||||
-rw-r--r-- | arch/ppc/mm/init.c | 16 | ||||
-rw-r--r-- | arch/ppc/xmon/xmon.c | 270 |
8 files changed, 76 insertions, 431 deletions
diff --git a/arch/ppc/boot/ld.script b/arch/ppc/boot/ld.script index 6ee602d8b6a0..9362193742ac 100644 --- a/arch/ppc/boot/ld.script +++ b/arch/ppc/boot/ld.script | |||
@@ -58,9 +58,6 @@ SECTIONS | |||
58 | *(.ramdisk) | 58 | *(.ramdisk) |
59 | __ramdisk_end = .; | 59 | __ramdisk_end = .; |
60 | . = ALIGN(4096); | 60 | . = ALIGN(4096); |
61 | __sysmap_begin = .; | ||
62 | *(.sysmap) | ||
63 | __sysmap_end = .; | ||
64 | CONSTRUCTORS | 61 | CONSTRUCTORS |
65 | } | 62 | } |
66 | _edata = .; | 63 | _edata = .; |
diff --git a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile index 4eacbd8c772a..03415238fabf 100644 --- a/arch/ppc/boot/openfirmware/Makefile +++ b/arch/ppc/boot/openfirmware/Makefile | |||
@@ -54,13 +54,10 @@ $(images)/ramdisk.image.gz: | |||
54 | @echo ' RAM disk image must be provided separately' | 54 | @echo ' RAM disk image must be provided separately' |
55 | @/bin/false | 55 | @/bin/false |
56 | 56 | ||
57 | objcpxmon-$(CONFIG_XMON) := --add-section=.sysmap=System.map \ | ||
58 | --set-section-flags=.sysmap=contents,alloc,load,readonly,data | ||
59 | quiet_cmd_genimage = GEN $@ | 57 | quiet_cmd_genimage = GEN $@ |
60 | cmd_genimage = $(OBJCOPY) -R .comment \ | 58 | cmd_genimage = $(OBJCOPY) -R .comment \ |
61 | --add-section=.image=$(images)/vmlinux.gz \ | 59 | --add-section=.image=$(images)/vmlinux.gz \ |
62 | --set-section-flags=.image=contents,alloc,load,readonly,data \ | 60 | --set-section-flags=.image=contents,alloc,load,readonly,data $< $@ |
63 | $(objcpxmon-y) $< $@ | ||
64 | 61 | ||
65 | targets += image.o | 62 | targets += image.o |
66 | $(obj)/image.o: $(obj)/dummy.o $(images)/vmlinux.gz FORCE | 63 | $(obj)/image.o: $(obj)/dummy.o $(images)/vmlinux.gz FORCE |
diff --git a/arch/ppc/boot/openfirmware/common.c b/arch/ppc/boot/openfirmware/common.c index 9e6952781f1f..0f46756a903e 100644 --- a/arch/ppc/boot/openfirmware/common.c +++ b/arch/ppc/boot/openfirmware/common.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <asm/page.h> | 15 | #include <asm/page.h> |
16 | 16 | ||
17 | /* Information from the linker */ | 17 | /* Information from the linker */ |
18 | extern char __sysmap_begin, __sysmap_end; | ||
19 | 18 | ||
20 | extern int strcmp(const char *s1, const char *s2); | 19 | extern int strcmp(const char *s1, const char *s2); |
21 | extern char *avail_ram, *avail_high; | 20 | extern char *avail_ram, *avail_high; |
@@ -116,14 +115,8 @@ void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) | |||
116 | void make_bi_recs(unsigned long addr, char *name, unsigned int mach, | 115 | void make_bi_recs(unsigned long addr, char *name, unsigned int mach, |
117 | unsigned long progend) | 116 | unsigned long progend) |
118 | { | 117 | { |
119 | unsigned long sysmap_size; | ||
120 | struct bi_record *rec; | 118 | struct bi_record *rec; |
121 | 119 | ||
122 | /* Figure out the size of a possible System.map we're going to | ||
123 | * pass along. | ||
124 | * */ | ||
125 | sysmap_size = (unsigned long)(&__sysmap_end) - | ||
126 | (unsigned long)(&__sysmap_begin); | ||
127 | 120 | ||
128 | /* leave a 1MB gap then align to the next 1MB boundary */ | 121 | /* leave a 1MB gap then align to the next 1MB boundary */ |
129 | addr = _ALIGN(addr+ (1<<20) - 1, (1<<20)); | 122 | addr = _ALIGN(addr+ (1<<20) - 1, (1<<20)); |
@@ -147,15 +140,6 @@ void make_bi_recs(unsigned long addr, char *name, unsigned int mach, | |||
147 | rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long); | 140 | rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long); |
148 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | 141 | rec = (struct bi_record *)((unsigned long)rec + rec->size); |
149 | 142 | ||
150 | if (sysmap_size) { | ||
151 | rec->tag = BI_SYSMAP; | ||
152 | rec->data[0] = (unsigned long)(&__sysmap_begin); | ||
153 | rec->data[1] = sysmap_size; | ||
154 | rec->size = sizeof(struct bi_record) + 2 * | ||
155 | sizeof(unsigned long); | ||
156 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | ||
157 | } | ||
158 | |||
159 | rec->tag = BI_LAST; | 143 | rec->tag = BI_LAST; |
160 | rec->size = sizeof(struct bi_record); | 144 | rec->size = sizeof(struct bi_record); |
161 | rec = (struct bi_record *)((unsigned long)rec + rec->size); | 145 | rec = (struct bi_record *)((unsigned long)rec + rec->size); |
diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile index c28061ad5982..991b4cbb83c8 100644 --- a/arch/ppc/boot/simple/Makefile +++ b/arch/ppc/boot/simple/Makefile | |||
@@ -203,7 +203,7 @@ $(obj)/zvmlinux: $(OBJS) $(LIBS) $(srctree)/$(boot)/ld.script \ | |||
203 | $(obj)/dummy.o $(obj)/image.o | 203 | $(obj)/dummy.o $(obj)/image.o |
204 | $(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/image.o $(LIBS) | 204 | $(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/image.o $(LIBS) |
205 | $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab \ | 205 | $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab \ |
206 | -R .stabstr -R .ramdisk -R .sysmap | 206 | -R .stabstr -R .ramdisk |
207 | 207 | ||
208 | $(obj)/zvmlinux.initrd: $(OBJS) $(LIBS) $(srctree)/$(boot)/ld.script \ | 208 | $(obj)/zvmlinux.initrd: $(OBJS) $(LIBS) $(srctree)/$(boot)/ld.script \ |
209 | $(images)/vmlinux.gz $(obj)/dummy.o | 209 | $(images)/vmlinux.gz $(obj)/dummy.o |
@@ -215,7 +215,7 @@ $(obj)/zvmlinux.initrd: $(OBJS) $(LIBS) $(srctree)/$(boot)/ld.script \ | |||
215 | $(obj)/dummy.o $(obj)/image.o | 215 | $(obj)/dummy.o $(obj)/image.o |
216 | $(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/image.o $(LIBS) | 216 | $(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/image.o $(LIBS) |
217 | $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab \ | 217 | $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab \ |
218 | -R .stabstr -R .sysmap | 218 | -R .stabstr |
219 | 219 | ||
220 | # Sort-of dummy rules, that let us format the image we want. | 220 | # Sort-of dummy rules, that let us format the image we want. |
221 | zImage: $(images)/$(zimage-y) $(obj)/zvmlinux | 221 | zImage: $(images)/$(zimage-y) $(obj)/zvmlinux |
diff --git a/arch/ppc/boot/utils/addSystemMap.c b/arch/ppc/boot/utils/addSystemMap.c deleted file mode 100644 index 4654f891b274..000000000000 --- a/arch/ppc/boot/utils/addSystemMap.c +++ /dev/null | |||
@@ -1,186 +0,0 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <byteswap.h> | ||
4 | #include <sys/types.h> | ||
5 | #include <sys/stat.h> | ||
6 | |||
7 | void xlate( char * inb, char * trb, unsigned len ) | ||
8 | { | ||
9 | unsigned i; | ||
10 | for ( i=0; i<len; ++i ) { | ||
11 | char c = *inb++; | ||
12 | char c1 = c >> 4; | ||
13 | char c2 = c & 0xf; | ||
14 | if ( c1 > 9 ) | ||
15 | c1 = c1 + 'A' - 10; | ||
16 | else | ||
17 | c1 = c1 + '0'; | ||
18 | if ( c2 > 9 ) | ||
19 | c2 = c2 + 'A' - 10; | ||
20 | else | ||
21 | c2 = c2 + '0'; | ||
22 | *trb++ = c1; | ||
23 | *trb++ = c2; | ||
24 | } | ||
25 | *trb = 0; | ||
26 | } | ||
27 | |||
28 | #define ElfHeaderSize (64 * 1024) | ||
29 | #define ElfPages (ElfHeaderSize / 4096) | ||
30 | #define KERNELBASE (0xc0000000) | ||
31 | |||
32 | void get4k( /*istream *inf*/FILE *file, char *buf ) | ||
33 | { | ||
34 | unsigned j; | ||
35 | unsigned num = fread(buf, 1, 4096, file); | ||
36 | for ( j=num; j<4096; ++j ) | ||
37 | buf[j] = 0; | ||
38 | } | ||
39 | |||
40 | void put4k( /*ostream *outf*/FILE *file, char *buf ) | ||
41 | { | ||
42 | fwrite(buf, 1, 4096, file); | ||
43 | } | ||
44 | |||
45 | int main(int argc, char **argv) | ||
46 | { | ||
47 | char inbuf[4096]; | ||
48 | FILE *ramDisk = NULL; | ||
49 | FILE *inputVmlinux = NULL; | ||
50 | FILE *outputVmlinux = NULL; | ||
51 | unsigned i = 0; | ||
52 | unsigned long ramFileLen = 0; | ||
53 | unsigned long ramLen = 0; | ||
54 | unsigned long roundR = 0; | ||
55 | unsigned long kernelLen = 0; | ||
56 | unsigned long actualKernelLen = 0; | ||
57 | unsigned long round = 0; | ||
58 | unsigned long roundedKernelLen = 0; | ||
59 | unsigned long ramStartOffs = 0; | ||
60 | unsigned long ramPages = 0; | ||
61 | unsigned long roundedKernelPages = 0; | ||
62 | if ( argc < 2 ) { | ||
63 | printf("Name of System Map file missing.\n"); | ||
64 | exit(1); | ||
65 | } | ||
66 | |||
67 | if ( argc < 3 ) { | ||
68 | printf("Name of vmlinux file missing.\n"); | ||
69 | exit(1); | ||
70 | } | ||
71 | |||
72 | if ( argc < 4 ) { | ||
73 | printf("Name of vmlinux output file missing.\n"); | ||
74 | exit(1); | ||
75 | } | ||
76 | |||
77 | ramDisk = fopen(argv[1], "r"); | ||
78 | if ( ! ramDisk ) { | ||
79 | printf("System Map file \"%s\" failed to open.\n", argv[1]); | ||
80 | exit(1); | ||
81 | } | ||
82 | inputVmlinux = fopen(argv[2], "r"); | ||
83 | if ( ! inputVmlinux ) { | ||
84 | printf("vmlinux file \"%s\" failed to open.\n", argv[2]); | ||
85 | exit(1); | ||
86 | } | ||
87 | outputVmlinux = fopen(argv[3], "w"); | ||
88 | if ( ! outputVmlinux ) { | ||
89 | printf("output vmlinux file \"%s\" failed to open.\n", argv[3]); | ||
90 | exit(1); | ||
91 | } | ||
92 | fseek(ramDisk, 0, SEEK_END); | ||
93 | ramFileLen = ftell(ramDisk); | ||
94 | fseek(ramDisk, 0, SEEK_SET); | ||
95 | printf("%s file size = %ld\n", argv[1], ramFileLen); | ||
96 | |||
97 | ramLen = ramFileLen; | ||
98 | |||
99 | roundR = 4096 - (ramLen % 4096); | ||
100 | if ( roundR ) { | ||
101 | printf("Rounding System Map file up to a multiple of 4096, adding %ld\n", roundR); | ||
102 | ramLen += roundR; | ||
103 | } | ||
104 | |||
105 | printf("Rounded System Map size is %ld\n", ramLen); | ||
106 | fseek(inputVmlinux, 0, SEEK_END); | ||
107 | kernelLen = ftell(inputVmlinux); | ||
108 | fseek(inputVmlinux, 0, SEEK_SET); | ||
109 | printf("kernel file size = %ld\n", kernelLen); | ||
110 | if ( kernelLen == 0 ) { | ||
111 | printf("You must have a linux kernel specified as argv[2]\n"); | ||
112 | exit(1); | ||
113 | } | ||
114 | |||
115 | actualKernelLen = kernelLen - ElfHeaderSize; | ||
116 | |||
117 | printf("actual kernel length (minus ELF header) = %ld\n", actualKernelLen); | ||
118 | |||
119 | round = actualKernelLen % 4096; | ||
120 | roundedKernelLen = actualKernelLen; | ||
121 | if ( round ) | ||
122 | roundedKernelLen += (4096 - round); | ||
123 | |||
124 | printf("actual kernel length rounded up to a 4k multiple = %ld\n", roundedKernelLen); | ||
125 | |||
126 | ramStartOffs = roundedKernelLen; | ||
127 | ramPages = ramLen / 4096; | ||
128 | |||
129 | printf("System map pages to copy = %ld\n", ramPages); | ||
130 | |||
131 | // Copy 64K ELF header | ||
132 | for (i=0; i<(ElfPages); ++i) { | ||
133 | get4k( inputVmlinux, inbuf ); | ||
134 | put4k( outputVmlinux, inbuf ); | ||
135 | } | ||
136 | |||
137 | |||
138 | |||
139 | roundedKernelPages = roundedKernelLen / 4096; | ||
140 | |||
141 | fseek(inputVmlinux, ElfHeaderSize, SEEK_SET); | ||
142 | |||
143 | { | ||
144 | for ( i=0; i<roundedKernelPages; ++i ) { | ||
145 | get4k( inputVmlinux, inbuf ); | ||
146 | if ( i == 0 ) { | ||
147 | unsigned long * p; | ||
148 | printf("Storing embedded_sysmap_start at 0x3c\n"); | ||
149 | p = (unsigned long *)(inbuf + 0x3c); | ||
150 | |||
151 | #if (BYTE_ORDER == __BIG_ENDIAN) | ||
152 | *p = ramStartOffs; | ||
153 | #else | ||
154 | *p = bswap_32(ramStartOffs); | ||
155 | #endif | ||
156 | |||
157 | printf("Storing embedded_sysmap_end at 0x44\n"); | ||
158 | p = (unsigned long *)(inbuf + 0x44); | ||
159 | #if (BYTE_ORDER == __BIG_ENDIAN) | ||
160 | *p = ramStartOffs + ramFileLen; | ||
161 | #else | ||
162 | *p = bswap_32(ramStartOffs + ramFileLen); | ||
163 | #endif | ||
164 | } | ||
165 | put4k( outputVmlinux, inbuf ); | ||
166 | } | ||
167 | } | ||
168 | |||
169 | { | ||
170 | for ( i=0; i<ramPages; ++i ) { | ||
171 | get4k( ramDisk, inbuf ); | ||
172 | put4k( outputVmlinux, inbuf ); | ||
173 | } | ||
174 | } | ||
175 | |||
176 | |||
177 | fclose(ramDisk); | ||
178 | fclose(inputVmlinux); | ||
179 | fclose(outputVmlinux); | ||
180 | /* Set permission to executable */ | ||
181 | chmod(argv[3], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); | ||
182 | |||
183 | return 0; | ||
184 | |||
185 | } | ||
186 | |||
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index c344c66e68f7..c42f75326939 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c | |||
@@ -61,8 +61,6 @@ extern void power4_idle(void); | |||
61 | 61 | ||
62 | extern boot_infos_t *boot_infos; | 62 | extern boot_infos_t *boot_infos; |
63 | struct ide_machdep_calls ppc_ide_md; | 63 | struct ide_machdep_calls ppc_ide_md; |
64 | char *sysmap; | ||
65 | unsigned long sysmap_size; | ||
66 | 64 | ||
67 | /* Used with the BI_MEMSIZE bootinfo parameter to store the memory | 65 | /* Used with the BI_MEMSIZE bootinfo parameter to store the memory |
68 | size value reported by the boot loader. */ | 66 | size value reported by the boot loader. */ |
@@ -578,11 +576,6 @@ void parse_bootinfo(struct bi_record *rec) | |||
578 | case BI_CMD_LINE: | 576 | case BI_CMD_LINE: |
579 | strlcpy(cmd_line, (void *)data, sizeof(cmd_line)); | 577 | strlcpy(cmd_line, (void *)data, sizeof(cmd_line)); |
580 | break; | 578 | break; |
581 | case BI_SYSMAP: | ||
582 | sysmap = (char *)((data[0] >= (KERNELBASE)) ? data[0] : | ||
583 | (data[0]+KERNELBASE)); | ||
584 | sysmap_size = data[1]; | ||
585 | break; | ||
586 | #ifdef CONFIG_BLK_DEV_INITRD | 579 | #ifdef CONFIG_BLK_DEV_INITRD |
587 | case BI_INITRD: | 580 | case BI_INITRD: |
588 | initrd_start = data[0] + KERNELBASE; | 581 | initrd_start = data[0] + KERNELBASE; |
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index c8529d004cfa..334ef4150d92 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c | |||
@@ -96,9 +96,6 @@ extern struct task_struct *current_set[NR_CPUS]; | |||
96 | char *klimit = _end; | 96 | char *klimit = _end; |
97 | struct mem_pieces phys_avail; | 97 | struct mem_pieces phys_avail; |
98 | 98 | ||
99 | extern char *sysmap; | ||
100 | extern unsigned long sysmap_size; | ||
101 | |||
102 | /* | 99 | /* |
103 | * this tells the system to map all of ram with the segregs | 100 | * this tells the system to map all of ram with the segregs |
104 | * (i.e. page tables) instead of the bats. | 101 | * (i.e. page tables) instead of the bats. |
@@ -442,12 +439,6 @@ void __init mem_init(void) | |||
442 | if (agp_special_page) | 439 | if (agp_special_page) |
443 | SetPageReserved(virt_to_page(agp_special_page)); | 440 | SetPageReserved(virt_to_page(agp_special_page)); |
444 | #endif | 441 | #endif |
445 | if ( sysmap ) | ||
446 | for (addr = (unsigned long)sysmap; | ||
447 | addr < PAGE_ALIGN((unsigned long)sysmap+sysmap_size) ; | ||
448 | addr += PAGE_SIZE) | ||
449 | SetPageReserved(virt_to_page(addr)); | ||
450 | |||
451 | for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory; | 442 | for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory; |
452 | addr += PAGE_SIZE) { | 443 | addr += PAGE_SIZE) { |
453 | if (!PageReserved(virt_to_page(addr))) | 444 | if (!PageReserved(virt_to_page(addr))) |
@@ -482,9 +473,7 @@ void __init mem_init(void) | |||
482 | codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10), | 473 | codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10), |
483 | initpages<< (PAGE_SHIFT-10), | 474 | initpages<< (PAGE_SHIFT-10), |
484 | (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); | 475 | (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); |
485 | if (sysmap) | 476 | |
486 | printk("System.map loaded at 0x%08x for debugger, size: %ld bytes\n", | ||
487 | (unsigned int)sysmap, sysmap_size); | ||
488 | #ifdef CONFIG_PPC_PMAC | 477 | #ifdef CONFIG_PPC_PMAC |
489 | if (agp_special_page) | 478 | if (agp_special_page) |
490 | printk(KERN_INFO "AGP special page: 0x%08lx\n", agp_special_page); | 479 | printk(KERN_INFO "AGP special page: 0x%08lx\n", agp_special_page); |
@@ -534,9 +523,6 @@ set_phys_avail(unsigned long total_memory) | |||
534 | if (rtas_data) | 523 | if (rtas_data) |
535 | mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1); | 524 | mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1); |
536 | #endif | 525 | #endif |
537 | /* remove the sysmap pages from the available memory */ | ||
538 | if (sysmap) | ||
539 | mem_pieces_remove(&phys_avail, __pa(sysmap), sysmap_size, 1); | ||
540 | #ifdef CONFIG_PPC_PMAC | 526 | #ifdef CONFIG_PPC_PMAC |
541 | /* Because of some uninorth weirdness, we need a page of | 527 | /* Because of some uninorth weirdness, we need a page of |
542 | * memory as high as possible (it must be outside of the | 528 | * memory as high as possible (it must be outside of the |
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 | } | ||