diff options
Diffstat (limited to 'qemu/scripts/disas-objdump.pl')
-rwxr-xr-x | qemu/scripts/disas-objdump.pl | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/qemu/scripts/disas-objdump.pl b/qemu/scripts/disas-objdump.pl new file mode 100755 index 000000000..8f7e8182a --- /dev/null +++ b/qemu/scripts/disas-objdump.pl @@ -0,0 +1,99 @@ +#!/usr/bin/perl -w + +use File::Temp qw/ tempfile /; +use Getopt::Long; + +# Default to the system objdump if a cross-compiler edition not given. +my $aobjdump = "objdump"; +my $hobjdump = ""; +my $tobjdump = ""; +my $hmachine = ""; +my $tmachine = ""; + +GetOptions ('O|objdump=s' => \$aobjdump, + 'host-objdump=s' => \$hobjdump, + 'target-objdump=s' => \$tobjdump, + 'h|host-machine=s' => \$hmachine, + 't|target-machine=s' => \$tmachine); + +# But we can't default the machines. Sanity check that we've at least one. +die "No host or target machine type" if !$hmachine && !$tmachine; + +# Reuse one temp file for all of the hunks. +my ($outh, $outname) = tempfile(); +binmode($outh); +END { unlink $outname; } + +# Pre-construct the command-lines for executing the dump. +sub mkobjcommand ($$) { + my ($cmd, $mach) = @_; + return 0 if !$mach; + $cmd = $aobjdump if !$cmd; + return "$cmd -m $mach --disassemble-all -b binary"; +} + +$objdump[1] = mkobjcommand($hobjdump, $hmachine); +$objdump[2] = mkobjcommand($tobjdump, $tmachine); + +# Zero-initialize current dumping state. +my $mem = ""; +my $inobjd = 0; +my $vma = 0; + +sub objcommand { + my $ret = $objdump[$inobjd]; + if (!$ret) { + die "Host machine type not specified" if $inobjd == 1; + die "Target machine type not specified" if $inobjd == 2; + die "Internal error"; + } + return $ret; +} + +while (<>) { + # Collect the data from the relevant OBJD-* lines ... + if (/^OBJD-H: /) { + die "Internal error" if $inobjd == 2; + $mem = $mem . pack("H*", substr($_, 8, -1)); + $inobjd = 1; + } elsif (/^OBJD-T: /) { + die "Internal error" if $inobjd == 1; + $mem = $mem . pack("H*", substr($_, 8, -1)); + $inobjd = 2; + } + # ... which will always be followed by a blank line, + # at which point we should produce our dump. + elsif ($inobjd) { + # Rewrite the temp file in one go; it will usually be small. + sysseek $outh, 0, 0; + truncate $outh, 0; + syswrite $outh, $mem; + + my $cmd = objcommand(); + $cmd = $cmd . " --adjust-vma=" . $vma if $vma; + $cmd = $cmd . " " . $outname; + + # Pipe from objdump... + open IN, "-|", $cmd; + + # ... copying all but the first 7 lines of boilerplate to our stdout. + my $i = 0; + while (<IN>) { + print if (++$i > 7); + } + close IN; + print "\n"; + + $mem = ""; + $inobjd = 0; + $vma = 0; + } + # The line before "OBJD-*" will be of the form "0x<hex>+: +\n". + # Extract the value for passing to --adjust-vma. + elsif (/^(0x[0-9a-fA-F]+):\s*$/) { + $vma = $1; + print; + } else { + print; + } +} |