410 likes | 626 Views
TAL : Typed Assembly Language について. 前田俊行. TAL とは何か ?. Typed Assembly Language 型づけされたアセンブリ言語 ベースとして、一般的な普通のアセンブリ言語を想定している 既存の様々な CPU 上で実現可能と思われる ( 例 )TALx86 : TAL を x86 上で実現したもの. TAL で何ができるか ?. 型チェックにより次の 2 つのことを防ぐことができる 不正なメモリアクセスが行われること 不正なジャンプが行われること. TAL の流れ.
E N D
TALとは何か? • Typed Assembly Language • 型づけされたアセンブリ言語 • ベースとして、一般的な普通のアセンブリ言語を想定している • 既存の様々なCPU上で実現可能と思われる • (例)TALx86 : TALをx86上で実現したもの
TALで何ができるか? • 型チェックにより次の2つのことを防ぐことができる • 不正なメモリアクセスが行われること • 不正なジャンプが行われること
TALの流れ • TALのアセンブラがソースファイルからオブジェクトファイルを生成する • まずTALのソースを型チェックする • 型チェックをパスしたら、オブジェクトファイルを生成する • 生成されたオブジェクトファイルには型情報は一切含まれない
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’ (その他)
ヒープ H ::= { l1 h1, …, ln hn } プログラムの要素(2/3)ヒープ(1/2) • ヒープにはヒープ値を保存できる • ヒープ値とは次の2種類である • ワード値のタプル • 命令列 ヒープ値 h ::= < w1, …, wn > (タプル) code[α1, …, αn]Γ.I (命令列)
プログラムの要素(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
Δ ti Δ < t1^φ1, …, ti^1, …, tn^φn > ≦ < t1^φ1, …, ti^0, …, tn^φn > TALのsubtyping(1/2) • タプル型のsubtyping • 初期化済みの領域を未初期化とみなしてよい
Δ ti (for 1 ≦ i ≦ m) Δ { r1 : t1, ………….., rm : tm } ≦ { r1 : t1, …, rn : tn } TALのsubtyping(2/2) • レジスタファイル型のsubtyping • 使わないレジスタの型を省略してもよい m ≧ n
H : Ψ Ψ R : Γ Ψ; ; Γ I ( H, R, I ) TALのstatic semantics(一部) • プログラム(H, R, I)の妥当性の判定 • ヒープが妥当であるか、そして • レジスタファイルが妥当であるか、さらに、 • 命令列が妥当であるか
Ψ Ψ hi : ti hval Ψ(li) = ti { l1 h1, …, ln hn } : Ψ TALのstatic semantics(一部) • ヒープの妥当性の判定 • ヒープの型が妥当であるか、そして • ヒープの各要素を型づけできるか
wi : ti wval (for 1 ≦ i ≦ m) Ψ; m ≧ n Ψ { r1 w1, …, rm wm } : { r1 : t1, …, rn : tn } TALのstatic semantics(一部) • レジスタファイルの妥当性の判定 • レジスタの各要素が型づけできるか
Ψ; Δ; Γ v : ∀[].Γ’ Δ Γ <= Γ’ Ψ; Δ; Γ jmp v TALのstatic semantics(一部) • 命令列の妥当性の判定(一部) • jmp命令 • vが命令列のラベルであるか • レジスタファイルの型が、その命令列へジャンプできる条件を満たしているか
Ψ; Δ; Γ v : int Ψ; Δ; Γ rs : int Ψ; Δ; Γ{ rd : int } I Ψ; Δ; Γ add rd, rs, v ; I TALのstatic semantics(一部) • 命令列の妥当性の判定(一部) • add命令 • rsとvが整数(int)であるか • 残りの命令列が妥当であるか
Ψ; Δ; Γ rs : < t0^φ0, …, tn-1^φn-1 > Ψ; Δ; Γ{ rd : ti } I φi = 1, 0 ≦ i < n Ψ; Δ; Γ ld rd, rs[i] ; I TALのstatic semantics(一部) • 命令列の妥当性の判定(一部) • ld命令 • rsはiより大きいサイズのタプルであるか • 読もうとしている領域は初期化済みか
Ψ; Δ; Γ rd : < t0^φ0, …, tn-1^φn-1 > Ψ; Δ; Γ rs : ti Ψ; Δ; Γ{ rd : < …, ti^1, … > } I Ψ; Δ; Γ st rd[i], rs ; I 0 ≦ i < n TALのstatic semantics(一部) • 命令列の妥当性の判定(一部) • st命令 • rdはiより大きいサイズのタプルであるか • rsは書きこもうとしている領域の型と同じ型か
TALの型チェックの例……の前に • 以降の例では以下の仮定をおく • ヒープHは空とする • レジスタファイルRは以下の型Γを持つと分かっているとする • Γ = { r1 : int, r2 : < int^0 >, r3 : ∀[].{ } } • 以上の仮定にもとづき、命令列の妥当性のチェックのみを示す
型チェックOK ! Γ r2 : < int^0 > Γ r3 : ∀[].{ } Γ r1 : int Γ{ r2 : < int^1 > } ≦ { } Γ{ r2 : < int^1 > } jmp r3 Γ st r2[0], r1 ; jmp r3 正しいプログラムの型チェック Γ = { r1 : int, r2 : < int^0 >, r3 : ∀[].{ } }
Γ r2 : < int^0 > Γ ld r4, r2[0] ; jmp r3 正しくないプログラムの型チェック 型チェックエラー Γ = { r1 : int, r2 : < int^0 >, 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. Springer-Verlag, 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 25-35, May 1999.