diff options
| author | Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de> | 2002-12-04 01:17:02 -0600 |
|---|---|---|
| committer | Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de> | 2002-12-04 01:17:02 -0600 |
| commit | 6802d702761dfdd910e37da40ba95fa71fd06dd7 (patch) | |
| tree | 3f211031708e5c04c4cf79e5ce28a3e306bf031b | |
| parent | a596e9e84c2ccafe145565195cee7eeae57da5b8 (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-- | Makefile | 13 | ||||
| -rw-r--r-- | kernel/kallsyms.c | 13 | ||||
| -rw-r--r-- | scripts/Makefile | 5 | ||||
| -rw-r--r-- | scripts/kallsyms | 40 | ||||
| -rw-r--r-- | scripts/kallsyms.c | 148 |
5 files changed, 163 insertions, 56 deletions
@@ -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; +} + |
