Put all functions in kallsyms
Subsystems (6)
PATCH 1/1 Put all functions in kallsyms
Hi all,
Simple, untested patch. Any objections?
Cheers,
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
Name: Include All Functions in kallsyms
Author: Rusty Russell
Status: Experimental
D: Do not discard functions outside _stext and _etext, but include all
D: 't' or 'T' functions. This means __init functions are included (in my
D: config this means an increas from 5691 to 6442 functions. D:
D: TODO: Allow multiple kallsym tables, discard init one after init.
D: TODO: Use huffman name compression and 16-bit offsets (see IDE
D: oopser patch)
scripts/kallsyms.c renamed from scripts/kallsyms.c.~1~ +8 -16
@@ -14,14 +14,12 @@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 )
@@ -35,8 +33,9 @@ {char str[500 ];int rc; +char type; - rc =fscanf (in,"%llx %c %499s\n" , &s->addr, &s->type, str); + rc =fscanf (in,"%llx %c %499s\n" , &s->addr, &type, str);if (rc !=3 ) {if (rc !=EOF ) {/* skip line */
@@ -44,19 +43,18 @@ }return -1 ; } + +/* Only interested in functions. */ +if (type !='t' && type !='T' ) +return -1 ; + s->sym =strdup (str);return 0 ; } -static int +static inline 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 ;
@@ -80,12 +78,6 @@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
Quoted 4 lines · Rusty Russell
Hi all,
Simple, untested patch. Any objections?
Seems OK to me. The only people who are likely to have large numbers of __init symbols are those who compile their own kernels. They know how to strip stuff down and they know to turn kallsyms off altogether if they have a space problem.
And initcalls are a popular place to go oops.
Quoted 1 line · Rusty Russell
Simple, untested patch. Any objections?
No objection, but you need to adapt the test inkernel/kallsyms.c:
if (addr >= (unsigned long)_stext && addr <= (unsigned long)_etext) {and in kernel/extable.c:
if (addr >= (unsigned long)_stext && addr <= (unsigned long)_etext)
Otherwise, you'd just add bloat with no gain at all ;)
--Kai
In message <[email protected]> y ou write:
Quoted 7 lines · Rusty Russell
Quoted 2 lines
Simple, untested patch. Any objections?
No objection, but you need to adapt the test in
kernel/kallsyms.c:
Quoted 8 lines
if (addr >= (unsigned long)_stext && addr <= (unsigned long)_etext) {and in
kernel/extable.c:if (addr >= (unsigned long)_stext && addr <= (unsigned long)_etext)Otherwise, you'd just add bloat with no gain at all ;)
Ick. Yes, the extable.c one is the killer. OK, let's do it the other way.
How's this? (Actually tested this time).
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
Name: Include All Functions in kallsyms
Author: Rusty Russell
Status: Tested on 2.5.66-bk6
D: Introduce _sinittext and _einittext (cf. _stext and _etext), so kallsyms
D: includes __init functions.
D:
D: TODO: Use huffman name compression and 16-bit offsets (see IDE
D: oopser patch)
arch/alpha/vmlinux.lds.S +5 -1
@@ -32,7 +32,11 @@ SECTIONS /* Will be freed after init */ . = ALIGN(8192); /* Init code and data */ __init_begin = .; - .init.text : { *(.init.text) } + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } .init.data : { *(.init.data) } . = ALIGN(16);
arch/arm/vmlinux-armo.lds.in +2 -0
@@ -14,7 +14,9 @@ SECTIONS .init : { /* Init code and data */ _stext = .; __init_begin = .; + _sinittext = .; *(.init.text) + _einittext = .; __proc_info_begin = .; *(.proc.info) __proc_info_end = .;
arch/arm/vmlinux-armv.lds.in +2 -0
@@ -18,7 +18,9 @@ SECTIONS .init : { /* Init code and data */ _stext = .; __init_begin = .; + _sinittext = .; *(.init.text) + _einittext = .; __proc_info_begin = .; *(.proc.info) __proc_info_end = .;
arch/i386/vmlinux.lds.S +5 -1
@@ -54,7 +54,11 @@ SECTIONS /* will be freed after init */ . = ALIGN(4096); /* Init code and data */ __init_begin = .; - .init.text : { *(.init.text) } + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } .init.data : { *(.init.data) } . = ALIGN(16); __setup_start = .;
arch/ia64/vmlinux.lds.S +5 -1
@@ -96,7 +96,11 @@ SECTIONS . = ALIGN(PAGE_SIZE); __init_begin = .; .init.text : AT(ADDR(.init.text) - PAGE_OFFSET) - { *(.init.text) } + { + _sinittext = .; + *(.init.text) + _einittext = .; + } .init.data : AT(ADDR(.init.data) - PAGE_OFFSET) { *(.init.data) }
arch/m68k/vmlinux-std.lds +5 -1
@@ -40,7 +40,11 @@ SECTIONS /* will be freed after init */ . = ALIGN(4096); /* Init code and data */ __init_begin = .; - .init.text : { *(.init.text) } + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } .init.data : { *(.init.data) } . = ALIGN(16); __setup_start = .;
arch/m68k/vmlinux-sun3.lds +5 -1
@@ -34,7 +34,11 @@ SECTIONS /* will be freed after init */ . = ALIGN(8192); /* Init code and data */ __init_begin = .; - .init.text : { *(.init.text) } + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } .init.data : { *(.init.data) } . = ALIGN(16); __setup_start = .;
arch/m68knommu/vmlinux.lds.S +2 -0
@@ -282,7 +282,9 @@ SECTIONS { .init : { . = ALIGN(4096); __init_begin = .; + _sinittext = .; *(.init.text) + _einittext = .; *(.init.data) . = ALIGN(16); __setup_start = .;
arch/parisc/vmlinux.lds.S +5 -1
@@ -53,7 +53,11 @@ SECTIONS . = ALIGN(16384); __init_begin = .; - .init.text : { *(.init.text) } + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } .init.data : { *(.init.data) } . = ALIGN(16); __setup_start = .;
arch/ppc/vmlinux.lds.S +5 -1
@@ -78,7 +78,11 @@ SECTIONS . = ALIGN(4096); __init_begin = .; - .init.text : { *(.init.text) } + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } .init.data : { *(.init.data); __vtop_table_begin = .;
arch/ppc64/vmlinux.lds.S +5 -1
@@ -77,7 +77,11 @@ SECTIONS /* will be freed after init */ . = ALIGN(4096); __init_begin = .; - .init.text : { *(.init.text) } + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } .init.data : { *(.init.data) } . = ALIGN(16); __setup_start = .;
arch/s390/vmlinux.lds.S +5 -1
@@ -58,7 +58,11 @@ SECTIONS /* will be freed after init */ . = ALIGN(4096); /* Init code and data */ __init_begin = .; - .init.text : { *(.init.text) } + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } .init.data : { *(.init.data) } . = ALIGN(256); __setup_start = .;
arch/s390x/vmlinux.lds.S +5 -1
@@ -58,7 +58,11 @@ SECTIONS /* will be freed after init */ . = ALIGN(4096); /* Init code and data */ __init_begin = .; - .init.text : { *(.init.text) } + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } .init.data : { *(.init.data) } . = ALIGN(256); __setup_start = .;
arch/sparc/vmlinux.lds.S +5 -1
@@ -34,7 +34,11 @@ SECTIONS . = ALIGN(4096); __init_begin = .; - .init.text : { *(.init.text) } + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } __init_text_end = .; .init.data : { *(.init.data) } . = ALIGN(16);
arch/sparc64/vmlinux.lds.S +5 -1
@@ -41,7 +41,11 @@ SECTIONS . = ALIGN(8192); __init_begin = .; - .init.text : { *(.init.text) } + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } .init.data : { *(.init.data) } . = ALIGN(16); __setup_start = .;
arch/v850/vmlinux.lds.S +4 -0
@@ -105,7 +105,9 @@ #define RAMK_INIT_CONTENTS_NO_END \ . = ALIGN (4096) ; \ __init_start = . ; \ + _sinittext = .; \ *(.init.text) /* 2.5 convention */ \ + _einittext = .; \ *(.init.data) \ *(.text.init) /* 2.4 convention */ \ *(.data.init) \
@@ -125,7 +127,9 @@ /* The contents of `init' section for a ROM-resident kernel which should go into ROM. */ #define ROMK_INIT_ROM_CONTENTS \ + _sinittext = .; \ *(.init.text) /* 2.5 convention */ \ + _einittext = .; \ *(.text.init) /* 2.4 convention */ \ INITCALL_CONTENTS \ INITRAMFS_CONTENTS
arch/x86_64/vmlinux.lds.S +5 -1
@@ -78,7 +78,11 @@ SECTIONS . = ALIGN(4096); /* Init code and data */ __init_begin = .; - .init.text : { *(.init.text) } + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } .init.data : { *(.init.data) } . = ALIGN(16); __setup_start = .;
kernel/extable.c +5 -1
@@ -19,7 +19,7 @@extern const struct exception_table_entry __start___ex_table[];extern const struct exception_table_entry __stop___ex_table[]; -extern char _stext[], _etext[]; +extern char _stext[], _etext[], _sinittext[], _einittext[];/* Given an address, look for it in the exception tables. */ const struct exception_table_entry *search_exception_tables (unsigned long addr)
@@ -38,5 +38,9 @@ int kernel_text_address(unsigned long ad addr <= (unsigned long)_etext)return 1 ; +if (addr >= (unsigned long )_sinittext && + addr <= (unsigned long )_einittext) +return 1 ; +return module_text_address (addr); }
kernel/kallsyms.c +19 -2
@@ -15,7 +15,22 @@ extern unsigned long kallsyms_num_syms _ extern char kallsyms_names[] __attribute__((weak));/* Defined by the linker script. */ -extern char _stext[], _etext[]; +extern char _stext[], _etext[], _sinittext[], _einittext[]; + +static inline int is_kernel_inittext (unsigned long addr) +{ +if (addr >= (unsigned long )_sinittext + && addr <= (unsigned long )_einittext) +return 1 ; +return 0 ; +} + +static inline int is_kernel_text (unsigned long addr) +{ +if (addr >= (unsigned long )_stext && addr <= (unsigned long )_etext) +return 1 ; +return 0 ; +}/* Lookup an address. modname is set to NULL if it's in the kernel. */ const char *kallsyms_lookup(unsigned long addr,
@@ -31,7 +46,7 @@ const char *kallsyms_lookup(unsigned lon namebuf[127 ] =0 ; namebuf[0 ] =0 ; -if (addr >= (unsigned long )_stext && addr <= (unsigned long )_etext) { +if (is_kernel_text (addr) ||is_kernel_inittext (addr)) {unsigned long symbol_end;char *name = kallsyms_names;
@@ -52,6 +67,8 @@ const char *kallsyms_lookup(unsigned lon/* Base symbol size on next symbol. */ if (best +1 < kallsyms_num_syms) symbol_end = kallsyms_addresses[best +1 ]; +else if (is_kernel_inittext (addr)) + symbol_end = (unsigned long )_einittext;else symbol_end = (unsigned long )_etext;
scripts/kallsyms.c +7 -5
@@ -21,7 +21,7 @@ struct sym_entry {static struct sym_entry *table;static int size, cnt; -static unsigned long long _stext, _etext; +static unsigned long long _stext, _etext, _sinittext, _einittext;static void usage (void )
@@ -51,10 +51,8 @@ read_symbol(FILE *in, struct sym_entry *static int symbol_valid (struct sym_entry *s) { -if (s->addr < _stext) -return 0 ; - -if (s->addr > _etext) +if ((s->addr < _stext || s->addr > _etext) + && (s->addr < _sinittext || s->addr > _einittext))return 0 ;if (strstr (s->sym,"_compiled." ))
@@ -85,6 +83,10 @@ read_map(FILE *in) _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; } }
Quoted 1 line · Rusty Russell
D: TODO: Allow multiple kallsym tables, discard init one after init.
Don't. Almost all kernel threads have a backtrace that goes through __init code, even though that code no longer exists. The symbols are still needed to get a decent backtrace and the overhead is minimal.
In message <[email protected]> you write:
Quoted 7 lines
Quoted 1 line · Rusty Russell
D: TODO: Allow multiple kallsym tables, discard init one after init.
Don't. Almost all kernel threads have a backtrace that goes through
__initcode, even though that code no longer exists. The symbols are still needed to get a decent backtrace and the overhead is minimal.
Hi Keith,
Excellent point. Thanks!
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
Hi,
Quoted 3 lines · Keith Owens
Don't. Almost all kernel threads have a backtrace that goes through
__initcode, even though that code no longer exists. The symbols are still needed to get a decent backtrace and the overhead is minimal.
Are you sure, this is still the case? I remember, that this was the main reason that kernel_thread() is not an inline function anymore, so AFAICT there should be no relevant data on the stack anymore which points to init code.
bye, Roman