1*9880d681SAndroid Build Coastguard Worker#!/usr/bin/perl 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Workeruse Getopt::Std; 4*9880d681SAndroid Build Coastguard Worker$DEBUG = 0; 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Workersub parse_objdump_file { 7*9880d681SAndroid Build Coastguard Worker my ($filename) = @_; 8*9880d681SAndroid Build Coastguard Worker my @result; 9*9880d681SAndroid Build Coastguard Worker open (INPUT, $filename) or die "$filename: $!\n"; 10*9880d681SAndroid Build Coastguard Worker print "opened objdump output file $filename\n" if $DEBUG; 11*9880d681SAndroid Build Coastguard Worker while (<INPUT>) { 12*9880d681SAndroid Build Coastguard Worker if (/\s*([0-9a-f]*):\t(([0-9a-f]{2} )+) *\t(.*)$/) { 13*9880d681SAndroid Build Coastguard Worker my ($addr, $bytes, $instr) = ($1, $2, $4); 14*9880d681SAndroid Build Coastguard Worker $addr = "0x" . $addr; 15*9880d681SAndroid Build Coastguard Worker $bytes =~ s/\s*(.*\S)\s*/$1/; # trim any remaining whitespace 16*9880d681SAndroid Build Coastguard Worker $instr =~ s/\s*(.*\S)\s*/$1/; 17*9880d681SAndroid Build Coastguard Worker push (@result, {'addr' => $addr, 'bytes' => $bytes, 'instr' => $instr}); 18*9880d681SAndroid Build Coastguard Worker print "addr=$addr bytes='$bytes' instr='$instr'\n" if $DEBUG; 19*9880d681SAndroid Build Coastguard Worker } 20*9880d681SAndroid Build Coastguard Worker } 21*9880d681SAndroid Build Coastguard Worker close INPUT; 22*9880d681SAndroid Build Coastguard Worker return @result; 23*9880d681SAndroid Build Coastguard Worker} 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Workersub parse_gdb_file { 26*9880d681SAndroid Build Coastguard Worker my ($filename) = @_; 27*9880d681SAndroid Build Coastguard Worker my @result; 28*9880d681SAndroid Build Coastguard Worker my $got_addr; 29*9880d681SAndroid Build Coastguard Worker open (INPUT, $filename) or die "$filename: $!\n"; 30*9880d681SAndroid Build Coastguard Worker print "opened gdb output file $filename\n" if $DEBUG; 31*9880d681SAndroid Build Coastguard Worker while (<INPUT>) { 32*9880d681SAndroid Build Coastguard Worker if (/^(0x[0-9a-f]*):\t([^\t]*)\t[^:]*:\t((0x[0-9a-f]{2}\s*)+)\s*$/) { 33*9880d681SAndroid Build Coastguard Worker my ($addr, $bytes, $instr) = ($1, $3, $2); 34*9880d681SAndroid Build Coastguard Worker $bytes =~ s/0x//g; 35*9880d681SAndroid Build Coastguard Worker $bytes =~ s/\s+/ /g; # regularize whitespace 36*9880d681SAndroid Build Coastguard Worker $bytes =~ s/\s*(.*\S)\s*/$1/; # trim any remaining whitespace 37*9880d681SAndroid Build Coastguard Worker $instr =~ s/\s*(.*\S)\s*/$1/; 38*9880d681SAndroid Build Coastguard Worker push (@result, {'addr' => $addr, 'bytes' => $bytes, 'instr' => $instr}); 39*9880d681SAndroid Build Coastguard Worker print "addr=$addr bytes='$bytes' instr='$instr'\n" if $DEBUG; 40*9880d681SAndroid Build Coastguard Worker } elsif (/^(0x[0-9a-f]*):\t$/) { # deal with gdb's line breaker 41*9880d681SAndroid Build Coastguard Worker $got_addr = $1; 42*9880d681SAndroid Build Coastguard Worker } elsif ($got_addr && /^ ([^\t]*)\t[^:]*:\t((0x[0-9a-f]{2}\s*)+)\s*$/) { 43*9880d681SAndroid Build Coastguard Worker my ($addr, $bytes, $instr) = ($got_addr, $2, $1); 44*9880d681SAndroid Build Coastguard Worker $bytes =~ s/0x//g; 45*9880d681SAndroid Build Coastguard Worker $bytes =~ s/\s+/ /g; # regularize whitespace 46*9880d681SAndroid Build Coastguard Worker $bytes =~ s/\s*(.*\S)\s*/$1/; # trim any remaining whitespace 47*9880d681SAndroid Build Coastguard Worker $instr =~ s/\s*(.*\S)\s*/$1/; 48*9880d681SAndroid Build Coastguard Worker push (@result, {'addr' => $addr, 'bytes' => $bytes, 'instr' => $instr}); 49*9880d681SAndroid Build Coastguard Worker print "addr=$addr bytes='$bytes' instr='$instr'\n" if $DEBUG; 50*9880d681SAndroid Build Coastguard Worker undef $got_addr; 51*9880d681SAndroid Build Coastguard Worker } 52*9880d681SAndroid Build Coastguard Worker } 53*9880d681SAndroid Build Coastguard Worker close INPUT; 54*9880d681SAndroid Build Coastguard Worker return @result; 55*9880d681SAndroid Build Coastguard Worker} 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Workersub binary_diffs { 58*9880d681SAndroid Build Coastguard Worker my ($objdump_file, $gdb_file) = @_; 59*9880d681SAndroid Build Coastguard Worker my @file1 = parse_objdump_file ($objdump_file); 60*9880d681SAndroid Build Coastguard Worker my @file2 = parse_gdb_file ($gdb_file); 61*9880d681SAndroid Build Coastguard Worker my $lastrecord = ($#file1 >= $#file2) ? ($#file1) : ($#file2); 62*9880d681SAndroid Build Coastguard Worker for (my $i = 0; $i <= $lastrecord; ++$i) { 63*9880d681SAndroid Build Coastguard Worker my $d1 = $file1[$i]; 64*9880d681SAndroid Build Coastguard Worker my $d2 = $file2[$i]; 65*9880d681SAndroid Build Coastguard Worker if ($d1->{'bytes'} ne $d2->{'bytes'}) { 66*9880d681SAndroid Build Coastguard Worker next if (($d1->{'instr'} eq $d2->{'instr'}) && $opt_d); 67*9880d681SAndroid Build Coastguard Worker printf "0x%08x:\t%30s \t%s\n", 0+$d1->{'addr'}, $d1->{'bytes'}, $d1->{'instr'}; 68*9880d681SAndroid Build Coastguard Worker printf "0x%08x:\t%30s \t%s\n\n", 0+$d2->{'addr'}, $d2->{'bytes'}, $d2->{'instr'}; 69*9880d681SAndroid Build Coastguard Worker } 70*9880d681SAndroid Build Coastguard Worker } 71*9880d681SAndroid Build Coastguard Worker} 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Worker&getopts('d'); 74*9880d681SAndroid Build Coastguard Worker$objdump_file = $ARGV[0]; 75*9880d681SAndroid Build Coastguard Worker$gdb_file = $ARGV[1]; 76*9880d681SAndroid Build Coastguard Workerbinary_diffs ($objdump_file, $gdb_file); 77*9880d681SAndroid Build Coastguard Workerexit (0); 78*9880d681SAndroid Build Coastguard Worker__END__ 79*9880d681SAndroid Build Coastguard Worker=pod 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Worker=head1 NAME 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Workercodegen-diff 84*9880d681SAndroid Build Coastguard Worker 85*9880d681SAndroid Build Coastguard Worker=head1 SYNOPSIS 86*9880d681SAndroid Build Coastguard Worker 87*9880d681SAndroid Build Coastguard Workercodegen-diff [-d] I<OBJDUMP-OUTPUT-FILE> I<GDB-DISASSEMBLY-FILE> 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker=head1 DESCRIPTION 90*9880d681SAndroid Build Coastguard Worker 91*9880d681SAndroid Build Coastguard WorkerB<codegen-diff> is a program that tries to show you the differences 92*9880d681SAndroid Build Coastguard Workerbetween the code that B<llc> generated and the code that B<lli> generated. 93*9880d681SAndroid Build Coastguard Worker 94*9880d681SAndroid Build Coastguard WorkerThe way you use it is as follows: first, you create I<OBJDUMP-OUTPUT-FILE> 95*9880d681SAndroid Build Coastguard Workerby running B<objdump> on the B<llc> compiled and linked binary. You need to 96*9880d681SAndroid Build Coastguard Workertrim down the result so it contains only the function of interest. 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard WorkerSecond, you create I<GDB-DISASSEMBLY-FILE> by running B<gdb>, with my patch 99*9880d681SAndroid Build Coastguard Workerto print out hex bytes in the B<disassemble> command output, on 100*9880d681SAndroid Build Coastguard WorkerB<lli>. Set a breakpoint in C<Emitter::finishFunction()> and wait until 101*9880d681SAndroid Build Coastguard Workerthe function you want is compiled. Then use the B<disassemble> command 102*9880d681SAndroid Build Coastguard Workerto print out the assembly dump of the function B<lli> just compiled. 103*9880d681SAndroid Build Coastguard Worker(Use C<lli -debug> to find out where the function starts and ends in memory.) 104*9880d681SAndroid Build Coastguard WorkerIt's easiest to save this output by using B<script>. 105*9880d681SAndroid Build Coastguard Worker 106*9880d681SAndroid Build Coastguard WorkerFinally, you run B<codegen-diff>, as indicated in the Synopsis section of 107*9880d681SAndroid Build Coastguard Workerthis manpage. It will print out a two-line stanza for each mismatched 108*9880d681SAndroid Build Coastguard Workerinstruction, with the B<llc> version first, and the B<lli> version second. 109*9880d681SAndroid Build Coastguard Worker 110*9880d681SAndroid Build Coastguard Worker=head1 OPTIONS 111*9880d681SAndroid Build Coastguard Worker 112*9880d681SAndroid Build Coastguard Worker=over 4 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Worker=item -d 115*9880d681SAndroid Build Coastguard Worker 116*9880d681SAndroid Build Coastguard WorkerDon't show instructions where the bytes are different but they 117*9880d681SAndroid Build Coastguard Workerdisassemble to the same thing. This puts a lot of trust in the 118*9880d681SAndroid Build Coastguard Workerdisassembler, but it might help you highlight the more egregious cases 119*9880d681SAndroid Build Coastguard Workerof misassembly. 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Worker=back 122*9880d681SAndroid Build Coastguard Worker 123*9880d681SAndroid Build Coastguard Worker=head1 AUTHOR 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard WorkerB<codegen-diff> was written by Brian Gaeke. 126*9880d681SAndroid Build Coastguard Worker 127*9880d681SAndroid Build Coastguard Worker=head1 SEE ALSO 128*9880d681SAndroid Build Coastguard Worker 129*9880d681SAndroid Build Coastguard WorkerL<gdb(1)>, L<objdump(1)>, L<script(1)>. 130*9880d681SAndroid Build Coastguard Worker 131*9880d681SAndroid Build Coastguard WorkerYou will need my B<gdb> patch: 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Worker http://llvm.cs.uiuc.edu/~gaeke/gdb-disassembly-print-bytes.patch 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Worker=cut 136