ARM binutils feature churn causing kernel problems
Hi,
The ARM binutils seems to be in a problematical state at the moment. It has recently had a "bug" fixed where ARM specific "mapping symbols" were not generated in ELF objects. These "mapping symbols" have names such as "$a" and "$d".
The unfortunate problem is that "$a" nearly always corresponds with the same address as the name of a function - and since none of the kernel knows about these "mapping symbols" we see backtraces which effectively say:
[<address>] ($a+0xfoo/0xbar) from [<address>] ($a+0xfoo/0xbar)
in other words, the kallsyms table and the symbol tables from kernel modules are next to useless because it invariably decodes all addresses to functions named "$a".
While the binutils people have (we believe) fixed "ld" to ignore these symbols when decoding to a function name, "nm" reveals these symbols.
It may be true that this will cause a lot of stuff which parses ELF objects to break, and I'm not going to debate whether the whole idea is a good one or bad. However, what are peoples (Rusty's in particular) to adding yet more ARM binutils specific hacks to the kernel to work around these continuing problems?
My major worry is that ARM ELF format will end up having soo many extra "features" that the Linux kernel, if it's going to continue supporting ARM, will need a fair amount of code to make all these features "work" as expected.
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial coreQuoted 2 lines
From loooking at the gcc and binutils lists it seems codesourcery is pushing
through all the ARM EABI bullshit. Maybe we can persuade hjl to keep it out of his bintuils release? So far we've been served far better with them on Linux anyway..
Quoted 4 lines · Christoph Hellwig
Quoted 1 line
From loooking at the gcc and binutils lists it seems codesourcery is pushing
through all the ARM EABI bullshit. Maybe we can persuade hjl to keep it out of his bintuils release? So far we've been served far better with them on Linux anyway..
Maybe... though I'd like to get some sort of concensus on the specific issue I mentioned so I can provide an adequate response back to the folk involved in this specific issue - both the users _and_ the developers of the toolchain.
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial coreQuoted 5 lines · Christoph Hellwig
From loooking at the gcc and binutils lists it seems codesourcery is pushing through all the ARM EABI bullshit. Maybe we can persuade hjl to keep it out of his bintuils release? So far we've been served far better with them on Linux anyway..
Or maybe we should strongly suggest codesourcery to add a command line option to be able to disable those new "features" especially since they're not always welcome like for the Linux kernel build.
Nicolas
Quoted 1 line · Russell King
[<address>] ($a+0xfoo/0xbar) from [<address>] ($a+0xfoo/0xbar)
Ok, here's a _partly_ tested patch which fixes kallsyms itself. I'm not certain whether this fixes the module side of it since I haven't had an oops from a module to confirm yet.
Comments at this stage only please?
===== kernel/module.c 1.120 vs edited =====
kernel/module.c +13 -2
@@ -1903,6 +1903,15 @@ }#ifdef CONFIG_KALLSYMS +/* +* This ignores the intensely annoying "mapping symbols" found +* in ARM ELF files: $a, $t and $d. +*/ +static inline int is_arm_mapping_symbol (const char *str) +{ +return str[0 ] =='$' &&strchr ("atd" , str[1 ]) && str[2 ] =='\0' ; +} + static const char *get_ksymbol(struct module *mod, unsigned long addr, unsigned long *size,
@@ -1927,11 +1936,13 @@* and inserted at a whim. */ if (mod->symtab[i].st_value <= addr && mod->symtab[i].st_value > mod->symtab[best].st_value - && *(mod->strtab + mod->symtab[i].st_name) !='\0' ) + && *(mod->strtab + mod->symtab[i].st_name) !='\0' + && !is_arm_mapping_symbol (mod->strtab + mod->symtab[i].st_name)) best = i;if (mod->symtab[i].st_value > addr && mod->symtab[i].st_value < nextval - && *(mod->strtab + mod->symtab[i].st_name) !='\0' ) + && *(mod->strtab + mod->symtab[i].st_name) !='\0' + && !is_arm_mapping_symbol (mod->strtab + mod->symtab[i].st_name)) nextval = mod->symtab[i].st_value; }
===== scripts/kallsyms.c 1.12 vs edited =====
scripts/kallsyms.c +12 -1
@@ -32,6 +32,16 @@exit (1 ); } +/* +* This ignores the intensely annoying "mapping symbols" found +* in ARM ELF files: $a, $t and $d. +*/ +static inline int +is_arm_mapping_symbol (const char *str) +{ +return str[0 ] =='$' &&strchr ("atd" , str[1 ]) && str[2 ] =='\0' ; +} +static int read_symbol (FILE *in,struct sym_entry *s) {
@@ -56,7 +66,8 @@ _sinittext = s->addr; else if (strcmp(str, "_einittext") == 0) _einittext = s->addr; - else if (toupper(s->type) == 'A' || toupper(s->type) == 'U') + else if (toupper(s->type) == 'A' || toupper(s->type) == 'U' || + is_arm_mapping_symbol(str))return -1 ; s->sym =strdup (str);
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial coreRussell,
kernel/module.c line 1912
Quoted 6 lines · Russell King
+ * This ignores the intensely annoying "mapping symbols" found
+ * in ARM ELF files: $a, $t and $d.
+ */kernel/module.c +3
-0+static inline int is_arm_mapping_symbol (const char *str) +{ +return str[0 ] =='$' &&strchr ("atd" , str[1 ]) && str[2 ] =='\0' ;
str[2] can be '\0' or '.', since a mapping symbol can also be $[atd].<any> (because binutils doesn't like to generate duplicate local labels).
Catalin
Quoted 13 lines · Catalin Marinas
Russell,
kernel/module.c line 1912
Quoted 6 lines · Russell King
+ * This ignores the intensely annoying "mapping symbols" found
+ * in ARM ELF files: $a, $t and $d.
+ */kernel/module.c +3
-0+static inline int is_arm_mapping_symbol (const char *str) +{ +return str[0 ] =='$' &&strchr ("atd" , str[1 ]) && str[2 ] =='\0' ;str[2] can be '\0' or '.', since a mapping symbol can also be $[atd].<any> (because binutils doesn't like to generate duplicate local labels).
Color me confused...
Russell, I thought about not including any symbol which is not of form "[A-Za-z0-9_]+" in kallsyms, for all archs: you are not the only one with weird-ass symbols. Is it that you want these mapping symbols in /proc/kallsyms but ignored in backtraces, or you don't need them in kallsyms altogether?
Thanks,
Rusty.
Signature · 1 line
Anyone who quotes me in their signature is an idiot -- Rusty Russell
Quoted 8 lines · Rusty Russell <rusty <at> rustcorp.com.au> writes:
Russell, I thought about not including any symbol which is not of form "[A-Za-z0-9_]+" in kallsyms, for all archs: you are not the only one with weird-ass symbols. Is it that you want these mapping symbols in
/proc/kallsymsbut ignored in backtraces, or you don't need them in kallsyms altogether?Thanks,
Rusty.
Mapping symbols will always be encoded with STB_LOCAL and STT_NOTYPE. I would have thought it unlikely that the kernel would ever want to report against any symbol with those attributes and they could all be dropped on that basis.
R.
Quoted 7 lines · Richard Earnshaw
Quoted 6 lines · Rusty Russell <rusty <at> rustcorp.com.au> writes:
Russell, I thought about not including any symbol which is not of form "[A-Za-z0-9_]+" in kallsyms, for all archs: you are not the only one with weird-ass symbols. Is it that you want these mapping symbols in
/proc/kallsymsbut ignored in backtraces, or you don't need them in kallsyms altogether?
Quoted 8 lines
Quoted 2 lines
Thanks,
Rusty.Mapping symbols will always be encoded with
STB_LOCALandSTT_NOTYPE. I would have thought it unlikely that the kernel would ever want to report against any symbol with those attributes and they could all be dropped on that basis.
(Richard - your mailer appears to have dropped people from the CC: list...)
How about this patch? Is there a better way to parse the 'nm' output to achieve the same as your suggestion above?
kernel/module.c +4 -0
@@ -1923,6 +1923,10 @@ static const char *get_ksymbol(struct moif (mod->symtab[i].st_shndx ==SHN_UNDEF )continue ; +if (ELF_ST_BIND (mod->symtab[i].st_info) ==STB_LOCAL + &&ELF_ST_TYPE (mod->symtab[i].st_info) ==STT_NOTYPE ) +continue ; +/* We ignore unnamed symbols: they're uninformative * and inserted at a whim. */ if (mod->symtab[i].st_value <= addr
scripts/kallsyms.c +13 -1
@@ -32,6 +32,17 @@ usage(void)exit (1 ); } +/* +* This ignores the intensely annoying "mapping symbols" found +* in ARM ELF files: $a, $t and $d. +*/ +static inline int +is_arm_mapping_symbol (const char *str) +{ +return str[0 ] =='$' &&strchr ("atd" , str[1 ]) && + (str[2 ] =='\0' || str[2 ] =='.' ); +} +static int read_symbol (FILE *in,struct sym_entry *s) {
@@ -56,7 +67,8 @@ read_symbol(FILE *in, struct sym_entry * _sinittext = s->addr; else if (strcmp(str, "_einittext") == 0) _einittext = s->addr; - else if (toupper(s->type) == 'A' || toupper(s->type) == 'U') + else if (toupper(s->type) == 'A' || toupper(s->type) == 'U' || + is_arm_mapping_symbol(str))return -1 ; s->sym =strdup (str);
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial coreQuoted 12 lines · Russell King
Quoted 11 lines · Richard Earnshaw
Quoted 8 lines · Rusty Russell <rusty <at> rustcorp.com.au> writes:
Russell, I thought about not including any symbol which is not of form "[A-Za-z0-9_]+" in kallsyms, for all archs: you are not the only one with weird-ass symbols. Is it that you want these mapping symbols in
/proc/kallsymsbut ignored in backtraces, or you don't need them in kallsyms altogether?Thanks,
Rusty.
Quoted 7 lines
Quoted 4 lines
Mapping symbols will always be encoded with
STB_LOCALandSTT_NOTYPE. I would have thought it unlikely that the kernel would ever want to report against any symbol with those attributes and they could all be dropped on that basis.(Richard - your mailer appears to have dropped people from the CC: list...)
Not by me, I don't subscribe to the list in question and was pointed to gmane.linux.kernel newsgroup by Phillipe. I simply followed up to that message.
Quoted 39 lines
How about this patch? Is there a better way to parse the 'nm' output to achieve the same as your suggestion above?
diff -up -x BitKeeper -x ChangeSet -x SCCS -x
_xlk-x *.orig -x *.rejorig/kernel/module.clinux/kernel/module.ckernel/module.c +4
-0@@ -1923,6 +1923,10 @@ static const char *get_ksymbol(struct moif (mod->symtab[i].st_shndx ==SHN_UNDEF )continue ; +if (ELF_ST_BIND (mod->symtab[i].st_info) ==STB_LOCAL + &&ELF_ST_TYPE (mod->symtab[i].st_info) ==STT_NOTYPE ) +continue ; +/* We ignore unnamed symbols: they're uninformative * and inserted at a whim. */ if (mod->symtab[i].st_value <= addrdiff -up -x BitKeeper -x ChangeSet -x SCCS -x
_xlk-x *.orig -x *.rejorig/scripts/kallsyms.clinux/scripts/kallsyms.cscripts/kallsyms.c +11
-0@@ -32,6 +32,17 @@ usage(void)exit (1 ); } +/* +* This ignores the intensely annoying "mapping symbols" found +* in ARM ELF files: $a, $t and $d. +*/ +static inline int +is_arm_mapping_symbol (const char *str) +{ +return str[0 ] =='$' &&strchr ("atd" , str[1 ]) && + (str[2 ] =='\0' || str[2 ] =='.' ); +} +static int read_symbol (FILE *in,struct sym_entry *s) {
scripts/kallsyms.c read_symbol(FILE *in, struct sym_entry * · line 74
Quoted 9 lines
scripts/kallsyms.c +2
-1@@ -56,7 +67,8 @@ read_symbol(FILE *in, struct sym_entry * _sinittext = s->addr; else if (strcmp(str, "_einittext") == 0) _einittext = s->addr; - else if (toupper(s->type) == 'A' || toupper(s->type) == 'U') + else if (toupper(s->type) == 'A' || toupper(s->type) == 'U' || + is_arm_mapping_symbol(str))return -1 ; s->sym =strdup (str);
Why don't you pass s to is_arm_mapping_symbol and have it do the same thing as you've done in get_ksymbol?
R.
Signature · 19 lines
Richard Earnshaw Email: [email protected] ARM Ltd Phone: +44 1223 400569 (Direct + VoiceMail) 110 Fulbourn Road Switchboard: +44 1223 400400 Cherry Hinton Fax: +44 1223 400410 Cambridge CB1 9NJ Web: http://www.arm.com/ UK ---------------------------------------------------------------- This e-mail message is intended for the addressee(s) only and may contain information that is the property of, and/or subject to a confidentiality agreement between the intended recipient(s), their organisation and/or the ARM Group of Companies. If you are not an intended recipient of this e-mail message, you should not read, copy, forward or otherwise distribute or further disclose the information in it; misuse of the contents of this e-mail message may violate various laws in your state, country or jurisdiction. If you have received this e-mail message in error, please contact the originator of this e-mail message via e-mail and delete all copies of this message from your computer or network, thank you. ----------------------------------------------------------------
Quoted 31 lines · Richard Earnshaw
Quoted 30 lines · Russell King
diff -up -x BitKeeper -x ChangeSet -x SCCS -x
_xlk-x *.orig -x *.rejorig/scripts/kallsyms.clinux/scripts/kallsyms.cscripts/kallsyms.c +13
-1@@ -32,6 +32,17 @@ usage(void)exit (1 ); } +/* +* This ignores the intensely annoying "mapping symbols" found +* in ARM ELF files: $a, $t and $d. +*/ +static inline int +is_arm_mapping_symbol (const char *str) +{ +return str[0 ] =='$' &&strchr ("atd" , str[1 ]) && + (str[2 ] =='\0' || str[2 ] =='.' ); +} +static int read_symbol (FILE *in,struct sym_entry *s) {@@ -56,7 +67,8 @@ read_symbol(FILE *in, struct sym_entry * _sinittext = s->addr; else if (strcmp(str, "_einittext") == 0) _einittext = s->addr; - else if (toupper(s->type) == 'A' || toupper(s->type) == 'U') + else if (toupper(s->type) == 'A' || toupper(s->type) == 'U' || + is_arm_mapping_symbol(str))return -1 ;
Quoted 4 lines
scripts/kallsyms.c read_symbol(FILE *in, struct sym_entry * · line 74
Quoted 1 line
scripts/kallsyms.c +0
-0s->sym =strdup (str);Why don't you pass s to
is_arm_mapping_symboland have it do the same thing as you've done inget_ksymbol?
"sym_entry" is not an ELF symtab structure - it's a parsed version of the `nm' output, and as such does not contain the symbol type nor binding information.
Quoted 5 lines
----------------------------------------------------------------
This e-mail message is intended for the addressee(s) only and may contain information that is the property of, and/or subject to a confidentiality agreement between the intended recipient(s), their organisation and/or the ARM Group of Companies. If you are not an
Quoted 8 lines
intended recipient of this e-mail message, you should not read, copy, forward or otherwise distribute or further disclose the information in it; misuse of the contents of this e-mail message may violate various laws in your state, country or jurisdiction. If you have received this e-mail message in error, please contact the originator of this e-mail message via e-mail and delete all copies of this message from your computer or network, thank you.
----------------------------------------------------------------
Does this apply to your message? It would appear that third parties subscribed to linux-kernel are not allowed to read your messages because they're not an "intended recipient" !
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial coreQuoted 7 lines · Russell King
Quoted 2 lines
Why don't you pass s to
is_arm_mapping_symboland have it do the same thing as you've done inget_ksymbol?"
sym_entry" is not an ELF symtab structure - it's a parsed version of the `nm' output, and as such does not contain the symbol type nor binding information.
Ah. That makes the question in your previous message make more sense then. What options do you pass to nm?
Looking at the output of nm -fsysv shows that currently the mapping symbols are being incorrectly typed (the EABI requires them to be STT_NOTYPE, but the previous ELF specification -- not supported by GNU utils -- required them to be typed by the data they addressed. I'll submit a patch for that shortly).
Quoted 7 lines
Quoted 4 lines
----------------------------------------------------------------
This e-mail message is intended for the addressee(s) only and may contain information that is the property of, and/or subject to a
...Does this apply to your message? It would appear that third parties subscribed to linux-kernel are not allowed to read your messages because they're not an "intended recipient" !
In this case no, which is why I reposted the message without it. It was an oversight (I have to remove the boilerplate when I *don't* need it rather than add it when I do).
R.
Quoted 5 lines · Richard Earnshaw
Quoted 3 lines · Russell King
Quoted 2 lines
Why don't you pass s to
is_arm_mapping_symboland have it do the same thing as you've done inget_ksymbol?
Quoted 7 lines
Quoted 4 lines
"
sym_entry" is not an ELF symtab structure - it's a parsed version of the `nm' output, and as such does not contain the symbol type nor binding information.Ah. That makes the question in your previous message make more sense then. What options do you pass to nm?
Only -n.
Quoted 5 lines
Looking at the output of nm -fsysv shows that currently the mapping symbols are being incorrectly typed (the EABI requires them to be
STT_NOTYPE, but the previous ELF specification -- not supported by GNU utils -- required them to be typed by the data they addressed. I'll submit a patch for that shortly).
Ugg - in that case, we need to go with the "match the name" version until these changes in binutils have matured (== 2 or 3 years time.)
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial coreQuoted 10 lines · Russell King
Quoted 5 lines · Richard Earnshaw
Looking at the output of nm -fsysv shows that currently the mapping symbols are being incorrectly typed (the EABI requires them to be
STT_NOTYPE, but the previous ELF specification -- not supported by GNU utils -- required them to be typed by the data they addressed. I'll submit a patch for that shortly).Ugg - in that case, we need to go with the "match the name" version until these changes in binutils have matured (== 2 or 3 years time.)
Why does the Linux ARM ABI have to have any relation to the ARM EABI? The PowerPC has had two different ABIs for years, and it's not caused us any trouble. Can't we just leave the behaviour of binutils alone when configured for an arm-linux target, and put all feature churn into an arm-eabi target?
- Adrian Cox
Humboldt Solutions Ltd.
Quoted 9 lines · Adrian Cox
Quoted 8 lines · Russell King
Quoted 5 lines · Richard Earnshaw
Looking at the output of nm -fsysv shows that currently the mapping symbols are being incorrectly typed (the EABI requires them to be
STT_NOTYPE, but the previous ELF specification -- not supported by GNU utils -- required them to be typed by the data they addressed. I'll submit a patch for that shortly).
Quoted 8 lines
Quoted 2 lines
Ugg - in that case, we need to go with the "match the name" version until these changes in binutils have matured (== 2 or 3 years time.)
Why does the Linux ARM ABI have to have any relation to the ARM EABI? The PowerPC has had two different ABIs for years, and it's not caused us any trouble. Can't we just leave the behaviour of binutils alone when configured for an arm-linux target, and put all feature churn into an arm-eabi target?
I'll suggest that Richard should answer this question.
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial coreQuoted 5 lines · Adrian Cox
Why does the Linux ARM ABI have to have any relation to the ARM EABI? The PowerPC has had two different ABIs for years, and it's not caused us any trouble. Can't we just leave the behaviour of binutils alone when configured for an arm-linux target, and put all feature churn into an arm-eabi target?
Sorry for the delay replying. The trouble with going on holiday is that you then have to catch up again...
The primary reason is because we have customers who are asking for it [linux conforming to the EABI].
On a technical front there's a number of reasons why it would be a good idea too:
- Natural endian and alignment of all basic types ( => better compatibility with other Linux ports. Also *very* important on XScale)
- Better compatibility with Thumb (a major customer demand).
- No more emulation of floating-point instructions that don't exist in the hardware.
- Future proofing -- the EABI is these days considered at the architectural level.
- and in C++, an efficient and compact unwinding model.
R.
Quoted 16 lines · Russell King
Quoted 5 lines · Richard Earnshaw
Quoted 3 lines · Russell King
Quoted 2 lines
Why don't you pass s to
is_arm_mapping_symboland have it do the same thing as you've done inget_ksymbol?Quoted 7 lines
Quoted 4 lines
"
sym_entry" is not an ELF symtab structure - it's a parsed version of the `nm' output, and as such does not contain the symbol type nor binding information.Ah. That makes the question in your previous message make more sense then. What options do you pass to nm?
Only -n.
Quoted 8 lines
Quoted 5 lines
Looking at the output of nm -fsysv shows that currently the mapping symbols are being incorrectly typed (the EABI requires them to be
STT_NOTYPE, but the previous ELF specification -- not supported by GNU utils -- required them to be typed by the data they addressed. I'll submit a patch for that shortly).Ugg - in that case, we need to go with the "match the name" version until these changes in binutils have matured (== 2 or 3 years time.)
Ok, here's a patch which fixes the problem using the original method.
This patch filters out the ARM mapping symbols by matching the name only. Unfortunately, we are unable to use STT_NOTYPE / STB_LOCAL since existing binutils does not generate ARM mapping symbols correctly.
Reference: 02-debug/03-kallsyms.diff
===== kernel/module.c 1.120 vs edited =====
kernel/module.c +14 -2
@@ -1903,6 +1903,16 @@ }#ifdef CONFIG_KALLSYMS +/* +* This ignores the intensely annoying "mapping symbols" found +* in ARM ELF files: $a, $t and $d. +*/ +static inline int is_arm_mapping_symbol (const char *str) +{ +return str[0 ] =='$' &&strchr ("atd" , str[1 ]) + && (str[2 ] =='\0' || str[2 ] =='.' ); +} + static const char *get_ksymbol(struct module *mod, unsigned long addr, unsigned long *size,
@@ -1927,11 +1937,13 @@* and inserted at a whim. */ if (mod->symtab[i].st_value <= addr && mod->symtab[i].st_value > mod->symtab[best].st_value - && *(mod->strtab + mod->symtab[i].st_name) !='\0' ) + && *(mod->strtab + mod->symtab[i].st_name) !='\0' + && !is_arm_mapping_symbol (mod->strtab + mod->symtab[i].st_name)) best = i;if (mod->symtab[i].st_value > addr && mod->symtab[i].st_value < nextval - && *(mod->strtab + mod->symtab[i].st_name) !='\0' ) + && *(mod->strtab + mod->symtab[i].st_name) !='\0' + && !is_arm_mapping_symbol (mod->strtab + mod->symtab[i].st_name)) nextval = mod->symtab[i].st_value; }
===== scripts/kallsyms.c 1.12 vs edited =====
scripts/kallsyms.c +13 -1
@@ -32,6 +32,17 @@exit (1 ); } +/* +* This ignores the intensely annoying "mapping symbols" found +* in ARM ELF files: $a, $t and $d. +*/ +static inline int +is_arm_mapping_symbol (const char *str) +{ +return str[0 ] =='$' &&strchr ("atd" , str[1 ]) + && (str[2 ] =='\0' || str[2 ] =='.' ); +} +static int read_symbol (FILE *in,struct sym_entry *s) {
@@ -56,7 +67,8 @@ _sinittext = s->addr; else if (strcmp(str, "_einittext") == 0) _einittext = s->addr; - else if (toupper(s->type) == 'A' || toupper(s->type) == 'U') + else if (toupper(s->type) == 'A' || toupper(s->type) == 'U' || + is_arm_mapping_symbol(str))return -1 ; s->sym =strdup (str);
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial coreQuoted 7 lines · Russell King
Quoted 2 lines · Richard Earnshaw
Why don't you pass s to
is_arm_mapping_symboland have it do the same thing as you've done inget_ksymbol?"
sym_entry" is not an ELF symtab structure - it's a parsed version of the `nm' output, and as such does not contain the symbol type nor binding information.
I believe that Paulo (CC'd) ended up with a patch which included the actual type information in /proc/kallsyms. Paulo, what's the status of that patch?
Rusty.
Signature · 1 line
Anyone who quotes me in their signature is an idiot -- Rusty Russell
Quoted 7 lines · Rusty Russell
Quoted 5 lines · Russell King
Quoted 2 lines · Richard Earnshaw
Why don't you pass s to
is_arm_mapping_symboland have it do the same thing as you've done inget_ksymbol?
Quoted 8 lines
Quoted 3 lines
"
sym_entry" is not an ELF symtab structure - it's a parsed version of the `nm' output, and as such does not contain the symbol type nor binding information.I believe that Paulo (CC'd) ended up with a patch which included the actual type information in
/proc/kallsyms. Paulo, what's the status of that patch?
That patch is in the -mm tree, and has been there for a while, so it is pretty much stable by now. There were 4 seperate patches, but since they were pretty much dependant, I think akpm merged them into "kallsyms-data-size-reduction--lookup-speedup.patch".
For those who don't know what the patch is about, it changes the format of the compressed kallsyms, so that they occupy less space, decompress faster (a lot faster) and include the same type char that was output by nm.
The code in kernel/kallsyms.c handles "aliases" (symbols with the same address) in a way that it shows a consistent output: the symbol shown is always the first. This can be easily changed, but I didn't want to change the old behavior.
The patch by Russel King seems ok to me, although I prefer Rusty's idea of not using any symbol that is not in the form "[A-Za-z0-9_]+". We just need to check if there are any real world users of these "weird" symbols.
If this seems ok to everyone I can cook up a patch to do this.
Signature · 4 lines
Paulo Marques - www.grupopie.com To err is human, but to really foul things up requires a computer. Farmers' Almanac, 1978
Quoted 3 lines · Paulo Marques
The patch by Russel King seems ok to me, although I prefer Rusty's idea of not using any symbol that is not in the form "[A-Za-z0-9_]+". We just need to check if there are any real world users of these "weird" symbols.
This may filter out too much - we have symbols starting with a '.' on ARM, particularly used in some of the assembly code, which are useful to be decoded back to names, such as ".bug".
However, including "." means that names like "__func__.0" also get included, which is probably a bad thing. So, maybe it needs to be
[A-Za-z0-9_\.][A-Za-z0-9_]*
?
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial coreQuoted 5 lines · Russell King
Quoted 1 line · Paulo Marques
The patch by Russel King seems ok to me, although I prefer Rusty's idea of not using any symbol that is not in the form "[A-Za-z0-9_]+". We just need to check if there are any real world users of these "weird" symbols.
Quoted 8 lines
This may filter out too much - we have symbols starting with a '.' on ARM, particularly used in some of the assembly code, which are useful to be decoded back to names, such as ".bug".
However, including "." means that names like "__func__.0" also get included, which is probably a bad thing. So, maybe it needs to be
[A-Za-z0-9_\.][A-Za-z0-9_]*
I just checked a "nm -n vmlinux" output on a x86 2.6.9-rc3-mm2 defconfig kernel and it has stuff like:
...c01aed13 t .text.lock.transactionc01b1db3 t .text.lock.checkpoint
...c03c7708 r single_rates.0c03c7714 r double_rate_channels.1
...c0482280 d get_s16_labels.0c04822c0 d put_s16_labels.1c0482300 d get_s16_labels.2c0482340 d put_s16_labels.3
...c053d780 b nulldevname.1c053d800 b bootstrap.2
...
Most of these seem like useful information (although I personally don't have any use for them).
The 'b' and 'r' types only get in if CONFIG_KALLSYMS_ALL is specified.
There were 572 "__func__.*" symbols all with type 'r'. If we take into account that there were a total of 32881 symbols, these 572 are not that many. Even more, with the new compression scheme they would probably take only about 3 bytes per symbol to store the name and 4 bytes for the address (8 on 64 bit architectures) that would require about 4kb of data
for users that choose the CONFIG_KALLSYMS_ALL option. Removing the
"__func__" symbols would represent less than a 2% decrease in size.
So maybe we could use "[A-Za-z0-9_\.]+" ?
Signature · 4 lines
Paulo Marques - www.grupopie.com To err is human, but to really foul things up requires a computer. Farmers' Almanac, 1978
[Let me try this again, without the corporate boilerplate on the bottom]
Quoted 12 lines · Russell King
Quoted 11 lines · Richard Earnshaw
Quoted 8 lines · Rusty Russell <rusty <at> rustcorp.com.au> writes:
Russell, I thought about not including any symbol which is not of form "[A-Za-z0-9_]+" in kallsyms, for all archs: you are not the only one with weird-ass symbols. Is it that you want these mapping symbols in
/proc/kallsymsbut ignored in backtraces, or you don't need them in kallsyms altogether?Thanks,
Rusty.
Quoted 6 lines
Quoted 4 lines
Mapping symbols will always be encoded with
STB_LOCALandSTT_NOTYPE. I would have thought it unlikely that the kernel would ever want to report against any symbol with those attributes and they could all be dropped on that basis.(Richard - your mailer appears to have dropped people from the CC: list...)
Not by me, I don't subscribe to the list in question and was pointed to gmane.linux.kernel newsgroup by Phillipe. I simply followed up to that message.
Quoted 39 lines
How about this patch? Is there a better way to parse the 'nm' output to achieve the same as your suggestion above?
diff -up -x BitKeeper -x ChangeSet -x SCCS -x
_xlk-x *.orig -x *.rejorig/kernel/module.clinux/kernel/module.ckernel/module.c +4
-0@@ -1923,6 +1923,10 @@ static const char *get_ksymbol(struct moif (mod->symtab[i].st_shndx ==SHN_UNDEF )continue ; +if (ELF_ST_BIND (mod->symtab[i].st_info) ==STB_LOCAL + &&ELF_ST_TYPE (mod->symtab[i].st_info) ==STT_NOTYPE ) +continue ; +/* We ignore unnamed symbols: they're uninformative * and inserted at a whim. */ if (mod->symtab[i].st_value <= addrdiff -up -x BitKeeper -x ChangeSet -x SCCS -x
_xlk-x *.orig -x *.rejorig/scripts/kallsyms.clinux/scripts/kallsyms.cscripts/kallsyms.c +11
-0@@ -32,6 +32,17 @@ usage(void)exit (1 ); } +/* +* This ignores the intensely annoying "mapping symbols" found +* in ARM ELF files: $a, $t and $d. +*/ +static inline int +is_arm_mapping_symbol (const char *str) +{ +return str[0 ] =='$' &&strchr ("atd" , str[1 ]) && + (str[2 ] =='\0' || str[2 ] =='.' ); +} +static int read_symbol (FILE *in,struct sym_entry *s) {
scripts/kallsyms.c read_symbol(FILE *in, struct sym_entry * · line 74
Quoted 9 lines
scripts/kallsyms.c +2
-1@@ -56,7 +67,8 @@ read_symbol(FILE *in, struct sym_entry * _sinittext = s->addr; else if (strcmp(str, "_einittext") == 0) _einittext = s->addr; - else if (toupper(s->type) == 'A' || toupper(s->type) == 'U') + else if (toupper(s->type) == 'A' || toupper(s->type) == 'U' || + is_arm_mapping_symbol(str))return -1 ; s->sym =strdup (str);
Why don't you pass s to is_arm_mapping_symbol and have it do the same thing as you've done in get_ksymbol?
R.
Quoted 4 lines · Russell King
The ARM binutils seems to be in a problematical state at the moment. It has recently had a "bug" fixed where ARM specific "mapping symbols" were not generated in ELF objects. These "mapping symbols" have names such as "$a" and "$d".
Ok, another tool which is affected by this is procps:
$ ps alx Warning: /boot/System.map-2.6.9-rc3 not parseable as a System.map Warning: /boot/System.map not parseable as a System.map Warning: /usr/src/linux/System.map has an incorrect kernel version. F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND 4 0 1 0 16 0 1244 508 do_sel S ? 0:01 init [3] ... $ grep -v '\$[adt]' /boot/System.map-2.6.9-rc3 > System.map-2.6.9-rc3 $ PS_SYSTEM_MAP=System.map-2.6.9-rc3 ps alx F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND 4 0 1 0 16 0 1244 508 do_sel S ? 0:01 init [3] ...
The System.map file is generated by ($1 = vmlinux $2 = System.map):
$NM -n $1 | grep -v '\( [aUw] \)\|\(__crc_\)' > $2
Can we change this to:
$NM -n $1 | grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)' > $2
?
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial coreQuoted 8 lines · Russell King
Quoted 4 lines · Russell King
The ARM binutils seems to be in a problematical state at the moment. It has recently had a "bug" fixed where ARM specific "mapping symbols" were not generated in ELF objects. These "mapping symbols" have names such as "$a" and "$d".
Quoted 8 lines
Ok, another tool which is affected by this is procps:
$ ps alx Warning: /boot/System.map-2.6.9-rc3 not parseable as a System.map Warning: /boot/System.map not parseable as a System.map Warning: /usr/src/linux/System.map has an incorrect kernel version. F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND 4 0 1 0 16 0 1244 508 do_sel S ? 0:01 init [3]
ps is reading System.map probably because reading /proc/<pid>/wchan directly was very slow. It used to take an average of 1.3ms (on a P4 2.8GHz) and now it takes less than 0.5us (that is miliseconds and microseconds!)
If this is the case, then after the changes to kallsyms go in, procps could start using wchan directly and avoid reading the System.map altogether.
I'm adding Albert Cahalan to this list since he should know a little more about this :)
Signature · 4 lines
Paulo Marques - www.grupopie.com To err is human, but to really foul things up requires a computer. Farmers' Almanac, 1978
Quoted 9 lines · Paulo Marques
Quoted 8 lines · Russell King
Quoted 4 lines · Russell King
The ARM binutils seems to be in a problematical state at the moment. It has recently had a "bug" fixed where ARM specific "mapping symbols" were not generated in ELF objects. These "mapping symbols" have names such as "$a" and "$d".
Quoted 8 lines
Quoted 8 lines
Ok, another tool which is affected by this is procps:
$ ps alx Warning: /boot/System.map-2.6.9-rc3 not parseable as a System.map Warning: /boot/System.map not parseable as a System.map Warning: /usr/src/linux/System.map has an incorrect kernel version. F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND 4 0 1 0 16 0 1244 508 do_sel S ? 0:01 init [3]
The "$" is considered a garbage character by the sanity check. (same as "\v", "\033", "\xff", and so on)
Quoted 4 lines
ps is reading System.map probably because reading /proc/<pid>/wchan directly was very slow. It used to take an average of 1.3ms (on a P4 2.8GHz) and now it takes less than 0.5us (that is miliseconds and microseconds!)
No, the /proc/*/wchan file is supposed to be used. For some reason, stat() is failing. Here is the code:
// next try the Linux 2.5.xx method
if(!stat("/proc/self/wchan", &sbuf)){
use_wchan_file = 1; // hack
return 0;
}See what these commands tell you:
strace -o data -e trace=stat ps alx >> /dev/null ; grep self data stat /proc/self/wchan
stat /proc/$$/wchan
stat /proc/self/
stat /proc/self
Quoted 3 lines
If this is the case, then after the changes to kallsyms go in, procps could start using wchan directly and avoid reading the System.map altogether.
Here's an idea: if both name and number were provided at the same time and I could get notified when a module is loaded or unloaded, then I could cache the number-to-name translation.
Quoted 11 lines · Albert Cahalan
....
No, the
/proc/*/wchanfile is supposed to be used. For some reason,stat()is failing. Here is the code:// next try the Linux 2.5.xx method if(!stat("/proc/self/wchan", &sbuf)){ use_wchan_file = 1; // hack return 0; }
Quoted 7 lines
See what these commands tell you:
strace -o data -e trace=stat ps alx >>
/dev/null; grep self data stat/proc/self/wchan
stat/proc/$$/wchan
stat/proc/self/
stat/proc/self
You are right. I just tested this on my system and ps doesn't read any System.map at all, provided there is a /proc/<pid>/wchan file to read from.
Quoted 7 lines
Quoted 1 line
If this is the case, then after the changes to kallsyms go in, procps could start using wchan directly and avoid reading the System.map altogether.
Here's an idea: if both name and number were provided at the same time and I could get notified when a module is loaded or unloaded, then I could cache the number-to-name translation.
This is more a question of whether kallsyms is a good feature to have always (modulo embedded or very limited memory systems) or not. If kallsyms is always available, the procps tools already read /proc/<pid>/wchan and don't need to cache anything at all. The only reason to cache would be performance, but if you try a recent -mm kernel you can see that there is no need for that any more.
From what I've seen on this list since I've joined (almost a year ago), 2.4 stack dumps are almost useless[1] whereas the 2.6 ones give very useful information thanks to the function names (and offsets) that lead to the problem.
IMHO we should try to make kallsyms always available, reducing further the space used by the symbol data if necessary.
Signature · 6 lines
Paulo Marques - www.grupopie.com To err is human, but to really foul things up requires a computer. Farmers' Almanac, 1978 [1] of course using ksymoops would solve this, but it requires more knowledge from the user than kallsyms, so it is not the same thing
PATCH 1/1 Fix ARM kernel build with permitted binutils versions
In reply to Russell KingOk, here's the latest version of the patch, fixing all presently known issues with ARM binutils post 2.11.90 by changing the kernel to suit.
Yes, it sounds like the wrong thing to do, but shrug.
---
All ARM binutils versions post 2.11.90 contains an extra "feature" which interferes with the kernel in various ways - extra "mapping symbols" in the ELF symbol table '$a', '$t' and '$d'. This causes two problems:
1. Since '$a' symbols have the same value as function names, this causes anything which uses the kallsyms infrastructure to report wrong values.
2. programs which parse System.map do not expect symbols to start with '$'.
===== kernel/module.c 1.120 vs edited =====
kernel/module.c +14 -2
@@ -1903,6 +1903,16 @@ }#ifdef CONFIG_KALLSYMS +/* +* This ignores the intensely annoying "mapping symbols" found +* in ARM ELF files: $a, $t and $d. +*/ +static inline int is_arm_mapping_symbol (const char *str) +{ +return str[0 ] =='$' &&strchr ("atd" , str[1 ]) + && (str[2 ] =='\0' || str[2 ] =='.' ); +} + static const char *get_ksymbol(struct module *mod, unsigned long addr, unsigned long *size,
@@ -1927,11 +1937,13 @@* and inserted at a whim. */ if (mod->symtab[i].st_value <= addr && mod->symtab[i].st_value > mod->symtab[best].st_value - && *(mod->strtab + mod->symtab[i].st_name) !='\0' ) + && *(mod->strtab + mod->symtab[i].st_name) !='\0' + && !is_arm_mapping_symbol (mod->strtab + mod->symtab[i].st_name)) best = i;if (mod->symtab[i].st_value > addr && mod->symtab[i].st_value < nextval - && *(mod->strtab + mod->symtab[i].st_name) !='\0' ) + && *(mod->strtab + mod->symtab[i].st_name) !='\0' + && !is_arm_mapping_symbol (mod->strtab + mod->symtab[i].st_name)) nextval = mod->symtab[i].st_value; }
===== scripts/kallsyms.c 1.12 vs edited =====
scripts/kallsyms.c +13 -1
@@ -32,6 +32,17 @@exit (1 ); } +/* +* This ignores the intensely annoying "mapping symbols" found +* in ARM ELF files: $a, $t and $d. +*/ +static inline int +is_arm_mapping_symbol (const char *str) +{ +return str[0 ] =='$' &&strchr ("atd" , str[1 ]) + && (str[2 ] =='\0' || str[2 ] =='.' ); +} +static int read_symbol (FILE *in,struct sym_entry *s) {
@@ -56,7 +67,8 @@ _sinittext = s->addr; else if (strcmp(str, "_einittext") == 0) _einittext = s->addr; - else if (toupper(s->type) == 'A' || toupper(s->type) == 'U') + else if (toupper(s->type) == 'A' || toupper(s->type) == 'U' || + is_arm_mapping_symbol(str))return -1 ; s->sym =strdup (str);
===== scripts/mksysmap 1.4 vs edited =====
scripts/mksysmap +1 -1
@@ -40,5 +40,5 @@ # so we just ignore them to let readprofile continue to work. # (At least sparc64 has __crc_ in the middle). -$NM -n $1 | grep -v '\( [aUw] \)\|\(__crc_\)' > $2 +$NM -n $1 | grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)' > $2
Signature · 4 lines
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial coreSam Ravnborg
AppliedRe: [PATCH] Fix ARM kernel build with permitted binutils versions
Quoted 11 lines · Russell King
Ok, here's the latest version of the patch, fixing all presently known issues with ARM binutils post 2.11.90 by changing the kernel to suit.
Yes, it sounds like the wrong thing to do, but shrug.
---
All ARM binutils versions post 2.11.90 contains an extra "feature" which interferes with the kernel in various ways - extra "mapping symbols" in the ELF symbol table '$a', '$t' and '$d'. This causes two problems:
Quoted 7 lines
1. Since '$a' symbols have the same value as function names, this causes anything which uses the kallsyms infrastructure to report wrong values.
2. programs which parse System.map do not expect symbols to start with '$'.Signed-off-by Russell King <[email protected]>
Applied to my tree. Will send onwards to Linus soon.
Sam
Quoted 84 lines
=====
kernel/module.c1.120 vs edited =====kernel/module.c +14
-2@@ -1903,6 +1903,16 @@ }#ifdef CONFIG_KALLSYMS +/* +* This ignores the intensely annoying "mapping symbols" found +* in ARM ELF files: $a, $t and $d. +*/ +static inline int is_arm_mapping_symbol (const char *str) +{ +return str[0 ] =='$' &&strchr ("atd" , str[1 ]) + && (str[2 ] =='\0' || str[2 ] =='.' ); +} + static const char *get_ksymbol(struct module *mod, unsigned long addr, unsigned long *size,@@ -1927,11 +1937,13 @@* and inserted at a whim. */ if (mod->symtab[i].st_value <= addr && mod->symtab[i].st_value > mod->symtab[best].st_value - && *(mod->strtab + mod->symtab[i].st_name) !='\0' ) + && *(mod->strtab + mod->symtab[i].st_name) !='\0' + && !is_arm_mapping_symbol (mod->strtab + mod->symtab[i].st_name)) best = i;if (mod->symtab[i].st_value > addr && mod->symtab[i].st_value < nextval - && *(mod->strtab + mod->symtab[i].st_name) !='\0' ) + && *(mod->strtab + mod->symtab[i].st_name) !='\0' + && !is_arm_mapping_symbol (mod->strtab + mod->symtab[i].st_name)) nextval = mod->symtab[i].st_value; }=====
scripts/kallsyms.c1.12 vs edited =====scripts/kallsyms.c +13
-1@@ -32,6 +32,17 @@exit (1 ); } +/* +* This ignores the intensely annoying "mapping symbols" found +* in ARM ELF files: $a, $t and $d. +*/ +static inline int +is_arm_mapping_symbol (const char *str) +{ +return str[0 ] =='$' &&strchr ("atd" , str[1 ]) + && (str[2 ] =='\0' || str[2 ] =='.' ); +} +static int read_symbol (FILE *in,struct sym_entry *s) {@@ -56,7 +67,8 @@ _sinittext = s->addr; else if (strcmp(str, "_einittext") == 0) _einittext = s->addr; - else if (toupper(s->type) == 'A' || toupper(s->type) == 'U') + else if (toupper(s->type) == 'A' || toupper(s->type) == 'U' || + is_arm_mapping_symbol(str))return -1 ; s->sym =strdup (str);=====
scripts/mksysmap1.4 vs edited =====scripts/mksysmap +1
-1@@ -40,5 +40,5 @@ # so we just ignore them to let readprofile continue to work. # (At least sparc64 has __crc_ in the middle). -$NM -n $1 | grep -v '\( [aUw] \)\|\(__crc_\)' > $2 +$NM -n $1 | grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)' > $2Signature · 5 lines
-- Russell King Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/ maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/ 2.6 Serial core