
From: Rusty Russell <rusty@rustcorp.com.au>

kallsyms contains only function names, but some debuggers (eg.  xmon on
PPC/PPC64) use it to lookup symbols: it'd be much nicer if it included data
symbols too.


---

 25-akpm/Makefile           |    2 +-
 25-akpm/init/Kconfig       |   11 +++++++++++
 25-akpm/kernel/kallsyms.c  |    5 ++++-
 25-akpm/scripts/kallsyms.c |   43 +++++++++++++++++++++++++------------------
 4 files changed, 41 insertions(+), 20 deletions(-)

diff -puN init/Kconfig~debugging-option-to-put-data-symbols-in-kallsyms init/Kconfig
--- 25/init/Kconfig~debugging-option-to-put-data-symbols-in-kallsyms	Tue May 18 16:47:49 2004
+++ 25-akpm/init/Kconfig	Tue May 18 16:47:49 2004
@@ -235,6 +235,17 @@ config KALLSYMS
 	   symbolic stack backtraces. This increases the size of the kernel
 	   somewhat, as all symbols have to be loaded into the kernel image.
 
+config KALLSYMS_ALL
+	bool "Include all symbols in kallsyms"
+	depends on DEBUG_KERNEL && KALLSYMS
+	help
+	   Normally kallsyms only contains the symbols of functions, for nicer
+	   OOPS messages.  Some debuggers can use kallsyms for other
+	   symbols too: say Y here to include all symbols, and you
+	   don't care about adding 300k to the size of your kernel.
+
+	   Say N.
+
 config FUTEX
 	bool "Enable futex support" if EMBEDDED
 	default y
diff -puN kernel/kallsyms.c~debugging-option-to-put-data-symbols-in-kallsyms kernel/kallsyms.c
--- 25/kernel/kallsyms.c~debugging-option-to-put-data-symbols-in-kallsyms	Tue May 18 16:47:49 2004
+++ 25-akpm/kernel/kallsyms.c	Tue May 18 16:47:49 2004
@@ -190,7 +190,10 @@ static unsigned long get_ksymbol_core(st
 	off += strlen(kallsyms_names + off) + 1;
 	iter->owner = NULL;
 	iter->value = kallsyms_addresses[iter->pos];
-	iter->type = 't';
+	if (is_kernel_text(iter->value) || is_kernel_inittext(iter->value))
+		iter->type = 't';
+	else
+		iter->type = 'd';
 
 	upcase_if_global(iter);
 	return off - iter->nameoff;
diff -puN Makefile~debugging-option-to-put-data-symbols-in-kallsyms Makefile
--- 25/Makefile~debugging-option-to-put-data-symbols-in-kallsyms	Tue May 18 16:47:49 2004
+++ 25-akpm/Makefile	Tue May 18 16:47:49 2004
@@ -568,7 +568,7 @@ ifdef CONFIG_KALLSYMS
 kallsyms.o := .tmp_kallsyms2.o
 
 quiet_cmd_kallsyms = KSYM    $@
-cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) > $@
+cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) $(foreach x,$(CONFIG_KALLSYMS_ALL),--all-symbols) > $@
 
 .tmp_kallsyms1.o .tmp_kallsyms2.o: %.o: %.S scripts FORCE
 	$(call if_changed_dep,as_o_S)
diff -puN scripts/kallsyms.c~debugging-option-to-put-data-symbols-in-kallsyms scripts/kallsyms.c
--- 25/scripts/kallsyms.c~debugging-option-to-put-data-symbols-in-kallsyms	Tue May 18 16:47:49 2004
+++ 25-akpm/scripts/kallsyms.c	Tue May 18 16:47:49 2004
@@ -5,12 +5,13 @@
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
- * Usage: nm -n vmlinux | scripts/kallsyms > symbols.S
+ * Usage: nm -n vmlinux | scripts/kallsyms [--all-symbols] > symbols.S
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 
 struct sym_entry {
 	unsigned long long addr;
@@ -22,11 +23,12 @@ struct sym_entry {
 static struct sym_entry *table;
 static int size, cnt;
 static unsigned long long _stext, _etext, _sinittext, _einittext;
+static int all_symbols = 0;
 
 static void
 usage(void)
 {
-	fprintf(stderr, "Usage: kallsyms < in.map > out.S\n");
+	fprintf(stderr, "Usage: kallsyms [--all-symbols] < in.map > out.S\n");
 	exit(1);
 }
 
@@ -44,6 +46,19 @@ read_symbol(FILE *in, struct sym_entry *
 		}
 		return -1;
 	}
+
+	/* Ignore most absolute/undefined (?) symbols. */
+	if (strcmp(str, "_stext") == 0)
+		_stext = s->addr;
+	else if (strcmp(str, "_etext") == 0)
+		_etext = s->addr;
+	else if (strcmp(str, "_sinittext") == 0)
+		_sinittext = s->addr;
+	else if (strcmp(str, "_einittext") == 0)
+		_einittext = s->addr;
+	else if (toupper(s->type) == 'A' || toupper(s->type) == 'U')
+		return -1;
+
 	s->sym = strdup(str);
 	return 0;
 }
@@ -51,9 +66,11 @@ read_symbol(FILE *in, struct sym_entry *
 static int
 symbol_valid(struct sym_entry *s)
 {
-	if ((s->addr < _stext || s->addr > _etext)
-	    && (s->addr < _sinittext || s->addr > _einittext))
-		return 0;
+	if (!all_symbols) {
+		if ((s->addr < _stext || s->addr > _etext)
+		    && (s->addr < _sinittext || s->addr > _einittext))
+			return 0;
+	}
 
 	if (strstr(s->sym, "_compiled."))
 		return 0;
@@ -64,8 +81,6 @@ symbol_valid(struct sym_entry *s)
 static void
 read_map(FILE *in)
 {
-	int i;
-
 	while (!feof(in)) {
 		if (cnt >= size) {
 			size += 10000;
@@ -78,16 +93,6 @@ read_map(FILE *in)
 		if (read_symbol(in, &table[cnt]) == 0)
 			cnt++;
 	}
-	for (i = 0; i < cnt; i++) {
-		if (strcmp(table[i].sym, "_stext") == 0)
-			_stext = table[i].addr;
-		if (strcmp(table[i].sym, "_etext") == 0)
-			_etext = table[i].addr;
-		if (strcmp(table[i].sym, "_sinittext") == 0)
-			_sinittext = table[i].addr;
-		if (strcmp(table[i].sym, "_einittext") == 0)
-			_einittext = table[i].addr;
-	}
 }
 
 static void
@@ -147,7 +152,9 @@ write_src(void)
 int
 main(int argc, char **argv)
 {
-	if (argc != 1)
+	if (argc == 2 && strcmp(argv[1], "--all-symbols") == 0)
+		all_symbols = 1;
+	else if (argc != 1)
 		usage();
 
 	read_map(stdin);

_
