xref: /openbmc/qemu/scripts/disas-objdump.pl (revision 42eed424e1ea6469ce73cb2fdddb0d31bebb686a)
18dc6d240SRichard Henderson#!/usr/bin/perl -w
28dc6d240SRichard Henderson
38dc6d240SRichard Hendersonuse File::Temp qw/ tempfile /;
48dc6d240SRichard Hendersonuse Getopt::Long;
58dc6d240SRichard Henderson
68dc6d240SRichard Henderson# Default to the system objdump if a cross-compiler edition not given.
78dc6d240SRichard Hendersonmy $aobjdump = "objdump";
88dc6d240SRichard Hendersonmy $hobjdump = "";
98dc6d240SRichard Hendersonmy $tobjdump = "";
108dc6d240SRichard Hendersonmy $hmachine = "";
118dc6d240SRichard Hendersonmy $tmachine = "";
128dc6d240SRichard Henderson
138dc6d240SRichard HendersonGetOptions ('O|objdump=s' => \$aobjdump,
148dc6d240SRichard Henderson            'host-objdump=s' => \$hobjdump,
158dc6d240SRichard Henderson            'target-objdump=s' => \$tobjdump,
168dc6d240SRichard Henderson            'h|host-machine=s' => \$hmachine,
178dc6d240SRichard Henderson            't|target-machine=s' => \$tmachine);
188dc6d240SRichard Henderson
198dc6d240SRichard Henderson# But we can't default the machines.  Sanity check that we've at least one.
208dc6d240SRichard Hendersondie "No host or target machine type" if !$hmachine && !$tmachine;
218dc6d240SRichard Henderson
228dc6d240SRichard Henderson# Reuse one temp file for all of the hunks.
238dc6d240SRichard Hendersonmy ($outh, $outname) = tempfile();
248dc6d240SRichard Hendersonbinmode($outh);
258dc6d240SRichard HendersonEND { unlink $outname; }
268dc6d240SRichard Henderson
278dc6d240SRichard Henderson# Pre-construct the command-lines for executing the dump.
288dc6d240SRichard Hendersonsub mkobjcommand ($$) {
298dc6d240SRichard Henderson    my ($cmd, $mach) = @_;
308dc6d240SRichard Henderson    return 0 if !$mach;
318dc6d240SRichard Henderson    $cmd = $aobjdump if !$cmd;
32*42eed424SRichard Henderson    return "$cmd -m $mach --disassemble-all -b binary";
338dc6d240SRichard Henderson}
348dc6d240SRichard Henderson
358dc6d240SRichard Henderson$objdump[1] = mkobjcommand($hobjdump, $hmachine);
368dc6d240SRichard Henderson$objdump[2] = mkobjcommand($tobjdump, $tmachine);
378dc6d240SRichard Henderson
388dc6d240SRichard Henderson# Zero-initialize current dumping state.
398dc6d240SRichard Hendersonmy $mem = "";
408dc6d240SRichard Hendersonmy $inobjd = 0;
41*42eed424SRichard Hendersonmy $vma = 0;
428dc6d240SRichard Henderson
438dc6d240SRichard Hendersonsub objcommand {
448dc6d240SRichard Henderson    my $ret = $objdump[$inobjd];
458dc6d240SRichard Henderson    if (!$ret) {
468dc6d240SRichard Henderson        die "Host machine type not specified" if $inobjd == 1;
478dc6d240SRichard Henderson        die "Target machine type not specified" if $inobjd == 2;
488dc6d240SRichard Henderson        die "Internal error";
498dc6d240SRichard Henderson    }
508dc6d240SRichard Henderson    return $ret;
518dc6d240SRichard Henderson}
528dc6d240SRichard Henderson
538dc6d240SRichard Hendersonwhile (<>) {
54*42eed424SRichard Henderson    # Collect the data from the relevant OBJD-* lines ...
558dc6d240SRichard Henderson    if (/^OBJD-H: /) {
568dc6d240SRichard Henderson        die "Internal error" if $inobjd == 2;
578dc6d240SRichard Henderson        $mem = $mem . pack("H*", substr($_, 8, -1));
588dc6d240SRichard Henderson        $inobjd = 1;
598dc6d240SRichard Henderson    } elsif (/^OBJD-T: /) {
608dc6d240SRichard Henderson        die "Internal error" if $inobjd == 1;
618dc6d240SRichard Henderson        $mem = $mem . pack("H*", substr($_, 8, -1));
628dc6d240SRichard Henderson        $inobjd = 2;
638dc6d240SRichard Henderson    }
648dc6d240SRichard Henderson    # ... which will always be followed by a blank line,
658dc6d240SRichard Henderson    # at which point we should produce our dump.
668dc6d240SRichard Henderson    elsif ($inobjd) {
678dc6d240SRichard Henderson        # Rewrite the temp file in one go; it will usually be small.
688dc6d240SRichard Henderson        sysseek $outh, 0, 0;
698dc6d240SRichard Henderson        truncate $outh, 0;
708dc6d240SRichard Henderson        syswrite $outh, $mem;
718dc6d240SRichard Henderson
72*42eed424SRichard Henderson        my $cmd = objcommand();
73*42eed424SRichard Henderson        $cmd = $cmd . " --adjust-vma=" . $vma if $vma;
74*42eed424SRichard Henderson        $cmd = $cmd . " " . $outname;
75*42eed424SRichard Henderson
768dc6d240SRichard Henderson        # Pipe from objdump...
77*42eed424SRichard Henderson        open IN, "-|", $cmd;
788dc6d240SRichard Henderson
798dc6d240SRichard Henderson        # ... copying all but the first 7 lines of boilerplate to our stdout.
808dc6d240SRichard Henderson	my $i = 0;
818dc6d240SRichard Henderson	while (<IN>) {
828dc6d240SRichard Henderson	    print if (++$i > 7);
838dc6d240SRichard Henderson        }
848dc6d240SRichard Henderson        close IN;
858dc6d240SRichard Henderson        print "\n";
868dc6d240SRichard Henderson
878dc6d240SRichard Henderson        $mem = "";
888dc6d240SRichard Henderson        $inobjd = 0;
89*42eed424SRichard Henderson        $vma = 0;
90*42eed424SRichard Henderson    }
91*42eed424SRichard Henderson    # The line before "OBJD-*" will be of the form "0x<hex>+: +\n".
92*42eed424SRichard Henderson    # Extract the value for passing to --adjust-vma.
93*42eed424SRichard Henderson    elsif (/^(0x[0-9a-fA-F]+):\s*$/) {
94*42eed424SRichard Henderson        $vma = $1;
95*42eed424SRichard Henderson        print;
968dc6d240SRichard Henderson    } else {
978dc6d240SRichard Henderson        print;
988dc6d240SRichard Henderson    }
998dc6d240SRichard Henderson}
100