Dalvikバイトコードリファレンスの読み方

19
Dalvikバイトコード リファレンスの読み方 発表者 : 僻地からの出稼ぎプログラマkmt-t

description

改定しました http://www.slideshare.net/kmt-t/dalvik-10359301

Transcript of Dalvikバイトコードリファレンスの読み方

Page 1: Dalvikバイトコードリファレンスの読み方

Dalvikバイトコード

リファレンスの読み方

発表者 :

僻地からの出稼ぎプログラマkmt-t

Page 2: Dalvikバイトコードリファレンスの読み方

自己紹介

Web上での活動

ハンドルネーム : kmt-t

はてなID : kmt-t2

Twitter ID : kmt_t

属性

僻地出身、去年の10月から大阪に出稼ぎ中

組み込みプログラマらしい?

仕事はミドルウェア担当な場合が多いかな?

Page 3: Dalvikバイトコードリファレンスの読み方

今後の話の前振り

Dalvik仮想マシン三部作

Dalvik仮想マシンのアーキテクチャ

Dalvikバイトコードリファレンスの読み方

DEXファイルフォーマット

今回は第二部のみを解説

今回は第一部の内容を前提に話をする

http://www.slideshare.net/kmt-t/javadalvik

Page 4: Dalvikバイトコードリファレンスの読み方

本日の前振り

Dalvikバイトコードリファレンスの読み方 実際のDalvikバイトコードの命令レイアウト

Dalvikバイトコード命令とそれに対応する実装

Dalvikバイトコードリファレンス Androidソースコードのdalvik/docsディレクトリ以下

dalvik-bytecode.html

instruction-formats.html

opcodeディレクトリ以下

Dalvik仮想マシンインタープリタ 今回はC言語バージョンを参照

dalvik/vm/mterp/out/InterpC-portstd.c

Page 5: Dalvikバイトコードリファレンスの読み方

dalvik-bytecode.htmlを

開いてみる

「Summary of Instruction Set」の章に注目

Page 6: Dalvikバイトコードリファレンスの読み方

dalvik-bytecode.html (move命令)

列 : Op & Format

「01」はオペコード(命令の種類を示すID)

「12x」は命令フォーマットの種類

instruction-formats.htmlに詳細が記載

実は上記ファイルを読まなくても、列Mnemonic/Syntaxを読めばおおまかな命令フォーマットは分かる

Page 7: Dalvikバイトコードリファレンスの読み方

dalvik-bytecode.html (move命令)

列 : Mnemonic/Syntax

「move」は命令の種類

「vA」「vB」は4bitのレジスタ番号のオペランドを2つ持つことを示す

仮に「vAA」とすると、8bitのレジスタ番号、「vAAAA」とすると16bitのレジスタ番号を示す

Page 8: Dalvikバイトコードリファレンスの読み方

dalvik-bytecode.html (move命令)

列 : Arguments

「A: destination register (4 bits)」 (レジスタ番号Aは値のコピー先レジスタ)

「B: source register (4 bits)」 (レジスタ番号Aは値のコピー元レジスタ)

オペランドの役割が記述されている

Page 9: Dalvikバイトコードリファレンスの読み方

dalvik-bytecode.html (move命令)

列 : Description

命令の解説が書いてある

命令自体のセマンティクス(命令の挙動)については述べられていない場合が多い

セマンティクスはdalvik/docs/opcode以下のディレクトリを参照

Page 10: Dalvikバイトコードリファレンスの読み方

命令フォーマット (move命令の例)

命令フォーマットの制約条件

すべての命令は最初の16bitの下位8bitがオペコード

move命令は4bitのレジスタ番号AとBを持つ

命令は必ず16bitでアライメントされている

オペランドは16bit境界ごとにLSB側から順に配置される

レジスタ番号 vB (4bit)

レジスタ番号 vA (4bit)

オペコード = 0x01 (8bit)

LSB MSB

命令長16bit

