クラスファイルの構造解析(2) 2003年6月23日 海谷 治彦.

Slides:



Advertisements
Similar presentations
アルゴリズムとプログラミン グ (Algorithms and Programming) 第6回:クラスとインスタンス クラスの宣言 アクセス修飾子 インスタンスの生成 (new キーワード) this キーワード フィールドとメソッドの実際の定義と使い 方 クラスの宣言 アクセス修飾子 インスタンスの生成.
Advertisements

1 Reference, 配列,アクセスフラ グ, jdb での観察, アセンブラ上での編集 2002 年 6 月 6 日 海谷 治彦.
6.4継承とメソッド 6.5継承とコンストラクタ 11月28日 時田 陽一
プログラミング 平成24年1月11日 森田 彦.
社会人学習講座 「Javaプログラミング概論」
クラスファイルの構造解析(1) 2002年6月16日 2003年6月8日 改訂 海谷 治彦.
プログラミング基礎I(再) 山元進.
WebサービスII (第10回) 2007年11月28日 植田龍男.
アルゴリズムとデータ構造1 2007年6月12日
アルゴリズムとプログラミング (Algorithms and Programming)
実行時のメモリ構造(1) Jasminの基礎とフレーム内動作
プログラミング基礎I(再) 山元進.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
独習Java ・ 10.6  Hashtableクラス ・ 10.7  String Tokenizerクラス  12月12日    小笠原 一恵.
プログラミング実習 1・2 クラス 第 1 週目 担当教員:  渡邊 直樹.
アルゴリズムとデータ構造 2011年6月13日
Java2セキュリティ, クラスローダー,ベリファイア
プログラミングIII演習 第1回目.
例外,並行・同期処理,ゴミ集め 2002年7月7日 海谷 治彦.
第2章 Eclipseと簡単なオブジェクト 指向プログラミング
第20章 Flyweight ~同じものを共有して無駄をなくす~
インタフェース プログラミング 第14回 インタフェース プログラミング第14回.
アルゴリズムとデータ構造 2011年6月20日
~手続き指向からオブジェクト指向へ[Ⅱ]~
実行時のメモリ構造(2) Javaスタック内動作他
細かい粒度でコードの再利用を可能とするメソッド内メソッドのJava言語への導入
プログラミング言語入門 手続き型言語としてのJava
JAVA入門.
アルゴリズムとプログラミング (Algorithms and Programming)
オブジェクト指向 プログラミング 第八回 知能情報学部 新田直也.
独習JAVA 6.8 コンストラクタの修飾子 6.9 メソッドの修飾子 6.10 ObjectクラスとClassクラス 11月28日(金)
オブジェクト指向 プログラミング 第十一回 知能情報学部 新田直也.
リファレンスの復習と例外処理 2005年6月14日 海谷 治彦.
オブジェクト指向 プログラミング 第二回 知能情報学部 新田直也.
コンパイラの解析 (3) クラスとインスタンスの初期化.
Integer Java Virtual Machine
Java/Swingについて (3) 2005年10月19日 海谷 治彦.
10-1 SAXの概要 10-2 Saxプログラミングの基礎 10-3 saxのプログラム例
パッケージ,アクセス修飾子 2008年4月27日 海谷 治彦.
オブジェクト指向 プログラミング 第十ニ回 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
new Calc(7,3).divInt()実行前
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
アルゴリズムとデータ構造1 2006年7月11日
JAVAバイトコードにおける データ依存解析手法の提案と実装
アルゴリズムとプログラミング (Algorithms and Programming)
オブジェクト指向 プログラミング 第九回 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第八回 知能情報学部 新田直也.
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
プログラムが実行されるまで 2002年4月14日 海谷 治彦.
アルゴリズムとデータ構造 2012年7月2日
C#プログラミング実習 第3回.
計算機プログラミングI 第3回 プリミティブ値 クラスメソッド クラス変数 式と演算 変数の利用
アルゴリズムとデータ構造 2012年6月11日
アルゴリズムとプログラミング (Algorithms and Programming)
アルゴリズムとデータ構造 2011年6月28日
アルゴリズムとデータ構造 2013年7月2日
Chapter 5 5.5 thisキーワード 5.6 インスタンス変数とインスタンスメソッド 結城 隆
アルゴリズムとデータ構造1 2009年6月15日
JAVA入門⑥ クラスとインスタンス.
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
アルゴリズムとデータ構造 2012年6月21日
アルゴリズムとデータ構造 2010年6月17日
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
計算機プログラミングI 第10回 2002年12月19日(木) メソッドの再定義と動的結合 クイズ メソッドの再定義 (オーバーライド)
計算機プログラミングI 第5回 2002年11月7日(木) 配列: 沢山のデータをまとめたデータ どんなものか どうやって使うのか
Josh : バイトコードレベルでのJava用 Aspect Weaver
Presentation transcript:

