TAL : Typed Assembly Language について 前田俊行 TALとは何か? • Typed Assembly Language • 型づけされたアセンブリ言語 – ベースとして、一般的な普通のアセンブリ言語 を想定している – 既存の様々なCPU上で実現可能と思われる • (例)TALx86 : TALをx86上で実現したもの TALで何ができるか? • 型チェックにより次の2つのことを防ぐこと ができる – 不正なメモリアクセスが行われること – 不正なジャンプが行われること TALの流れ • TALのアセンブラがソースファイルからオ ブジェクトファイルを生成する 1. まずTALのソースを型チェックする 2. 型チェックをパスしたら、オブジェクトファイル を生成する • 生成されたオブジェクトファイルには型情報は一 切含まれない TALのコード例…… の前に • 以降の例ではレジスタに関して次の条件 が満たされているとする – レジスタr1の中身は整数 – レジスタr2の中身は1つのint要素を持つタプル のアドレス – レジスタr3の中身は命令列のアドレス • 上の条件を以下のように書くことにする ∀[].{ r1 : int, r2 : < int >, r3 : ∀[].{ } } 正しいTALコードの例 • r1に与えられた整数を2倍し • r2に与えられたアドレスに保存して • r3に与えられたアドレスへジャンプする ∀[].{ r1 : int, r2 : < int >, r3 : ∀[].{ } } add r4, r1, r1; st r2[0], r4; jmp r3 正しくないTALコードの例(1/6) • 不正なメモリアクセス ∀[].{ r1 : int, r2 : < int >, r3 : ∀[].{ } } ld r4, r1[0]; jmp r3 整数をポインタとし て扱っている!!! 正しくないTALコードの例(2/6) • 不正なメモリアクセス ∀[].{ r1 : int, r2 : < int >, r3 : ∀[].{ } } st r3[0], r2; jmp r3 コードを書き換えよ うとしている!!! 正しくないTALコードの例(3/6) • 不正なメモリアクセス ∀[].{ r1 : int, r2 : < int >, r3 : ∀[].{ } } ld r1, r2[3] jmp r3 データ領域外から 読もうとしている!!! 正しくないTALコードの例(4/6) • 不正なジャンプ ∀[].{ r1 : int, r2 : < int >, r3 : ∀[].{ } } jmp r1 整数をアドレスとして ジャンプしている!!! 正しくないTALコードの例(5/6) • 不正なジャンプ ∀[].{ r1 : int, r2 : < int >, r3 : ∀[].{ } } jmp r2 コードでないアドレスに ジャンプしている!!! 正しくないTALコードの例(6/6) • 不正なジャンプ l1: ∀[].{ r1 : int, r2 : < int >, r3 : ∀[].{ } } mov r3, r1; jmp l1 レジスタr3が飛ぼうとし ているアドレスの条件を 満たしていない!!! TALのプログラムモデル • TALのプログラムは次の3つの要素からな る – レジスタファイル R – ヒープ H – 命令列 I プログラムの要素(1/3) レジスタファイル • 各レジスタにはワード値を保存できる – ワード値とは基本的には次の2種類である • ラベル(ヒープの要素へのポインタ) • 整数 レジスタファイルR ::= { r1 w1, …, rn wn } ワード値 w ::= l (ラベル) i (整数) ?t | w[t] | pack [t, w] as t’ (その他) プログラムの要素(2/3) ヒープ(1/2) • ヒープにはヒープ値を保存できる – ヒープ値とは次の2種類である • ワード値のタプル • 命令列 ヒープ H ::= { l1 h1, …, ln ヒープ値 h ::= < w1, …, wn > code[α1, …, αn]Γ.I hn } (タプル) (命令列) プログラムの要素(2/3) ヒープ(2/2) • 実行時にmalloc命令により新たに領域を 確保できる • 解放はGCによる プログラムの要素(3/3) 命令列 • 命令列Iは次の3通りで構成される – jmp v – halt[t] – (jmpとhalt以外の命令) ; I 命令の種類(1/2) • 算術演算 – add rs, rd, v (vはレジスタや即値である) – sub, mul (addと同様) • ジャンプ命令 – jmp v • 分岐命令 – bnz rs, v 命令の種類(2/3) • メモリ(ヒープ)アクセス命令 – ld rd, rs[i] – st rd[i], rs 命令の種類(2/3) • 特殊命令 – malloc命令 • ヒープから新たにデータ領域を確保する – unpack命令 • Existential Type をunpackする – halt命令 • ある型の値を受けとってプログラムを終了する TALの型(1/2) 値の型 • 型 t ::= –α : 型変数 – int : 整数 – ∀[ α1, …, αn ].Γ : 命令列 – < t1^φ1, … tn^φn > : タプル – ∃α.t : Existential Type • 初期化フラグ φ ::= 0 (未初期化) 1 (初期化済み) TALの型(2/2) プログラムの要素の型 • ヒープの型 – Ψ ::= { l1 : t1, …, ln : tn } • レジスタファイルの型Ψ – Γ ::= { r1 : t1, …, rn : tn } • Type Context – Δ ::= α1, …, αn TALのsubtyping(1/2) • タプル型のsubtyping – 初期化済みの領域を未初期化とみなしてよい Δ Δ ti < t1^φ1, …, ti^1, …, tn^φn > ≦ < t1^φ1, …, ti^0, …, tn^φn > TALのsubtyping(2/2) • レジスタファイル型のsubtyping – 使わないレジスタの型を省略してもよい Δ Δ ti (for 1 ≦ i ≦ m) { r1 : t1, ………….., rm : tm } ≦ { r1 : t1, …, rn : tn } m≧n TALのstatic semantics(一部) • プログラム(H, R, I)の妥当性の判定 – ヒープが妥当であるか、そして – レジスタファイルが妥当であるか、さらに、 – 命令列が妥当であるか H:Ψ Ψ R:Γ ( H, R, I ) Ψ; ; Γ I TALのstatic semantics(一部) • ヒープの妥当性の判定 – ヒープの型が妥当であるか、そして – ヒープの各要素を型づけできるか Ψ { l1 Ψ h1, …, ln hi : ti hval hn } : Ψ Ψ(li) = ti TALのstatic semantics(一部) • レジスタファイルの妥当性の判定 – レジスタの各要素が型づけできるか wi : ti wval (for 1 ≦ i ≦ m) Ψ; Ψ { r1 w1, …, rm wm } : { r1 : t1, …, rn : tn } m≧n TALのstatic semantics(一部) • 命令列の妥当性の判定(一部) – jmp命令 • vが命令列のラベルであるか • レジスタファイルの型が、その命令列へジャンプで きる条件を満たしているか Ψ; Δ; Γ v : ∀[].Γ’ Ψ; Δ; Γ Δ jmp v Γ <= Γ’ TALのstatic semantics(一部) • 命令列の妥当性の判定(一部) – add命令 • rsとvが整数(int)であるか • 残りの命令列が妥当であるか Ψ; Δ; Γ rs : int Ψ; Δ; Γ Ψ; Δ; Γ{ rd : int } Ψ; Δ; Γ v : int I add rd, rs, v ; I TALのstatic semantics(一部) • 命令列の妥当性の判定(一部) – ld命令 • rsはiより大きいサイズのタプルであるか • 読もうとしている領域は初期化済みか Ψ; Δ; Γ rs : < t0^φ0, …, tn-1^φn-1 > Ψ; Δ; Γ{ rd : ti } I φi = 1, 0 ≦ i < n Ψ; Δ; Γ ld rd, rs[i] ; I TALのstatic semantics(一部) • 命令列の妥当性の判定(一部) – st命令 • rdはiより大きいサイズのタプルであるか • rsは書きこもうとしている領域の型と同じ型か Ψ; Δ; Γ rd : < t0^φ0, …, tn-1^φn-1 > Ψ; Δ; Γ rs : ti Ψ; Δ; Γ{ rd : < …, ti^1, … > } I Ψ; Δ; Γ st rd[i], rs ; I 0≦i<n TALの型チェックの例…… の前に • 以降の例では以下の仮定をおく – ヒープHは空とする – レジスタファイルRは以下の型Γを持つと分 かっているとする – Γ = { r1 : int, r2 : < int^0 >, r3 : ∀[].{ } } • 以上の仮定にもとづき、命令列の妥当性 のチェックのみを示す 正しいプログラムの型チェック 型チェックOK ! Γ = { r1 : int, r2 : < int^0 >, r3 : ∀[].{ } } Γ{ r2 : < int^1 > } ≦ { } Γ r3 : ∀[].{ } Γ{ r2 : < int^1 > } Γ jmp r3 r2 : < int^0 > Γ r1 : int Γ st r2[0], r1 ; jmp r3 正しくないプログラムの 型チェック Γ = { r1 : int, r2 : < int^0 >, r3 : ∀[].{ } } 型チェックエラー Γ Γ r2 : < int^0 > ld r4, r2[0] ; jmp r3 ld命令のstatic semanticsのうち φi = 1 を満たさない TALプロジェクトの現状(1/2) • 拡張 : より現実に近づけるために – スタックを扱えるようにしている – 配列を扱えるようにしている – など • 実装 : TALx86 – TALをx86上で実現したものである – 型チェッカ兼アセンブラがある – GCはBoehm-GCを利用している TALプロジェクトの現状(2/2) • 高級言語 : Popcorn – Cの型安全な方言 – PopcornコンパイラはTALのソースを生成する – ちなみに、PopcornコンパイラはPopcornで書 ける TALで何ができないか? • リソースを制御すること • CPU時間やメモリ使用量を制限すること • メモリを明示的に解放すること TALのまとめ • TALとは型づけされたアセンブリ言語であ る • 型チェックにより、次のことを防げる – 不正なメモリアクセス – 不正なジャンプ • ただし、次のことはできていない – リソース制御 – 明示的なメモリ解放 References(1/3) • 以降の論文は以下のTALのページから入手可能 ですhttp://www.cs.cornell.edu/talc/ • Greg Morrisett, David Walker, Karl Crary, and Neal Glew. “From System F to Typed Assembly Language” In the 25th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, page 85-97, January 1998. References(2/3) • Greg Morrisett, Karl Crary, Neal Glew, and David Walker. “Stack-Based Typed Assembly Language” In the 1998 Workshop on Types in Compilation, March 1998. Published in LNCS, volume 1473, page 28-52. SpringerVerlag, 1998. References(3/3) • Greg Morrisett, Karl Crary, Neal Glew, Dan Grossman, Richard Samuels, Frederick Smith, David Walker, Stephanie Weirich, and Steve Zdancewic. “TALx86 : A Realistic Typed Assembly Language” In the 1999 ACM SIGPLAN Workshop on Compiler Support for System Software, pages 2535, May 1999.
© Copyright 2024 ExpyDoc