Skip to contentSkip to conversation

ARM binutils feature churn causing kernel problems

RFC Applied Russell King 10 participants 28 messages Sep 27, 2004 – Oct 26, 2004 Kbuild

lore
Share & tools
lore
#0 lore raw

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 core
#1 lore raw
Quoted 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..

#2 lore raw
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 core
#3 lore raw
In reply to Christoph Hellwig
Quoted 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

#4 lore raw
In reply to Russell King
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 core
#5 lore raw

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).

Catalin

#6 lore raw
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
#7 lore raw
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/kallsyms but 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.

#8 lore raw
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/kallsyms but 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_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.

(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
diff -up -x BitKeeper -x ChangeSet -x SCCS -x _xlk -x *.orig -x *.rej orig/kernel/module.c linux/kernel/module.c
@@ -1923,6 +1923,10 @@ static const char *get_ksymbol(struct mo
 		if (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
diff -up -x BitKeeper -x ChangeSet -x SCCS -x _xlk -x *.orig -x *.rej orig/scripts/kallsyms.c linux/scripts/kallsyms.c
@@ -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 core
#9 lore raw
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/kallsyms but 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_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.

(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 *.rej orig/kernel/module.c linux/kernel/module.c

kernel/module.c +4 -0
@@ -1923,6 +1923,10 @@ static const char *get_ksymbol(struct mo
 		if (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

diff -up -x BitKeeper -x ChangeSet -x SCCS -x _xlk -x *.orig -x *.rej orig/scripts/kallsyms.c linux/scripts/kallsyms.c

scripts/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.
----------------------------------------------------------------
#10 lore raw
Quoted 31 lines · Richard Earnshaw
Quoted 30 lines · Russell King

diff -up -x BitKeeper -x ChangeSet -x SCCS -x _xlk -x *.orig -x *.rej orig/scripts/kallsyms.c linux/scripts/kallsyms.c

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;
 
Quoted 4 lines

scripts/kallsyms.c read_symbol(FILE *in, struct sym_entry * · line 74

Quoted 1 line
scripts/kallsyms.c +0 -0
 	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?

"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 core
#11 lore raw
Quoted 7 lines · Russell King
Quoted 2 lines

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?

"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.

#12 lore raw
Quoted 5 lines · Richard Earnshaw
Quoted 3 lines · Russell King
Quoted 2 lines

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?

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 core
#13 lore raw
Quoted 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.

#14 lore raw
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 core
#15 lore raw
In reply to Adrian Cox
Quoted 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.

#16 lore raw
In reply to Russell King
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_symbol and have it do the same thing as you've done in get_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 core
#17 lore raw
In reply to Russell King
Quoted 7 lines · Russell King
Quoted 2 lines · Richard Earnshaw

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?

"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
#18 lore raw
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_symbol and have it do the same thing as you've done in get_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
#19 lore raw
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 core
#20 lore raw
Quoted 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.transaction
c01b1db3 t .text.lock.checkpoint
...
c03c7708 r single_rates.0
c03c7714 r double_rate_channels.1
...
c0482280 d get_s16_labels.0
c04822c0 d put_s16_labels.1
c0482300 d get_s16_labels.2
c0482340 d put_s16_labels.3
...
c053d780 b nulldevname.1
c053d800 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
#21 lore raw
In reply to Russell King

[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/kallsyms but 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_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.

(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 *.rej orig/kernel/module.c linux/kernel/module.c

kernel/module.c +4 -0
@@ -1923,6 +1923,10 @@ static const char *get_ksymbol(struct mo
 		if (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

diff -up -x BitKeeper -x ChangeSet -x SCCS -x _xlk -x *.orig -x *.rej orig/scripts/kallsyms.c linux/scripts/kallsyms.c

scripts/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.

#22 lore raw
In reply to 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".

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 core
#23 lore raw
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

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
#24 lore raw
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.

#25 lore raw
Quoted 11 lines · Albert Cahalan

....

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;
  }
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
#26 lore raw

PATCH 1/1 Fix ARM kernel build with permitted binutils versions

In reply to 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:

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 core
Applied
#27 lore raw

Re: [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 '$'.

Applied to my tree. Will send onwards to Linus soon.

Sam

Quoted 84 lines

===== 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 · 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