| #!/usr/bin/perl -w |
| |
| use strict; |
| |
| use Getopt::Std; |
| $Getopt::Std::STANDARD_HELP_VERSION++; |
| |
| my %args; |
| |
| getopts('f:s', \%args); |
| |
| sub VERSION_MESSAGE { |
| # Nothing |
| } |
| |
| sub HELP_MESSAGE { |
| print <<EOS |
| This program parses a linker map file, especially one produced when linking an iOS executable. |
| |
| Input is read from a map file provided as command-line argument |
| |
| By default a list of libraries used and the size of code and data |
| linked in from each library is printed, in reverse order of size. |
| |
| The following options are available: |
| -s Print a list of symbols instead. |
| -f 'filter' Filter which libraries are handled. The filter can be |
| a regular expression, typically several library names |
| combined with the '|' operator. Makes sense only when |
| -s is used too. |
| EOS |
| } |
| |
| die "The -f switch makes sense only if -s is also used\n" if defined($args{'f'}) && !defined($args{'s'}); |
| |
| die "Please provide one map file name\n" if !defined($ARGV[0]); |
| |
| die "Just one argument please\n" if defined($ARGV[1]); |
| |
| my $state = 0; |
| my %libofnumber; |
| my %sizeoflib; |
| my %sizeofsym; |
| |
| open(INPUT, '<', $ARGV[0]) || die "Could not open $ARGV[0]: $!\n"; |
| |
| while (<INPUT>) { |
| if ($state == 0 && m!^# Object files:!) { |
| $state = 1; |
| } elsif ($state == 1 && m!^\[ *([0-9]+)\] .*/([-_a-z0-9]+\.a)\(.*!i) { |
| $libofnumber{$1} = $2; |
| } elsif ($state == 1 && m!^# Sections:!) { |
| $state = 2; |
| } elsif ($state == 2 && m!^# Address\s+Size\s+File\s+Name!) { |
| $state = 3; |
| } elsif ($state == 3 && m!^0x[0-9A-F]+\s+(0x[0-9A-F]+)\s+\[ *([0-9]+)\] (.*)!) { |
| my ($size,$libnum,$symbol) = ($1, $2, $3); |
| if (defined($libofnumber{$libnum})) { |
| $sizeoflib{$libofnumber{$libnum}} += hex($size); |
| if (!defined($args{'f'}) || $libofnumber{$libnum} =~ /$args{'f'}/) { |
| $sizeofsym{$symbol} = hex($size); |
| } |
| } |
| } |
| } |
| |
| if ($args{'s'}) { |
| # Print symbols in reverse size order |
| foreach (sort { $sizeofsym{$b} <=> $sizeofsym{$a} } keys(%sizeofsym)) { |
| print $_, ": ", $sizeofsym{$_}, "\n"; |
| } |
| } else { |
| # Print libraries in reverse size order |
| foreach (sort { $sizeoflib{$b} <=> $sizeoflib{$a} } keys(%sizeoflib)) { |
| print $_, ": ", $sizeoflib{$_}, "\n"; |
| } |
| } |
| |