Merge remote-tracking branch 'remotes/dagrh/tags/pull-virtiofs-20211026' into staging
[qemu.git] / scripts / disas-objdump.pl
1 #!/usr/bin/env perl
2
3 use warnings;
4
5 use File::Temp qw/ tempfile /;
6 use Getopt::Long;
7
8 # Default to the system objdump if a cross-compiler edition not given.
9 my $aobjdump = "objdump";
10 my $hobjdump = "";
11 my $tobjdump = "";
12 my $hmachine = "";
13 my $tmachine = "";
14
15 GetOptions ('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.
22 die "No host or target machine type" if !$hmachine && !$tmachine;
23
24 # Reuse one temp file for all of the hunks.
25 my ($outh, $outname) = tempfile();
26 binmode($outh);
27 END { unlink $outname; }
28
29 # Pre-construct the command-lines for executing the dump.
30 sub 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.
41 my $mem = "";
42 my $inobjd = 0;
43 my $vma = 0;
44
45 sub 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
55 while (<>) {
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 }