#!/usr/bin/perl
# Bloat-O-Meter (c) 1997 by Andi Kleen
# released under the GNU public license v2
# f1 and f2 are either nm --size-sort -t d x.o files or ELF executables/object files
# bugs: doesn't like duplicate symbol names

die "usage: $0 file1 file2\n" if $#ARGV < 1 || $#ARGV>2;

open(F1,"<$ARGV[0]") || die "cannot open $ARGV[0] ($!)\n";
open(F2,"<$ARGV[1]") || die "cannot open $ARGV[1] ($!)\n";

&checkelf;

$= = 0; 
while (<F1>) {
	($size, $type, $name) = split;
	if ($type !~ /[tT]/)  { next; }
	$size =~ s/^0+//;
	$t1{$name} = $size;
}
while(<F2>) {
	($size, $type, $name) = split;
	next if $type !~ /[tT]/;
	$size =~ s/^0+//;
	if (defined $t1{$name}) {
		$olds=$t1{$name}; 
		delete $t1{$name};

		next if $olds == $size;   # only changed sizes

		$delta = $size-$olds;
		$change = (($size-$old)/($olds == 0 ? 1 : $olds))*100-100;
		$change = sprintf("%+.2f", $change);
	} else {
		$olds = "(new)";
		$delta = $size;
		$change = "";
	}
	write;
	$- = 10;
}
$change="";
foreach $name (keys %t1) {
	$olds = $t1{$name};
	$delta = -$olds;
	$size = "(del)";
	write;
	$- = 10;
}

format STDOUT_TOP =
Symbol                         Old size  New size  Delta     Change (%)
.

format STDOUT = 
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>  @>>>>>> @>>>>>>  @>>>>>>
$name                          $olds     $size     $delta   $change
.


sub checkelf {
	if (read(F1,$b,4) == 4 && $b eq "\177ELF") {
		close F1;
		open(F1,"nm --size-sort -t d $ARGV[0] |") || 
			die "cannot run nm on ARGV[0] ($!)\n";
	} else { seek F1,0,0; }
	if (read(F2,$b,4) == 4 && $b eq "\177ELF") {
		close F2;
		open(F2,"nm --size-sort -t d $ARGV[1] |") || 
			die "cannot run nm on ARGV[1] ($!)\n"; 
	} else { seek F2,0,0; }
}