Page 11: Dalvikバイトコードリファレンスの読み方

バイトコード命令の実装を読む

sparse-switch命令の例 (1)

Javaのswitch文に対応した命令

Mnemonic/Syntax

「sparce-switch vAA, +BBBBBBBB」

「vAA」は分岐の判定値が格納されたレジスタ

「+BBBBBBBB」は分岐情報「sparse-switch構造体」への符号付32bitオフセット

Page 12: Dalvikバイトコードリファレンスの読み方

バイトコード命令の実装を読む

sparse-switch命令の例 (2)

sparce-switch構造体

Page 13: Dalvikバイトコードリファレンスの読み方

バイトコード命令の実装を読む

sparse-switch命令の例 (3)

「ident=0x0200」

バイトコード中に0xXX00(XX≠0)のバイナリで始まる命令が出現する場合をPseudo命令と呼ぶ

Pseudo命令はバイトコードではない

DEXファイル上の都合でバイトコードとsparse-switch構造体を区別する必要があるため

「size」

switch文のcaseの数

「keys」

switch文の「case XX」のXXの値の配列

「targets」

switch文の分岐先バイトコード命令へのオフセットの配列

Page 14: Dalvikバイトコードリファレンスの読み方

バイトコード命令の実装を読む

sparse-switch命令の例 (4)

dalvik/vm/mterp/out/InterpC-portstd.c

該当部分の実装コードを簡略化すると以下のとおり

HANDLE_OPCODE(OP_SPARSE_SWITCH /*vAA, +BBBB*/) { u2 vsrc1 = INST_AA(inst); u4 testVal = GET_REGISTER(vsrc1); s4 offset = FETCH(1) | (((s4) FETCH(2)) << 16); const u2* switchData = pc + offset; offset = dvmInterpHandleSparseSwitch(switchData, testVal); FINISH(offset); } OP_END

Page 15: Dalvikバイトコードリファレンスの読み方

バイトコード命令の実装を読む

invoke-virtual命令の例 (1)

dalvik/vm/mterp/out/InterpC-portstd.c

「GOTO_TARGET(invokeVirtual, bool

methodCallRange)」マクロが実装コード部分

Page 16: Dalvikバイトコードリファレンスの読み方

バイトコード命令の実装を読む

invoke-virtual命令の例 (2)

1. 引数の数をバイトコード命令から取得

2. メソッドIDをバイトコード命令から取得

3. メソッドの引数をバイトコード命令から取得

4. thisポインタのNULLチェック

5. メソッドIDから基底メソッド情報のポインタを取得

DEXファイルから基底メソッド情報を構築する

メソッド構造体はキャッシュされる

キャッシュはクラスIDとメソッドIDの組をキー、メソッド構造体のポインタを値とするハッシュテーブル構造

Page 17: Dalvikバイトコードリファレンスの読み方

バイトコード命令の実装を読む

invoke-virtual命令の例 (3)

6. 基底メソッドのインスタンスからメソッドのvtable

インデックスを取得

7. 派生メソッドのインスタンスをvtableから取得

8. 抽象メソッドの呼び出しでないかチェック

9. 命令を詳細にデコードし、引数をひとつずつ取り出し、スタックに積む

10. 新しいフレームポインタとvm-specific-internal-

goopの位置を計算

11. スタックあふれが発生していないかチェック

Page 18: Dalvikバイトコードリファレンスの読み方

バイトコード命令の実装を読む

invoke-virtual命令の例 (4)

12. vm-specific-internal-goopに以下の情報を保存

現在のフレームポインタ

現在のプログラムカウンタ

現在のメソッド情報構造体のポインタ

13. (以下ネイティブメソッドでない場合)

14. 実行中のメソッド情報を呼び出し先に切り替え

15. プログラムカウンタとフレームポインタを呼び出し先のものに切り替え

Page 19: Dalvikバイトコードリファレンスの読み方

以上で発表は終了

ご静聴ありがとうございました!