Greg Hartman | 76d05dc | 2016-11-23 15:51:27 -0800 | [diff] [blame] | 1 | #!/usr/bin/perl -w |
| 2 | |
| 3 | use strict; |
| 4 | use warnings; |
| 5 | |
| 6 | # Sort the symbol table portion of the output of objdump -ht by |
| 7 | # section, then by symbol value, then by size. Used to enhance the |
| 8 | # linker maps produced by "make bin/%.map" by also showing the values |
| 9 | # of all non-global symbols. |
| 10 | |
| 11 | my %section_idx = ( "*ABS*" => ".", "*UND*" => "_" ); |
| 12 | my %lines; |
| 13 | while ( <> ) { |
| 14 | if ( /^\s+(\d+)\s+([\.\*]\S+)\s+[0-9a-fA-F]+\s+[0-9a-fA-F]/ ) { |
| 15 | # It's a header line containing a section definition; extract the |
| 16 | # section index and store it. Also print the header line. |
| 17 | print; |
| 18 | ( my $index, my $section ) = ( $1, $2 ); |
| 19 | $section_idx{$section} = sprintf ( "%02d", $index ); |
| 20 | } elsif ( /^([0-9a-fA-F]+)\s.*?\s([\.\*]\S+)\s+([0-9a-fA-F]+)\s+(\S+)/ ) { |
| 21 | # It's a symbol line - store it in the hash, indexed by |
| 22 | # "<section_index>:<value>:<size>:<end_tag>". <end_tag> is "0" if |
| 23 | # the symbol name is of the form xxx_end, "1" otherwise; this is |
| 24 | # done so that table end markers show up before any other symbols |
| 25 | # with the same value. |
| 26 | ( my $value, my $section, my $size, my $name ) = ( $1, $2, $3, $4 ); |
| 27 | die "Unrecognised section \"$section\"\n" |
| 28 | unless exists $section_idx{$section}; |
| 29 | my $section_idx = $section_idx{$section}; |
| 30 | my $end = ( $name =~ /_end$/ ) ? "0" : "1"; |
| 31 | my $key = $section_idx.":".$value.":".$size.":".$end; |
| 32 | $lines{$key} ||= ''; |
| 33 | $lines{$key} .= $_; |
| 34 | } else { |
| 35 | # It's a generic header line: just print it. |
| 36 | print; |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | print $lines{$_} foreach sort keys %lines; |