source: branches/gcc/UNIT_TESTER/filter_objdump_syms.pl

Last change on this file was 19810, checked in by westram, 3 weeks ago
  • Property svn:executable set to *
File size: 5.1 KB
Line 
1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
6# This script is called from ./make_symlist.sh@filter_objdump_syms
7#
8# For help on filtered format see .man objdump under '--syms'
9
10my $show_converted = 1; # 1=result, 0=leftover(debug)
11my $ENDIE = "\n "; # print error location, but in new line
12
13sub list_symbol($$$) {
14  my ($state, $type, $symbol) = @_;
15  # $state: 'ref' = refer symbol
16  #         'def' = define symbol
17  # $type:  'sub' = subroutine
18  #         'var' = variable
19  #         'unk' = unknown ('ref' is always unknown)
20  # $symbol: prototype or variable name
21  #
22  # see also ./make_symlist.sh@SYMLIST_FORMAT
23
24  if ($symbol =~ /;/) {
25    die "unexpected ';' contained in demangled symbol '$symbol'".$ENDIE;
26  }
27  if ($state eq 'def') {
28    if ($type ne 'sub' and $type ne 'var') {
29      die "unexpected type='$type' when defining symbol '$symbol'".$ENDIE;
30    }
31  }
32  if ($show_converted==1) {
33    print $state.';'.$type.';'.$symbol."\n";
34  }
35}
36
37my $reg_objdump_symbol_linestart = qr/^([0-9a-f]+)\s([a-zA-Z !]{7})\s/o;
38my $reg_symrest_lineend_elf = qr/^([^\s]+)\s([0-9a-f]+)\s+(.*)$/o;
39my $reg_symrest_lineend_osx = qr/^([^\s]+)\s(.*)$/o;
40my $reg_file_header = qr/^([^:]+):\s+(.*)$/o;
41
42my %symbol_seen = ();
43
44sub main() {
45  my $style = undef;
46
47 LINE: while (defined ($_=<STDIN>)) {
48    # if ($_ =~ $reg_objdump_elf_line) {
49    if ($_ =~ $reg_objdump_symbol_linestart) {
50      my ($addr, $flags, $rest) = ($1, $2, $');
51      my ($section, $symbol) = (undef, undef);
52
53      my $thisStyle = undef;
54      if ($rest =~ $reg_symrest_lineend_elf) {
55        ($section, $symbol) = ($1, $3);
56        $thisStyle = 'ELF';
57      }
58      elsif ($rest =~ $reg_symrest_lineend_osx) {
59        ($section, $symbol) = ($1, $2);
60        if ($symbol =~ /^\.hidden\s/o) { $symbol = $'; }
61        $thisStyle = 'MACHO';
62      }
63      else {
64        die "unexpected rest='$rest' in line: $_".$ENDIE;
65      }
66
67      if (defined $style) {
68        if ($thisStyle ne $style) {
69          die "objdump style change detected: $style -> $thisStyle (parser is broken)".$ENDIE;
70        }
71      }
72      else {
73        $style = $thisStyle;
74      }
75
76      # exclude useless symbols:
77      if ($symbol =~ /^non-virtual thunk to /o) {
78        next LINE;
79      }
80
81      if ($section eq '*UND*') {
82        if ($symbol =~ /;/) { die "unexpected ';' contained in demangled symbol '$symbol'".$ENDIE; }
83        list_symbol('ref', 'unk', $symbol); # references are stored with unknown type here
84      }
85      else {
86        my $scope = substr($flags, 0, 1); # l=local, g=global, u=unique-global(gnu), !=broken, ' '=no-scope
87        if ($scope   =~ /[ug]/o) {
88          my $type = substr($flags, 6, 1);  # 'F'=function, 'f'=file, 'o'=object, ' '=normal
89
90          if ($type eq 'F') { # function
91            my $suppress = 0;
92            if (exists $symbol_seen{$symbol}) {
93              # duplicated symbol - accept only for ctors and dtors. no idea why these are duplicated.
94              if ($symbol =~ /\(/o) {
95                my ($name, $params) = ($`, $&.$');
96                my @namepart = split /::/, $name;
97                my $parts = scalar(@namepart);
98                if ($parts>=2) {
99                  my ($class, $method) = @namepart[$parts-2, $parts-1];
100                  if (($class eq $method) or ($method eq '~'.$class)) { $suppress = 1; }
101                  else { print STDERR "Warning: not ctor/dtor: class='$class' method='$method'\n"; }
102                }
103                else { print STDERR "Warning: non-class function\n"; }
104              }
105              else { print STDERR "Warning: function w/o parenthesis\n"; }
106              if ($suppress==0) { die "detected duplicated symbol '$symbol'".$ENDIE; }
107            }
108            else { $symbol_seen{$symbol} = 1; }
109            if ($suppress==0) { list_symbol('def', 'sub', $symbol); }
110          }
111          elsif ($type =~ /[O]/o) {
112            if (($scope eq 'g') and (($section eq '.data') or ($section eq '.bss'))) {
113              list_symbol('def', 'var', $symbol);
114            }
115          }
116          elsif (($scope eq 'g') and (($section eq '.data') or ($section eq '.bss'))) {
117            # silently accept some symbols occurring in dynamic libraries
118            # (only occur in libCORE, libARBDB and libWINDOW; but neighter in libglAW nor in libglpng_arb)
119          }
120          else {
121            if ($show_converted==0) { print $_; }
122            else {
123              die "unexpected line: $_".$ENDIE;
124              # If this fails, set show_converted=0 => prints non-converted lines.
125              # Decide whether to suppress or convert..
126            }
127          }
128        }
129      }
130    }
131    else {
132      chomp;
133      if (/./o) {
134        if ($_ =~ $reg_file_header) {
135          # print "matched reg_file_header: $_\n";
136          ;
137        }
138        elsif (/:$/o) {
139          my $b4 = $`;
140          if (($b4 eq 'SYMBOL TABLE') or
141              ($b4 =~ /^In\sarchive\s.*$/o)) {
142            ;
143          }
144          else {
145              die "can't parse line '$_'".$ENDIE;
146          }
147        }
148        else {
149          die "can't parse line '$_'".$ENDIE;
150          # may be caused by non-ELF-object.
151        }
152      }
153    }
154  }
155}
156
157eval { main(); };
158if ($@) { die "filter_objdump_syms.pl: Error: $@\n"; }
Note: See TracBrowser for help on using the repository browser.