クラスファイルの構造解析(2) 2003年6月23日 海谷 治彦

目次 コンスタントプールの解決とダイナミックリンク バイトコードの直接解析の手順 フィールド,メソッド,クラス属性等について.

コンスタントプール リゾリューション Constant Pool Resolution CP中の,クラス,メソッド,フィールドの参照を,JVM中の実際のメモリ空間のアドレスに置きかえること. JVMでのダイナミックリンクの実現手段 リンクについては講義第2回資料参照. 教科書 p.115~ 先週の資料の再掲載

簡単な例題 ./cpr/ の下 class Go{ static ClassA a; public static void main(String[] args){ a=new ClassA(); } class ClassA{ private int a; }

ロードとリンクの実際 1/3 CPの抜粋 (Go.class) ロード時には,CP#0002は,CP#0012の文字列を指してる. BB 00 02 ; new ClassA 59 ; dup B7 00 03 ; invokespecial ClassA/<init>()V B3 00 04 ; putstatic Go/a LClassA; B1 ; return CPの抜粋 (Go.class) 07 00 12 ;(00 02) Class => ClassA 01 00 06 43 6C 61 73 73 41 ;(00 12) Utf8 = "ClassA" ロード時には,CP#0002は,CP#0012の文字列を指してる.

ロードとリンクの実際 2/3 CPの抜粋 (Go.class) BB 00 02 ; new ClassA 59 ; dup B7 00 03 ; invokespecial ClassA/<init>()V B3 00 04 ; putstatic Go/a LClassA; B1 ; return CPの抜粋 (Go.class) 07 00 12 ;(00 02) Class => ClassA 01 00 06 43 6C 61 73 73 41 ;(00 12) Utf8 = "ClassA" メソッドエリア しかし,new ClassA が実行されると,ClassAがロードされ,#0012は,実際にClassAが配置されたメモリにおきかわる class ClassA{ private int a; }

ロードとリンクの実際 3/3 教科書p.116に書いてある例を,より簡単な形で図示した. jdbでの観察例も, ./cpr/ 下においた. これにより,CPエントリ#0002番,ClassAをさすCPは,以降,単なる文字列でなく,実際のClassAを指すようになる. CPリゾリューションが起こらない限り,クラスはロードされない.

CPリゾリューションのまとめ CPエントリ内の,Fieldref, Methodref, InterfaceMethodref, Class の4つは,必要に応じて,メソッドエリア内のアドレスを指すようになる. 上記のようなことをCPリゾリューション(解決)と呼ぶ. ただし,その参照が利用されない限り,解決は行われない.

Javaが遅いと感じるのは このCPリゾリューションを一発目にやってるので,走り出しが遅く感じる.

用語の確認 ダイナミックリンク: もともとはばらばらだったクラスをCPを通して結び付け,相互に利用できるようにすること.

バイトコード解析の手順 javacでクラスファイルを得る. bin2hex でダンプをとる. クラスファイルの構造を参考に区切りをつける. CPのエントリを分割. インストラクションの認識. かなり非人道的な作業です(涙)

クラスファイルの構造概要 教科書 p.36 図1-13 である. 大雑把にいって, の7つのパートからなる. クラスファイル自体の情報 コンスタントプールのリスト クラス自体の情報 実装しているインタフェースのリスト フィールドのリスト メソッドのリスト クラスの付加的情報のリスト(Innerクラスもこれに含まれる) の7つのパートからなる. 再録

例題 public class Byte implements Runnable{ private int s; public void run(){ s++; } インタフェース 1つ フィールド 1つ メソッド 2つ (暗黙のコンストラクタを含める)

とりあえずバイト列を見る CA FE BA BE 00 03 00 2D 00 14 0A 00 04 00 0F 09 ; .......-........ 00 03 00 10 07 00 11 07 00 12 07 00 13 01 00 01 ; ................ 73 01 00 01 49 01 00 06 3C 69 6E 69 74 3E 01 00 ; s...I...<init>.. 03 28 29 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 ; .()V...Code...Li 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 03 ; neNumberTable... 72 75 6E 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 ; run...SourceFile 01 00 09 42 79 74 65 2E 6A 61 76 61 0C 00 08 00 ; ...Byte.java.... 09 0C 00 06 00 07 01 00 04 42 79 74 65 01 00 10 ; .........Byte... 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 ; java/lang/Object 01 00 12 6A 61 76 61 2F 6C 61 6E 67 2F 52 75 6E ; ...java/lang/Run 6E 61 62 6C 65 00 21 00 03 00 04 00 01 00 05 00 ; nable.!......... 01 00 02 00 06 00 07 00 00 00 02 00 01 00 08 00 ; ................ 09 00 01 00 0A 00 00 00 1D 00 01 00 01 00 00 00 ; ................ 05 2A B7 00 01 B1 00 00 00 01 00 0B 00 00 00 06 ; .*.............. 00 01 00 00 00 01 00 01 00 0C 00 09 00 01 00 0A ; ................ 00 00 00 27 00 03 00 01 00 00 00 0B 2A 59 B4 00 ; ...'........*Y.. 02 04 60 B5 00 02 B1 00 00 00 01 00 0B 00 00 00 ; ..`............. 0A 00 02 00 00 00 04 00 0A 00 05 00 01 00 0D 00 ; ................ 00 00 02 00 0E ; .....

bin2hex –q Byte.class の結果 CA FE BA BE 00 03 00 2D 00 14 0A 00 04 00 0F 09 00 03 00 10 07 00 11 07 00 12 07 00 13 01 00 01 73 01 00 01 49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 03 72 75 6E 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 09 42 79 74 65 2E 6A 61 76 61 0C 00 08 00 09 0C 00 06 00 07 01 00 04 42 79 74 65 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 01 00 12 6A 61 76 61 2F 6C 61 6E 67 2F 52 75 6E 6E 61 62 6C 65 00 21 00 03 00 04 00 01 00 05 00 01 00 02 00 06 00 07 00 00 00 02 00 01 00 08 00 09 00 01 00 0A 00 00 00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 01 00 0B 00 00 00 06 00 01 00 00 00 01 00 01 00 0C 00 09 00 01 00 0A 00 00 00 27 00 03 00 01 00 00 00 0B 2A 59 B4 00 02 04 60 B5 00 02 B1 00 00 00 01 00 0B 00 00 00 0A 00 02 00 00 00 04 00 0A 00 05 00 01 00 0D 00 00 00 02 00 0E

最初の8バイトはプリアンブルとバージョン番号 CA FE BA BE 00 03 00 2D 00 14 0A 00 04 00 0F 09 00 03 00 10 07 00 11 07 00 12 07 00 13 01 00 01 73 01 00 01 49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 03 72 75 6E 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 09 42 79 74 65 2E 6A 61 76 61 0C 00 08 00 09 0C 00 06 00 07 01 00 04 42 79 74 65 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 01 00 12 6A 61 76 61 2F 6C 61 6E 67 2F 52 75 6E 6E 61 62 6C 65 以下,省略.

CPの数は0x0014個-1 CA FE BA BE ; プリアンブル 00 03 00 2D ; マイナーバージョン,メジャーバージョン 00 03 00 10 07 00 11 07 00 12 07 00 13 01 00 01 73 01 00 01 49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 03 72 75 6E 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 09 42 79 74 65 2E 6A 61 76 61 0C 00 08 00 09 0C 00 06 00 07 01 00 04 42 79 74 65 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 01 00 12 6A 61 76 61 2F 6C 61 6E 67 2F 52 75 6E 6E 61 62 6C 65 以下,省略.

19個のCPを分割 p.51, 189~ 等参照 CA FE BA BE ; プリアンブル 00 03 00 2D ; マイナーバージョン,メジャーバージョン 00 14 ; 0x0014-1 = 16+4-1 = 19個 (10進法) 0A 00 04 00 0F 09 00 03 00 10 07 00 11 07 00 12 07 00 13 01 00 01 73 01 00 01 49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 03 72 75 6E 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 09 42 79 74 65 2E 6A 61 76 61 0C 00 08 00 09 0C 00 06 00 07 01 00 04 42 79 74 65 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 01 00 12 6A 61 76 61 2F 6C 61 6E 67 2F 52 75 6E 6E 61 62 6C 65 以下,省略.

CPエントリ毎のサイズ 1 Utf8 = 1B + 2B + 上記2Bで示されたサイズ 2 Integer = 1B + 4B 4 Float = 1B + 4B 5 long = 1B + 8B 6 double = 1B + 8B 7 class = 1B + 2B 8 string = 1B + 2B 9 fieldref = 1B + 2B + 2B A methodref = 1B + 2B + 2B B interfaceMethodref = 1B + 2B + 2B C NameAndType = 1B + 2B + 2B

19個のCPを分割 CA FE BA BE ; プリアンブル 00 03 00 2D ; マイナーバージョン,メジャーバージョン 00 14 ; 0x0014-1 = 16+4-1 = 19個 (10進法) 0A 00 04 00 0F ; 0001 09 00 03 00 10 ; 0002 07 00 11 ; 0003 07 00 12 ; 0004 07 00 13 ; 0005 01 00 01 73 ; 0006 01 00 01 49 ; 0007 01 00 06 3C 69 6E 69 74 3E ; 0008 01 00 03 28 29 56 ; 0009 01 00 04 43 6F 64 65 ; 000a 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 ; 000b 01 00 03 72 75 6E ; 000c 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 ; 000d 01 00 09 42 79 74 65 2E 6A 61 76 61 ; 000e 0C 00 08 00 09 ; 000f 0C 00 06 00 07 ; 0010 01 00 04 42 79 74 65 ; 0011 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 ; 0012 01 00 12 6A 61 76 61 2F 6C 61 6E 67 2F 52 75 6E 6E 61 62 6C 65 ; 0013 以下,省略. 19個のCPを分割

残りのバイト 6Bはクラス情報 00 21 ; アクセスフラフ PUBLIC + SUPER 00 03 ; このクラスのCP “Byte” 00 04 ; スーパークラスのCP “java/lang/Object” 00 01 00 05 00 01 00 02 00 06 00 07 00 00 00 02 00 01 00 08 00 09 00 01 00 0A 00 00 00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 01 00 0B 00 00 00 06 00 01 00 00 00 01 00 01 00 0C 00 09 00 01 00 0A 00 00 00 27 00 03 00 01 00 00 00 0B 2A 59 B4 00 02 04 60 B5 00 02 B1 00 00 00 01 00 0B 00 00 00 0A 00 02 00 00 00 04 00 0A 00 05 00 01 00 0D 00 00 00 02 00 0E

実装インタフェースの数 00 21 ; アクセスフラフ PUBLIC + SUPER 00 03 ; このクラスのCP “Byte” 00 04 ; スーパークラスのCP “java/lang/Object” 00 01 ; インタフェース 0x0001個 要は一個 00 05 ; そのCPのリスト 一個だけど. CP05=“java/lang/Runnable” 00 01 00 02 00 06 00 07 00 00 00 02 00 01 00 08 00 09 00 01 00 0A 00 00 00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 01 00 0B 00 00 00 06 00 01 00 00 00 01 00 01 00 0C 00 09 00 01 00 0A 00 00 00 27 00 03 00 01 00 00 00 0B 2A 59 B4 00 02 04 60 B5 00 02 B1 00 00 00 01 00 0B 00 00 00 0A 00 02 00 00 00 04 00 0A 00 05 00 01 00 0D 00 00 00 02 00 0E

フィールドの数 00 01 ; インタフェース 0x0001個 要は一個 00 05 ; CP05=“java/lang/Runnable” 00 02 ; 一個目のフィールドのフラグ 00 06 ; フィールドの名前のCP “s” 00 07 ; フィールドの型へのCP “I” 00 00 ; このフィールドの属性は1つもない 00 02 00 01 00 08 00 09 00 01 00 0A 00 00 00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 01 00 0B 00 00 00 06 00 01 00 00 00 01 00 01 00 0C 00 09 00 01 00 0A 00 00 00 27 00 03 00 01 00 00 00 0B 2A 59 B4 00 02 04 60 B5 00 02 B1 00 00 00 01 00 0B 00 00 00 0A 00 02 00 00 00 04 00 0A 00 05 00 01 00 0D 00 00 00 02 00 0E

メソッド数 00 01 ; インタフェース 0x0001個 要は一個 00 05 ; CP05=“java/lang/Runnable” 00 02 ; 一個目のフィールドのフラグ 00 06 ; フィールドの名前のCP “s” 00 07 ; フィールドの型へのCP “I” 00 00 ; このフィールドの属性は1つもない 00 02 ; メソッドは二つ 00 01 00 08 00 09 00 01 00 0A 00 00 00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 01 00 0B 00 00 00 06 00 01 00 00 00 01 以下省略

メソッドその1 00 02 ; メソッドは二つ 00 01 ; アクセスフラグ PUBLIC 00 08 ; メソッド名へのCP “<init>” 00 09 ; メソッド型へのCP “()V” 00 01 ; メソッド属性の数 1個 00 0A ; この属性の種類のCP “Code” 00 00 00 1D ; 属性の長さ 0x0000001Dバイト=29B 残り29Bがメソッド 00 01 ; stack limit 00 01 ; locals limit 00 00 00 05 ; コードの長さ 5B 2A ; aload_0 B7 00 01 ; invokespecial java/lang/Object/<init>()V B1 ; return 00 00 ; 例外ハンドラの数 = 0 00 01 ; このコードのコード属性の数 00 0B ; 属性の種類のCP “LineNumberTable” 00 00 00 06 ; 属性の長さ 6B 00 01 ; 行番号は1つ 00 00 00 01 ; コード先頭から0B目が, .line 1 以下省略 メソッドその1

メソッド2 00 01 ; アクセスフラグ PUBLIC 00 0C ; メソッド名のCP “run” 00 09 ; 型のCP “()V” 00 01 ; 属性数 1 00 0A ; 属性の種類のCP “Code” 00 00 00 27 ; 属性の長さ 0x27= 39B, 残り39Bがこのメソッド 00 03 ; stack limit=3 00 01 ; locals limit=1 00 00 00 0B ; コードの長さ 0xB=11バイト 2A ; aload_0 59 ; dup B4 00 02 ; getfield Byte/s I 04 ; iconst_1 60 ; iadd B5 00 02 ; putfield Byte/s I B1 ; return 00 00 ; 例外ハンドラ数=0 00 01 ; コード属性の属性数=1 00 0B ; 属性の種類のCP “LineNumberTable” 00 00 00 0A ; 属性の長さAバイト=10バイト 00 02 ; 2行分 00 00 00 04 ; .line 4 00 0A 00 05 ; .line 5 メソッド2

クラス属性 00 01 ; num. of class attribute(s)= 1(d) 00 0D ; class's attr.1(d) name="SourceFile" 00 00 00 02 ; length of attr.=2(d) 00 0E ; filenameのCP "Byte.java"

感想 疲れた. あまり人のやることじゃないな. でも,マイコンの授業だし,一生一度の記念にやってみてください,来週の演習にて. 今日はおしまい