summaryrefslogtreecommitdiff
path: root/bin/ios-mapfile-statistics
blob: 07f3f0aa68b4378c0fea397e537b3d165022474c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#!/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";
  }
}