From: Felix Fietkau Subject: kernel: add a config option for keeping the kallsyms table uncompressed, saving ~9kb kernel size after lzma on ar71xx [john@phrozen.org: added to my upstream queue 30.12.2016] lede-commit: e0e3509b5ce2ccf93d4d67ea907613f5f7ec2eed Signed-off-by: Felix Fietkau --- init/Kconfig | 11 +++++++++++ kernel/kallsyms.c | 8 ++++++++ kernel/vmcore_info.c | 2 ++ scripts/kallsyms.c | 12 ++++++++++++ scripts/link-vmlinux.sh | 4 ++++ 5 files changed, 37 insertions(+) --- a/init/Kconfig +++ b/init/Kconfig @@ -1533,6 +1533,17 @@ config SYSCTL_ARCH_UNALIGN_ALLOW the unaligned access emulation. see arch/parisc/kernel/unaligned.c for reference +config KALLSYMS_UNCOMPRESSED + bool "Keep kallsyms uncompressed" + depends on KALLSYMS + help + Normally kallsyms contains compressed symbols (using a token table), + reducing the uncompressed kernel image size. Keeping the symbol table + uncompressed significantly improves the size of this part in compressed + kernel images. + + Say N unless you need compressed kernel images to be small. + config HAVE_PCSPKR_PLATFORM bool --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -69,6 +69,11 @@ static unsigned int kallsyms_expand_symb * For every byte on the compressed symbol data, copy the table * entry for that byte. */ +#ifdef CONFIG_KALLSYMS_UNCOMPRESSED + memcpy(result, data + 1, len - 1); + result += len - 1; + len = 0; +#endif while (len) { tptr = &kallsyms_token_table[kallsyms_token_index[*data]]; data++; @@ -101,6 +106,9 @@ tail: */ static char kallsyms_get_symbol_type(unsigned int off) { +#ifdef CONFIG_KALLSYMS_UNCOMPRESSED + return kallsyms_names[off + 1]; +#endif /* * Get just the first code, look it up in the token table, * and return the first char from this token. --- a/kernel/vmcore_info.c +++ b/kernel/vmcore_info.c @@ -214,8 +214,10 @@ static int __init crash_save_vmcoreinfo_ #ifdef CONFIG_KALLSYMS VMCOREINFO_SYMBOL(kallsyms_names); VMCOREINFO_SYMBOL(kallsyms_num_syms); +#ifndef CONFIG_KALLSYMS_UNCOMPRESSED VMCOREINFO_SYMBOL(kallsyms_token_table); VMCOREINFO_SYMBOL(kallsyms_token_index); +#endif VMCOREINFO_SYMBOL(kallsyms_offsets); VMCOREINFO_SYMBOL(kallsyms_relative_base); #endif /* CONFIG_KALLSYMS */ --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -62,6 +62,7 @@ static struct addr_range percpu_range = static struct sym_entry **table; static unsigned int table_size, table_cnt; static int all_symbols; +static int uncompressed; static int absolute_percpu; static int token_profit[0x10000]; @@ -412,13 +413,17 @@ static void write_src(void) for (k = 0; k < table[i]->len; k++) printf(", 0x%02x", table[i]->sym[k]); - /* - * Now that we wrote out the compressed symbol name, restore the - * original name and print it in the comment. - */ - expand_symbol(table[i]->sym, table[i]->len, buf); - strcpy((char *)table[i]->sym, buf); - printf("\t/* %s */\n", table[i]->sym); + if (!uncompressed) { + /* + * Now that we wrote out the compressed symbol name, restore the + * original name and print it in the comment. + */ + expand_symbol(table[i]->sym, table[i]->len, buf); + strcpy((char *)table[i]->sym, buf); + printf("\t/* %s */\n", table[i]->sym); + } else { + printf("\n"); + } } printf("\n"); @@ -429,20 +434,22 @@ static void write_src(void) free(markers); - output_label("kallsyms_token_table"); - off = 0; - for (i = 0; i < 256; i++) { - best_idx[i] = off; - expand_symbol(best_table[i], best_table_len[i], buf); - printf("\t.asciz\t\"%s\"\n", buf); - off += strlen(buf) + 1; + if (!uncompressed) { + output_label("kallsyms_token_table"); + off = 0; + for (i = 0; i < 256; i++) { + best_idx[i] = off; + expand_symbol(best_table[i], best_table_len[i], buf); + printf("\t.asciz\t\"%s\"\n", buf); + off += strlen(buf) + 1; + } + printf("\n"); + + output_label("kallsyms_token_index"); + for (i = 0; i < 256; i++) + printf("\t.short\t%d\n", best_idx[i]); + printf("\n"); } - printf("\n"); - - output_label("kallsyms_token_index"); - for (i = 0; i < 256; i++) - printf("\t.short\t%d\n", best_idx[i]); - printf("\n"); output_label("kallsyms_offsets"); @@ -532,6 +539,9 @@ static unsigned char *find_token(unsigne { int i; + if (uncompressed) + return NULL; + for (i = 0; i < len - 1; i++) { if (str[i] == token[0] && str[i+1] == token[1]) return &str[i]; @@ -604,6 +614,9 @@ static void optimize_result(void) { int i, best; + if (uncompressed) + return; + /* using the '\0' symbol last allows compress_symbols to use standard * fast string functions */ for (i = 255; i >= 0; i--) { @@ -763,6 +776,7 @@ int main(int argc, char **argv) static const struct option long_options[] = { {"all-symbols", no_argument, &all_symbols, 1}, {"absolute-percpu", no_argument, &absolute_percpu, 1}, + {"uncompressed", no_argument, &uncompressed, 1}, {}, }; --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -144,6 +144,10 @@ kallsyms() kallsymopt="${kallsymopt} --absolute-percpu" fi + if is_enabled CONFIG_KALLSYMS_UNCOMPRESSED; then + kallsymopt="${kallsymopt} --uncompressed" + fi + info KSYMS "${2}.S" scripts/kallsyms ${kallsymopt} "${1}" > "${2}.S"