Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

164 lines
3.3 KiB

  1. # Disassembler.pm
  2. #
  3. # Copyright (c) 1996 Malcolm Beattie
  4. #
  5. # You may distribute under the terms of either the GNU General Public
  6. # License or the Artistic License, as specified in the README file.
  7. package B::Disassembler::BytecodeStream;
  8. use FileHandle;
  9. use Carp;
  10. use B qw(cstring cast_I32);
  11. @ISA = qw(FileHandle);
  12. sub readn {
  13. my ($fh, $len) = @_;
  14. my $data;
  15. read($fh, $data, $len);
  16. croak "reached EOF while reading $len bytes" unless length($data) == $len;
  17. return $data;
  18. }
  19. sub GET_U8 {
  20. my $fh = shift;
  21. my $c = $fh->getc;
  22. croak "reached EOF while reading U8" unless defined($c);
  23. return ord($c);
  24. }
  25. sub GET_U16 {
  26. my $fh = shift;
  27. my $str = $fh->readn(2);
  28. croak "reached EOF while reading U16" unless length($str) == 2;
  29. return unpack("n", $str);
  30. }
  31. sub GET_U32 {
  32. my $fh = shift;
  33. my $str = $fh->readn(4);
  34. croak "reached EOF while reading U32" unless length($str) == 4;
  35. return unpack("N", $str);
  36. }
  37. sub GET_I32 {
  38. my $fh = shift;
  39. my $str = $fh->readn(4);
  40. croak "reached EOF while reading I32" unless length($str) == 4;
  41. return cast_I32(unpack("N", $str));
  42. }
  43. sub GET_objindex {
  44. my $fh = shift;
  45. my $str = $fh->readn(4);
  46. croak "reached EOF while reading objindex" unless length($str) == 4;
  47. return unpack("N", $str);
  48. }
  49. sub GET_strconst {
  50. my $fh = shift;
  51. my ($str, $c);
  52. while (defined($c = $fh->getc) && $c ne "\0") {
  53. $str .= $c;
  54. }
  55. croak "reached EOF while reading strconst" unless defined($c);
  56. return cstring($str);
  57. }
  58. sub GET_pvcontents {}
  59. sub GET_PV {
  60. my $fh = shift;
  61. my $str;
  62. my $len = $fh->GET_U32;
  63. if ($len) {
  64. read($fh, $str, $len);
  65. croak "reached EOF while reading PV" unless length($str) == $len;
  66. return cstring($str);
  67. } else {
  68. return '""';
  69. }
  70. }
  71. sub GET_comment_t {
  72. my $fh = shift;
  73. my ($str, $c);
  74. while (defined($c = $fh->getc) && $c ne "\n") {
  75. $str .= $c;
  76. }
  77. croak "reached EOF while reading comment" unless defined($c);
  78. return cstring($str);
  79. }
  80. sub GET_double {
  81. my $fh = shift;
  82. my ($str, $c);
  83. while (defined($c = $fh->getc) && $c ne "\0") {
  84. $str .= $c;
  85. }
  86. croak "reached EOF while reading double" unless defined($c);
  87. return $str;
  88. }
  89. sub GET_none {}
  90. sub GET_op_tr_array {
  91. my $fh = shift;
  92. my @ary = unpack("n256", $fh->readn(256 * 2));
  93. return join(",", @ary);
  94. }
  95. sub GET_IV64 {
  96. my $fh = shift;
  97. my ($hi, $lo) = unpack("NN", $fh->readn(8));
  98. return sprintf("0x%4x%04x", $hi, $lo); # cheat
  99. }
  100. package B::Disassembler;
  101. use Exporter;
  102. @ISA = qw(Exporter);
  103. @EXPORT_OK = qw(disassemble_fh);
  104. use Carp;
  105. use strict;
  106. use B::Asmdata qw(%insn_data @insn_name);
  107. sub disassemble_fh {
  108. my ($fh, $out) = @_;
  109. my ($c, $getmeth, $insn, $arg);
  110. bless $fh, "B::Disassembler::BytecodeStream";
  111. while (defined($c = $fh->getc)) {
  112. $c = ord($c);
  113. $insn = $insn_name[$c];
  114. if (!defined($insn) || $insn eq "unused") {
  115. my $pos = $fh->tell - 1;
  116. die "Illegal instruction code $c at stream offset $pos\n";
  117. }
  118. $getmeth = $insn_data{$insn}->[2];
  119. $arg = $fh->$getmeth();
  120. if (defined($arg)) {
  121. &$out($insn, $arg);
  122. } else {
  123. &$out($insn);
  124. }
  125. }
  126. }
  127. 1;
  128. __END__
  129. =head1 NAME
  130. B::Disassembler - Disassemble Perl bytecode
  131. =head1 SYNOPSIS
  132. use Disassembler;
  133. =head1 DESCRIPTION
  134. See F<ext/B/B/Disassembler.pm>.
  135. =head1 AUTHOR
  136. Malcolm Beattie, C<[email protected]>
  137. =cut