aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>2010-11-25 18:16:57 +0000
committerRainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>2010-11-25 18:16:57 +0000
commit88d9be5af58c642648dc6a6e04e47d382f759618 (patch)
treed60a8f039415ca3d7441c0fa3b38d2ef4766be7a
parent0970375132ac79f5c753629232628c548fbc2aee (diff)
* make_sunver.pl: Use elfdump -s to extract symbols if possible,
readelf -s otherwise. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@167149 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--contrib/ChangeLog5
-rw-r--r--contrib/make_sunver.pl124
2 files changed, 101 insertions, 28 deletions
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index 61478153915..1737cc8d264 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,8 @@
+2010-11-25 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * make_sunver.pl: Use elfdump -s to extract symbols if possible,
+ readelf -s otherwise.
+
2010-11-08 Eric Botcazou <ebotcazou@adacore.com>
* make_sunver.pl: Ignore entries without symbol name first. Then do
diff --git a/contrib/make_sunver.pl b/contrib/make_sunver.pl
index bb45004c283..b3abd8addac 100644
--- a/contrib/make_sunver.pl
+++ b/contrib/make_sunver.pl
@@ -12,8 +12,7 @@
# A comment with the original pattern and its type is left in the output
# file to make it easy to understand the matches.
#
-# It expects a 'nm' with the POSIX '-P' option, but everyone has one of
-# those, right?
+# It uses elfdump when present (native), GNU readelf otherwise.
# It depends on the GNU version of c++filt, since it must understand the
# GNU mangling style.
@@ -46,35 +45,104 @@ foreach $file (@ARGV) {
}
}
-# The nm command to use.
-my $nm = $ENV{'NM_FOR_TARGET'} || "nm";
+# We need to detect and ignore hidden symbols. Solaris nm can only detect
+# this in the harder to parse default output format, and GNU nm not at all,
+# so use elfdump -s in the native case and GNU readelf -s otherwise.
+# GNU objdump -t cannot be used since it produces a variable number of
+# columns.
-# Process each symbol.
-open NM,$nm.' -P '.(join ' ',@OBJECTS).'|' or die $!;
-while (<NM>) {
- my $i;
- chomp;
+# The path to elfdump.
+my $elfdump = "/usr/ccs/bin/elfdump";
+
+if (-f $elfdump) {
+ open ELFDUMP,$elfdump.' -s '.(join ' ',@OBJECTS).'|' or die $!;
+ my $skip_arsym = 0;
+
+ while (<ELFDUMP>) {
+ chomp;
+
+ # Ignore empty lines.
+ if (/^$/) {
+ # End of archive symbol table, stop skipping.
+ $skip_arsym = 0 if $skip_arsym;
+ next;
+ }
+
+ # Keep skipping until end of archive symbol table.
+ next if ($skip_arsym);
+
+ # Ignore object name header for individual objects and archives.
+ next if (/:$/);
+
+ # Ignore table header lines.
+ next if (/^Symbol Table Section:/);
+ next if (/index.*value.*size/);
- # nm prints out stuff at the start, ignore it.
- next if (/^$/);
- next if (/:$/);
- # Ignore entries without symbol name. Sun nm emits those for local, .bss
- # or scratch register (SPARC only) symbols for example.
- next if (/^ /);
- # Ignore undefined and local symbols.
- next if (/^[^ ]+[ \t]+[Ua-z][ \t]+/);
- # Ignore objects without symbol table. Message goes to stdout with Sun
- # nm, while GNU nm emits the corresponding message to stderr.
- next if (/.* - No symbol table data/);
-
- # $sym is the name of the symbol.
- die "unknown nm output $_" if (! /^([^ ]+)[ \t]+[A-Z][ \t]+/);
- my $sym = $1;
-
- # Remember symbol.
- $sym_hash{$sym}++;
+ # Start of archive symbol table: start skipping.
+ if (/^Symbol Table: \(archive/) {
+ $skip_arsym = 1;
+ next;
+ }
+
+ # Split table.
+ (undef, undef, undef, undef, $bind, $oth, undef, $shndx, $name) = split;
+
+ # Error out for unknown input.
+ die "unknown input line:\n$_" unless defined($bind);
+
+ # Ignore local symbols.
+ next if ($bind eq "LOCL");
+ # Ignore hidden symbols.
+ next if ($oth eq "H");
+ # Ignore undefined symbols.
+ next if ($shndx eq "UNDEF");
+ # Error out for unhandled cases.
+ if ($bind !~ /^(GLOB|WEAK)/ or $oth ne "D") {
+ die "unhandled symbol:\n$_";
+ }
+
+ # Remember symbol.
+ $sym_hash{$name}++;
+ }
+ close ELFDUMP or die "$elfdump error";
+} else {
+ open READELF, 'readelf -s -W '.(join ' ',@OBJECTS).'|' or die $!;
+ # Process each symbol.
+ while (<READELF>) {
+ chomp;
+
+ # Ignore empty lines.
+ next if (/^$/);
+
+ # Ignore object name header.
+ next if (/^File: .*$/);
+
+ # Ignore table header lines.
+ next if (/^Symbol table.*contains.*:/);
+ next if (/Num:.*Value.*Size/);
+
+ # Split table.
+ (undef, undef, undef, undef, $bind, $vis, $ndx, $name) = split;
+
+ # Error out for unknown input.
+ die "unknown input line:\n$_" unless defined($bind);
+
+ # Ignore local symbols.
+ next if ($bind eq "LOCAL");
+ # Ignore hidden symbols.
+ next if ($vis eq "HIDDEN");
+ # Ignore undefined symbols.
+ next if ($ndx eq "UND");
+ # Error out for unhandled cases.
+ if ($bind !~ /^(GLOBAL|WEAK)/ or $vis ne "DEFAULT") {
+ die "unhandled symbol:\n$_";
+ }
+
+ # Remember symbol.
+ $sym_hash{$name}++;
+ }
+ close READELF or die "readelf error";
}
-close NM or die "nm error";
##########
# The various types of glob patterns.