summaryrefslogtreecommitdiff
path: root/cesar/common/tools/lram-size
blob: 6f0ffe362f3669f4205c70de05f79fa2067d1ab7 (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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long qw(:config no_ignore_case bundling);
use Pod::Usage;

# Option parsing.
my $help;
my $details;
my $total;
my $total_stderr;
my $prefix = 'sparc-elf-';
my @rams;
my $nocheck = 0;
GetOptions (
    'help|h' => \$help,
    'details|d' => \$details,
    'total|t' => \$total,
    'total-stderr' => \$total_stderr,
    'prefix|p=s' => \$prefix,
    'ram|r=s' => \@rams,
    'no-check' => \$nocheck,
) or pod2usage (2);
pod2usage (1) if $help;
@ARGV == 1 or pod2usage (2);
$details or $total or $total_stderr or pod2usage (2);
@rams = qw(ilram dlram_data dlram_bss) unless @rams;

my $file = shift @ARGV;

if ($details)
{
    # Memories hashes.
    my %rams;
    $rams{$_} = { } for @rams;

    # Eat file into memory.
    open F, "${prefix}objdump -t $file|"
	or die "can not read symbols: $!, stopping";
    while (<F>)
    {
	if (/^[[:xdigit:]]{8} .{7} \.(\S+)\t([[:xdigit:]]{8}) ([^.].*)/)
	{
	    my ($ram, $size, $name) = ($1, hex ($2), $3);
	    next unless exists $rams{$ram};
	    exists $rams{$ram}->{$name} and die;
	    $rams{$ram}->{$name} = $size;
	}
    }
    close F;

    # Dump.
    for my $ram (@rams)
    {
	my $size = 0;
	my $d = $rams{$ram};
	print "$ram:\n";
	my @okeys = sort { $d->{$b} <=> $d->{$a} } keys %$d;
	for (@okeys)
	{
	    printf "%8d  $_\n", $d->{$_};
	    $size += $d->{$_};
	}
	#printf "%8d  total\n", $size
    }
}

if ($total || $total_stderr)
{
    # Memories hash.
    my %rams;
    $rams{$_} = 0 for @rams;

    # Eat file into memory.
    open F, "${prefix}size -A $file|"
	or die "can not read size: $!, stopping";
    while (<F>)
    {
	if (/^\.(\S+)\s*(\d+)/)
	{
	    my ($ram, $size) = ($1, $2);
	    next unless exists $rams{$ram};
	    $rams{$ram} != 0 and die;
	    $rams{$ram} = $size;
	}
    }
    close F;

    # Dump.
    my @o = map { "$_: " . $rams{$_} } @rams;
    my $o = join (', ', @o) . "\n";
    print $o if $total;
    print STDERR $o if $total_stderr;

    # Check memory size.
    if (!$nocheck)
    {
	exists $rams{'ilram'} && $rams{'ilram'} > 32 * 1024
	    and die "ERROR: ilram too big.\n";
	exists $rams{'dlram_data'} && exists $rams{'dlram_bss'}
	&& $rams{'dlram_data'} + $rams{'dlram_bss'} > 16 * 1024
	    and die "ERROR: dlram too big.\n";
    }
}

__END__

=head1 NAME

lram-size - print local ram usage.

=head1 SYNOPSIS

lram-size [options] file.elf

 Options:
   -h, --help		brief help message
   -d, --details	print detailed section usage
   -t, --total		print total section size
   --total-stderr	print total on standard error output
   -p, --prefix=PREFIX  compiler prefix
   -r, --ram=RAM	include specified RAM
   --no-check		do not check ram size

=cut