summaryrefslogtreecommitdiffstats
path: root/tools/ocamlsize
blob: 659543d5930c7c17caec67425fd252316468cf6b (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
#!/usr/bin/perl

foreach $f (@ARGV) {
    open(FILE, $f) || die("Cannot open $f");
    seek(FILE, -16, 2);
    $num_sections = do read_int();
    read(FILE, $magic, 12);
    seek(FILE, -16 - 8 * $num_sections, 2);
    @secname = ();
    @seclength = ();
    %length = ();
    for ($i = 0; $i < $num_sections; $i++) {
        read(FILE, $sec, 4);
        $secname[$i] = $sec;
        $seclength[$i] = do read_int();
        $length{$sec} = $seclength[$i];
    }
    print $f, ":\n" if ($#ARGV > 0);
    $path =
        $length{'RNTM'} > 0 ?
            do read_section('RNTM') :
            "(default runtime)\n";
    printf ("\tcode: %-7d data: %-7d symbols: %-7d debug: %-7d\n",
            $length{'CODE'}, $length{'DATA'},
            $length{'SYMB'}, $length{'DBUG'});
    printf ("\tmagic number: %s  runtime system: %s",
            $magic, $path);
    close(FILE);
}

sub read_int {
    read(FILE, $buff, 4) == 4 || die("Truncated bytecode file $f");
    @int = unpack("C4", $buff);
    return ($int[0] << 24) + ($int[1] << 16) + ($int[2] << 8) + $int[3];
}

sub read_section {
    local ($sec) = @_;
    local ($i, $ofs, $data);
    for ($i = $num_sections - 1; $i >= 0; $i--) {
        $ofs += $seclength[$i];
        if ($secname[$i] eq $sec) {
            seek(FILE, -16 - 8 * $num_sections - $ofs, 2);
            read(FILE, $data, $seclength[$i]);
            return $data;
        }
    }
    return '';
}