summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Germaschewski <kai@tp1.ruhr-uni-bochum.de>2002-12-04 01:17:02 -0600
committerKai Germaschewski <kai@tp1.ruhr-uni-bochum.de>2002-12-04 01:17:02 -0600
commit6802d702761dfdd910e37da40ba95fa71fd06dd7 (patch)
tree3f211031708e5c04c4cf79e5ce28a3e306bf031b
parenta596e9e84c2ccafe145565195cee7eeae57da5b8 (diff)
kbuild: Speed up kallsyms generation
This patch basically just replaces the scripts/kallsyms script by a scripts/kallsyms.c C program, which does the same thing much faster. It also removes duplicates and entries which are not between _stext and _etext, as they would not get used anyway. This saves about 290KB in vmlinux with my .config, more than 50% of the kallsyms bloat ;)
-rw-r--r--Makefile13
-rw-r--r--kernel/kallsyms.c13
-rw-r--r--scripts/Makefile5
-rw-r--r--scripts/kallsyms40
-rw-r--r--scripts/kallsyms.c148
5 files changed, 163 insertions, 56 deletions
diff --git a/Makefile b/Makefile
index 3f0090162d57..537d7589bfb2 100644
--- a/Makefile
+++ b/Makefile
@@ -352,12 +352,12 @@ ifdef CONFIG_KALLSYMS
kallsyms.o := .tmp_kallsyms2.o
quiet_cmd_kallsyms = KSYM $@
-cmd_kallsyms = sh $(KALLSYMS) $< $@
+cmd_kallsyms = $(NM) -n $< | scripts/kallsyms > $@
-.tmp_kallsyms1.o: .tmp_vmlinux1
- $(call cmd,kallsyms)
+.tmp_kallsyms1.o .tmp_kallsyms2.o: %.o: %.S scripts FORCE
+ $(call if_changed_dep,as_o_S)
-.tmp_kallsyms2.o: .tmp_vmlinux2
+.tmp_kallsyms%.S: .tmp_vmlinux%
$(call cmd,kallsyms)
.tmp_vmlinux1: $(vmlinux-objs) arch/$(ARCH)/vmlinux.lds.s FORCE
@@ -796,7 +796,7 @@ help:
@echo ''
@echo 'Execute "make" or "make all" to build all targets marked with [*] '
@echo 'For further info browse Documentation/kbuild/*'
-
+
# Documentation targets
# ---------------------------------------------------------------------------
@@ -842,6 +842,9 @@ a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(NOSTDINC_FLAGS) \
quiet_cmd_as_s_S = CPP $@
cmd_as_s_S = $(CPP) $(a_flags) -o $@ $<
+quiet_cmd_as_o_S = AS $@
+cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $<
+
# read all saved command lines
targets := $(wildcard $(sort $(targets)))
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 0335cc7fe4a1..bb880ba4e776 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -45,14 +45,11 @@ const char *kallsyms_lookup(unsigned long addr,
for (i = 0; i < best; i++)
name += strlen(name)+1;
- /* Base symbol size on next symbol, but beware aliases. */
- symbol_end = (unsigned long)_etext;
- for (i = best+1; i < kallsyms_num_syms; i++) {
- if (kallsyms_addresses[i] != kallsyms_addresses[best]){
- symbol_end = kallsyms_addresses[i];
- break;
- }
- }
+ /* Base symbol size on next symbol. */
+ if (best + 1 < kallsyms_num_syms)
+ symbol_end = kallsyms_addresses[best + 1];
+ else
+ symbol_end = (unsigned long)_etext;
*symbolsize = symbol_end - kallsyms_addresses[best];
*modname = NULL;
diff --git a/scripts/Makefile b/scripts/Makefile
index 25979b0efdb3..7301b039f96e 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -8,12 +8,11 @@
# docproc: Preprocess .tmpl file in order to generate .sgml documentation
# conmakehash: Create arrays for initializing the kernel console tables
-host-progs := fixdep split-include conmakehash docproc
+host-progs := fixdep split-include conmakehash docproc kallsyms
build-targets := $(host-progs)
# Let clean descend into subdirs
subdir- := lxdialog kconfig
# fixdep is needed to compile other host programs
-$(obj)/split-include $(obj)/docproc \
-$(obj)/conmakehash: $(obj)/fixdep
+$(obj)/split-include $(obj)/docproc $(obj)/conmakehash: $(obj)/fixdep
diff --git a/scripts/kallsyms b/scripts/kallsyms
deleted file mode 100644
index 72a51e0dbdd7..000000000000
--- a/scripts/kallsyms
+++ /dev/null
@@ -1,40 +0,0 @@
-#! /bin/sh
-# Written by Rusty Russell <rusty@rustcorp.com.au> 2002.
-
-if [ $# -ne 2 ]; then
- echo Usage: kallsyms vmlinux objfile >&2
-
- echo Adds a .kallsyms section containing symbol info.
- exit 1
-fi
-
-set -e
-
-# Clean up on exit.
-trap "rm -f kallsyms.map kallsyms.c $2" 0
-
-# Takes nm output from $1, produces a .c file on standard output.
-encode_symbols()
-{
- # First take addresses.
- echo "unsigned long kallsyms_addresses[] = {"
- sed 's/^[ ]*\([A-Fa-f0-9]*\).*/0x\1UL,/' < $1
- echo "};"
-
- # Now output size.
- echo "unsigned long kallsyms_num_syms = `wc -l < $1`;"
-
- # Now output names.
- echo "char kallsyms_names[] = ";
- sed 's/^[ ]*[A-Fa-f0-9]*[ ]*.[ ]\(.*\)/"\1\\0"/' < $1
- echo ";"
-}
-
-# FIXME: Use System.map as input, and regenerate each time in Makefile.
-$NM -n $1 | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > kallsyms.map
-
-encode_symbols kallsyms.map > kallsyms.c
-$CC $CFLAGS -c -o $2 kallsyms.c
-
-trap "rm -f kallsyms.map kallsyms.c" 0
-exit 0
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
new file mode 100644
index 000000000000..1f68d859559f
--- /dev/null
+++ b/scripts/kallsyms.c
@@ -0,0 +1,148 @@
+/* Generate assembler source containing symbol information
+ *
+ * Copyright 2002 by Kai Germaschewski
+ *
+ * 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
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct sym_entry {
+ unsigned long long addr;
+ char type;
+ char *sym;
+};
+
+
+static struct sym_entry *table;
+static int size, cnt;
+static unsigned long long _stext, _etext;
+
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: kallsyms < in.map > out.S\n");
+ exit(1);
+}
+
+static int
+read_symbol(FILE *in, struct sym_entry *s)
+{
+ char str[500];
+ int rc;
+
+ rc = fscanf(in, "%llx %c %499s\n", &s->addr, &s->type, str);
+ if (rc != 3) {
+ if (rc != EOF) {
+ /* skip line */
+ fgets(str, 500, in);
+ }
+ return -1;
+ }
+ s->sym = strdup(str);
+ return 0;
+}
+
+static int
+symbol_valid(struct sym_entry *s)
+{
+ if (s->addr < _stext)
+ return 0;
+
+ if (s->addr > _etext)
+ return 0;
+
+ if (strstr(s->sym, "_compiled."))
+ return 0;
+
+ return 1;
+}
+
+static void
+read_map(FILE *in)
+{
+ int i;
+
+ while (!feof(in)) {
+ if (cnt >= size) {
+ size += 10000;
+ table = realloc(table, sizeof(*table) * size);
+ if (!table) {
+ fprintf(stderr, "out of memory\n");
+ exit (1);
+ }
+ }
+ 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;
+ }
+}
+
+static void
+write_src(void)
+{
+ unsigned long long last_addr;
+ int i, valid = 0;
+
+ printf(".data\n");
+
+ printf(".globl kallsyms_addresses\n");
+ printf("\t.align 8\n");
+ printf("kallsyms_addresses:\n");
+ for (i = 0, last_addr = 0; i < cnt; i++) {
+ if (!symbol_valid(&table[i]))
+ continue;
+
+ if (table[i].addr == last_addr)
+ continue;
+
+ printf("\t.long\t%#llx\n", table[i].addr);
+ valid++;
+ last_addr = table[i].addr;
+ }
+ printf("\n");
+
+ printf(".globl kallsyms_num_syms\n");
+ printf("\t.align 8\n");
+ printf("\t.long\t%d\n", valid);
+ printf("\n");
+
+ printf(".globl kallsyms_names\n");
+ printf(".data\n");
+ printf("\t.align 8\n");
+ printf("kallsyms_names:\n");
+ for (i = 0, last_addr = 0; i < cnt; i++) {
+ if (!symbol_valid(&table[i]))
+ continue;
+
+ if (table[i].addr == last_addr)
+ continue;
+
+ printf("\t.string\t\"%s\"\n", table[i].sym);
+ last_addr = table[i].addr;
+ }
+ printf("\n");
+}
+
+int
+main(int argc, char **argv)
+{
+ if (argc != 1)
+ usage();
+
+ read_map(stdin);
+ write_src();
+
+ return 0;
+}
+