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