Google luky.org euqset.org

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: sh: inconsistent kallsyms data


On Fri, 31 Dec 2004 19:25:50 +0200, 
Paul Mundt <lethal@xxxxxxxxxxxx> wrote:
>Building 2.6.10 for sh results in inconsistent kallsyms data. Turning on
>CONFIG_KALLSYMS_ALL fixes it, as does CONFIG_KALLSYMS_EXTRA_PASS.
>
>The symbols that seem to be problematic between the second and third
>pass are all kallsyms special symbols. With only CONFIG_KALLSYMS set we
>see:
>
>--- System.map  2004-12-31 10:53:10.278567522 -0600
>+++ .tmp_System.map     2004-12-31 10:53:10.347558024 -0600
>@@ -6868,9 +6868,9 @@
> 8817c4d0 D kallsyms_addresses
> 88182660 D kallsyms_num_syms
> 88182670 D kallsyms_names
>-88190630 D kallsyms_markers
>-881906a0 D kallsyms_token_table
>-88190b50 D kallsyms_token_index
>+881906a0 D kallsyms_markers
>+88190710 D kallsyms_token_table
>+88190bc0 D kallsyms_token_index
> 88191000 D irq_desc
> 88191000 A __per_cpu_end
> 88191000 A __per_cpu_start
>
>So for some reason we have a 0x70 variance between these, and only
>these. Running with --all-symbols this seems to work fine.

It is a nasty corner case in scripts/kallsyms.c processing.  There is a
difference in the list of names between pass 1 and pass 2.  This is not
supposed to happen, the name and compression tables must be the same
after pass 1 and 2.  The symbol addresses will be different, but the
amount of data must be the same.

--- out1        2005-01-01 14:30:30.192497864 +1100
+++ out2        2005-01-01 14:30:46.556974017 +1100
@@ -5854,390 +5854,389 @@
 r __param_yres         PTR     0x8816d300
 r __param_xres         PTR     0x8816d314
 A _etext       PTR     0x8816d328
-D init_task    PTR     0x8816d328
 R __stop___param       PTR     0x8816d328

In pass 1, init_task has the same value as _etext so it is included in
the name table.  Adding the kallsyms data to vmlinux at the end of pass
1 adds more data which shifts where init_task is linked so it is no
longer the same as _etext, so we lose a symbol on pass 2 which breaks
the kallsyms rules.

This corner case only occurs with CONFIG_KALLSYMS_ALL=n.  That is the
only time that we drop symbols outside the ranges _stext ... _etext and
_sinittext ... _einittext.  For CONFIG_KALLSYMS_ALL=n, we want the
_etext and _einittext labels, but not any other symbols that have the
same numeric value as _etext or _einittext.

Paul, please test this patch.  Build with CONFIG_KALLSYMS_ALL=n and
CONFIG_KALLSYMS_EXTRA_PASS=n.

Index: 2.6.10/scripts/kallsyms.c
===================================================================
--- 2.6.10.orig/scripts/kallsyms.c	2005-01-01 14:24:21.240400295 +1100
+++ 2.6.10/scripts/kallsyms.c	2005-01-01 14:54:57.695169107 +1100
@@ -184,6 +184,16 @@ symbol_valid(struct sym_entry *s)
 		if ((s->addr < _stext || s->addr > _etext)
 		    && (s->addr < _sinittext || s->addr > _einittext))
 			return 0;
+		/* Corner case.  Discard any symbols with the same value as
+		 * _etext or _einittext, they can move between pass 1 and 2
+		 * when the kallsyms data is added.  If these symbols move then
+		 * they may get dropped in pass 2, which breaks the kallsyms
+		 * rules.
+		 */
+		if ((s->addr == _etext || s->addr == _einittext) &&
+		    strcmp(s->sym + 1, "_etext") &&
+		    strcmp(s->sym + 1, "_einittext"))
+			return 0;
 	}
 
 	/* Exclude symbols which vary between passes. */


BTW, this script will take a .tmp_kallsyms<n>.S file and convert the
tables to something that a human can read.

#!/usr/bin/perl -w
#
# kallsyms_uncompress.pl (C) Keith Owens 2005 <kaos@xxxxxxxxxx>
#
# Released under GPL V2.
#
# Uncompress the names in a .tmp_kallsymsn.S file.  Humans need text strings
# to work out why kallsyms is giving inconsistent results.  Use on 2.6.10
# onwards.
# kallsyms_uncompress.pl .tmp_kallsymsn.S > outfile

use strict;
die($0 . " takes exactly one argument\n") if($#ARGV != 0);

my @token;
my @name;
my @ptr;

my $line;
my $state = 0;	# 1 token, 2 name, 3 ptr

while (defined ($line = <>)) {
	chomp($line);
	if ($line eq "kallsyms_token_table:") {
		$state = 1;
		next;
	}
	if ($line eq "kallsyms_names:") {
		$state = 2;
		next;
	}
	if ($line eq "kallsyms_addresses:") {
		$state = 3;
		next;
	}
	next if ($state == 0);
	if ($line eq "") {
		$state = 0;
		next;
	}
	if ($state == 1) {
		$line =~ s/[^"]*"//;
		$line =~ s/"//;
		push(@token, $line);
	} elsif ($state == 2) {
		$line =~ s/\s//g;
		my @b = (split(/,/, $line));
		shift(@b);
		push(@name, \@b);
	} else {
		push(@ptr, $line);
	}
}

my ($b, $i, $text);
for ($i = 0; $i <= $#name; ++$i) {
	$text = "";
	foreach $b (@{$name[$i]}) {
		$text .= $token[hex($b)];
	}
	printf("%s %s %s\n", substr($text, 0, 1), substr($text, 1), $ptr[$i]);
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


$B$3$N>pJs$,$"$J$?$NC5$7$F$$?$b$N$+$I$&$+A*Br$7$F$/$@$5$!#(B
yes/$B$^$5$K$3$l$@!*(B   no/$B0c$&$J$!(B   part/$B0lIt8+$D$+$C$?(B   try/$B$3$l$G;n$7$F$_$k(B

$B$"$J$?$,C5$7$F$$?>pJs$O$I$N$h$&$J$3$H$+!"$4<+M3$K5-F~2<$5$!#FC$K!V$^$5$K$3$l$@!*!W$H8@$&>l9g$O5-F~$r$*4j$$7$^$9!#(B
$BNc(B:$B!VJ#?t$N%^%7%s$+$i(BCATV$B7PM3$G(Bipmasquerade$B$rMxMQ$7$F(BWeb$B$r;2>H$7$?$>l9g$N@_Dj$K$D$$F!W(B
Follow-Ups: References: