1#!/usr/bin/env perl 2 3use warnings; 4 5use File::Temp qw/ tempfile /; 6use Getopt::Long; 7 8# Default to the system objdump if a cross-compiler edition not given. 9my $aobjdump = "objdump"; 10my $hobjdump = ""; 11my $tobjdump = ""; 12my $hmachine = ""; 13my $tmachine = ""; 14 15GetOptions ('O|objdump=s' => \$aobjdump, 16 'host-objdump=s' => \$hobjdump, 17 'target-objdump=s' => \$tobjdump, 18 'h|host-machine=s' => \$hmachine, 19 't|target-machine=s' => \$tmachine); 20 21# But we can't default the machines. Sanity check that we've at least one. 22die "No host or target machine type" if !$hmachine && !$tmachine; 23 24# Reuse one temp file for all of the hunks. 25my ($outh, $outname) = tempfile(); 26binmode($outh); 27END { unlink $outname; } 28 29# Pre-construct the command-lines for executing the dump. 30sub mkobjcommand ($$) { 31 my ($cmd, $mach) = @_; 32 return 0 if !$mach; 33 $cmd = $aobjdump if !$cmd; 34 return "$cmd -m $mach --disassemble-all -b binary"; 35} 36 37$objdump[1] = mkobjcommand($hobjdump, $hmachine); 38$objdump[2] = mkobjcommand($tobjdump, $tmachine); 39 40# Zero-initialize current dumping state. 41my $mem = ""; 42my $inobjd = 0; 43my $vma = 0; 44 45sub objcommand { 46 my $ret = $objdump[$inobjd]; 47 if (!$ret) { 48 die "Host machine type not specified" if $inobjd == 1; 49 die "Target machine type not specified" if $inobjd == 2; 50 die "Internal error"; 51 } 52 return $ret; 53} 54 55while (<>) { 56 # Collect the data from the relevant OBJD-* lines ... 57 if (/^OBJD-H: /) { 58 die "Internal error" if $inobjd == 2; 59 $mem = $mem . pack("H*", substr($_, 8, -1)); 60 $inobjd = 1; 61 } elsif (/^OBJD-T: /) { 62 die "Internal error" if $inobjd == 1; 63 $mem = $mem . pack("H*", substr($_, 8, -1)); 64 $inobjd = 2; 65 } 66 # ... which will always be followed by a blank line, 67 # at which point we should produce our dump. 68 elsif ($inobjd) { 69 # Rewrite the temp file in one go; it will usually be small. 70 sysseek $outh, 0, 0; 71 truncate $outh, 0; 72 syswrite $outh, $mem; 73 74 my $cmd = objcommand(); 75 $cmd = $cmd . " --adjust-vma=" . $vma if $vma; 76 $cmd = $cmd . " " . $outname; 77 78 # Pipe from objdump... 79 open IN, "-|", $cmd; 80 81 # ... copying all but the first 7 lines of boilerplate to our stdout. 82 my $i = 0; 83 while (<IN>) { 84 print if (++$i > 7); 85 } 86 close IN; 87 print "\n"; 88 89 $mem = ""; 90 $inobjd = 0; 91 $vma = 0; 92 } 93 # The line before "OBJD-*" will be of the form "0x<hex>+: +\n". 94 # Extract the value for passing to --adjust-vma. 95 elsif (/^(0x[0-9a-fA-F]+):\s*$/) { 96 $vma = $1; 97 print; 98 } else { 99 print; 100 } 101} 102