bc4c2098a6
Reading stdin is confusing as it means running the script without any arguments and with no input redirection just seems to do nothing. (OTOH, who would use this script except seasoned hackers who know how command-line tools typically work... oh well.) Change-Id: I00b4f70b07b6515b52a22b4ec4e048cc84c1dc83
78 lines
2.2 KiB
Perl
Executable file
78 lines
2.2 KiB
Perl
Executable file
#!/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";
|
|
}
|
|
}
|
|
|