v8がJavascriptから生成する実際のマシンコードを確認する方法を知っている人はいますか?私はそこまで到達しましScript::Compile()
たsrc/api.cc
が、そこからどこに行くべきかわかりません。
5 に答える
C ++コードから逆アセンブラを呼び出す方法はわかりませんが、シェルから逆アセンブラを取得するための手っ取り早い方法があります。
まず、逆アセンブラをサポートしてv8をコンパイルします。
scons [your v8 build options here] disassembler=on sample=shell
これで、「-print_code」オプションを使用してシェルを呼び出すことができます。
./shell --print_code hello.js
これはあなたにこのようなものを与えるはずです:
--- Raw source ---
print("hello world");
--- Code ---
kind = FUNCTION
Instructions (size = 134)
0x2ad0a77ceea0 0 55 push rbp
0x2ad0a77ceea1 1 488bec REX.W movq rbp,rsp
0x2ad0a77ceea4 4 56 push rsi
0x2ad0a77ceea5 5 57 push rdi
0x2ad0a77ceea6 6 49ba59c13da9d02a0000 REX.W movq r10,0x2ad0a93dc159 ;; object: 0xa93dc159 <undefined>
0x2ad0a77ceeb0 16 4952 REX.W push r10
0x2ad0a77ceeb2 18 49ba688b700000000000 REX.W movq r10,0x708b68
0x2ad0a77ceebc 28 493b22 REX.W cmpq rsp,[r10]
0x2ad0a77ceebf 31 0f824e000000 jc 115 (0x2ad0a77cef13)
0x2ad0a77ceec5 37 488b462f REX.W movq rax,[rsi+0x2f]
0x2ad0a77ceec9 41 4883ec18 REX.W subq rsp,0xlx
0x2ad0a77ceecd 45 49ba094b3ea9d02a0000 REX.W movq r10,0x2ad0a93e4b09 ;; object: 0xa93e4b09 <String[5]: print>
0x2ad0a77ceed7 55 4c8955e0 REX.W movq [rbp-0x20],r10
0x2ad0a77ceedb 59 488945d8 REX.W movq [rbp-0x28],rax
0x2ad0a77ceedf 63 49ba014d3ea9d02a0000 REX.W movq r10,0x2ad0a93e4d01 ;; object: 0xa93e4d01 <String[11]: hello world>
0x2ad0a77ceee9 73 4c8955d0 REX.W movq [rbp-0x30],r10
0x2ad0a77ceeed 77 49baa06c7ba7d02a0000 REX.W movq r10,0x2ad0a77b6ca0 ;; debug: statement 0
;; code: contextual, CALL_IC, UNINITIALIZED, argc = 1
0x2ad0a77ceef7 87 49ffd2 REX.W call r10
0x2ad0a77ceefa 90 488b75f8 REX.W movq rsi,[rbp-0x8]
0x2ad0a77ceefe 94 4883c408 REX.W addq rsp,0xlx
0x2ad0a77cef02 98 488945e8 REX.W movq [rbp-0x18],rax
0x2ad0a77cef06 102 488be5 REX.W movq rsp,rbp ;; js return
0x2ad0a77cef09 105 5d pop rbp
0x2ad0a77cef0a 106 c20800 ret 0x8
0x2ad0a77cef0d 109 cc int3
0x2ad0a77cef0e 110 cc int3
0x2ad0a77cef0f 111 cc int3
0x2ad0a77cef10 112 cc int3
0x2ad0a77cef11 113 cc int3
0x2ad0a77cef12 114 cc int3
0x2ad0a77cef13 115 49ba60657ba7d02a0000 REX.W movq r10,0x2ad0a77b6560 ;; code: STUB, StackCheck, minor: 0
0x2ad0a77cef1d 125 49ffd2 REX.W call r10
0x2ad0a77cef20 128 488b7df0 REX.W movq rdi,[rbp-0x10]
0x2ad0a77cef24 132 eb9f jmp 37 (0x2ad0a77ceec5)
RelocInfo (size = 10)
0x2ad0a77ceea8 embedded object (0xa93dc159 <undefined>)
0x2ad0a77ceecf embedded object (0xa93e4b09 <String[5]: print>)
0x2ad0a77ceee1 embedded object (0xa93e4d01 <String[11]: hello world>)
0x2ad0a77ceeed statement position (0)
0x2ad0a77ceeef code target (context) (CALL_IC) (0x2ad0a77b6ca0)
0x2ad0a77cef06 js return
0x2ad0a77cef15 code target (STUB) (0x2ad0a77b6560)
hello world
もちろん、出力は異なります。上記は、Linuxx64用にコンパイルされたv8トランクからのものです。
逆アセンブラーをサポートする v8 をビルドする必要があります。
v8 ソース コードをダウンロードします。
git clone https://chromium.googlesource.com/v8/v8.git
逆アセンブラーをサポートしてビルドします。
make dependencies
make ia32.release objectprint=on disassembler=on
必要に応じて、特定のフラグを使用して d8 (v8 シェル) を呼び出します。
out/ia32.release/d8 --code-comments --print-code <app.js>
参考のため:
- --code-comments : コード コメントが含まれます。
- --print-code : コードをstdoutに出力します。
- --print-code-stubs : コード スタブを出力します。
- --print-opt-code : 最適化されたコードを出力します。
- --trace-hydrogen : IR (中間表現) コードを Hydrogen.cfg に出力します。このファイルは、Java の C1Visualizerで開くことができます。
あなたは正しい軌道に乗っていると思います。
Script::Compile から Compiler::Compile に移動する必要があるようです。これにより、コード ジェネレーター (codegen*.cc および .h) が表示されます。
以上のことから、codegen-ia32.cc を見ると、ビルド時に ENABLE_DISASSEMBLER を定義すると、逆アセンブリが出力されるはずです。
もちろん、これはすべて、私がここに持っているソースの古いコピーを簡単にブラウズしただけなので、YMMV ですが、これでうまくいくと思います。
(あなたの投稿をもう一度見ると、アセンブラーではなく機械語を探していることがわかります。よくわかりませんが、逆アセンブリではなくアセンブルされたコード出力が必要な場合は、ロジックを変更する必要があるかもしれません)
を参照するv8_root/build/features.gypi
と、V8 の逆アセンブラー関連およびその他の多くのコンパイル時機能スイッチが見つかります。