ウィンビー国際的アイドル化計画

Download Report

Transcript ウィンビー国際的アイドル化計画

オペレーティングシステム発表資料
Win32 on BeOS
プラットフォームの違いとは?

CPUの違い


APIの違い


実行形式の違い

エミュレーション可能だが、パ
フォーマンスは落ちる
仕様がわかっていれば互換
APIを用意する事で解決
直接実行するにはOSのサ
ポートが必要だが、間接的に
実行するならアプリケーション
でのサポートで十分
実装ポリシー
やった事




PE(COFF)ローダの実装
膨大なWin32 APIを(必要なとこだけ)実装
gccの移植と改変(DirectXとCOM)
メモリ再配置不能問題の対処
動作例
実行形式
メモリ空間
プログラムコード
初期化値付きデータ
未初期化データ
・プログラムのサイズ、場所
・初期化データのサイズ、場所
・未初期化データのサイズ
・再配置情報
・共有ライブラリ情報
.
.
.
実行ファイル
スタック
ヘッダ情報
カーネル領域
プログラムコード
初期値データ
共有ライブラリ
プログラム
プログラム側の処理としてはDLL関数呼び出しは、
ExternLib[func_number](args);
といった処理と等価になっている。
0x08000000[0]();
0x08000000
0x10000000
0x10000240
0x10000614
.
.
ExternLibという関数テーブルは、プログラムロード
時にOSによって適切な値が設定される。
関数テーブル
0x10000000
共有ライブラリ
再配置情報
再配置情報
アプリケーション
.
mov ax, 0x80403f00
.
.
call 0x80402024
.
補正
アプリケーション
.
mov ax, 0x00403f00
.
.
call 0x00402024
.
プロセスの生成
fork→exec系
create process系
親
fork
親
子
exec
CreateProcess
子
アプリケーションの間接実行

直接実行(OS)
(Kernel)
読み込み・解釈
リソース割り当て

(User)
間接実行(ユーザー)
(Kernel)
(中継プロセスの)
起動要求
読み込み・解釈
起動
(User)
起動要求
(中継プロセスの)
(中継プロセスの)
リソース割り当て
起動
(Win32プロセスの)
読み込み・解釈
リソース割り当て
リソース要求
(Win32プロセスの)
起動
Windows/BeOSのメモリ配置
Windows
HAL
各種プール・キャッシュ・エントリ
メモリマップドファイル
BeOS
0xFFFFFFFF
共有ライブラリ
カ
ー
ネ
ル
領
域
0xEC000000
実行イメージ
0xA0000000
ユ
ー
ザ
ー
領
域
カーネル
0x80000000
ユ
ー
ザ
ー
領
域
実行イメージ・共有ライブラリ
0x30000000
0x10000000
0x00000000
カ
実行ファイル・共有ライブラリのキャッシュ ー
ネ
ル
領
域
物理メモリ
カーネル
Windowsに置ける標準的な実行イメージ配置場所にBeOSではカーネルが存在してい
る!!
再配置が必要不可欠
動的再配置(1) - 仮配置
実際の配置場所
再配置情報がない場合には、必ず仮
定されたアドレスへ配置する必要があ
るのだが、それは不可能なので、とり
あえず必要な補正は行えないが、別の
アドレスへ配置する。
(本来の配置場所)
実行イメージ
動的再配置(2) - クラッシュ
.
.
call 0x00402024
.
.
.
.
巻き戻し・再実行
解析・修正
クラッシュ
アドレス
補正処理
.
.
call 0x80402024
.
.
.
.
動的再配置(3) - 予測
下の例のように、単純に問題個所だけ補正していた
のでは解決できない場合が多々ある!
char buffer[1024];
char *p;
for (p = buffer; p != &buffer[1024]; p++) *p = 0;
1. 最初の「*p = 0」で、不正なアドレスへのアクセスが発生。「p」の指すアドレスが補正される。
2. この状態では「&buffer[1024]」という値は補正前の値になっている。
3. 終了条件に一致せず、永遠にメモリを「0」で埋め尽くす。
4. スタックの破壊。この状態からはもはや復帰不能。
問題個所周辺のプログラム・データの流れについて、
十分な解析・予測の上で補正する必要があり、これ
を自動的に完全動作させるのは不可能。
おまけ(1)
CoffError
Coff::SetSignal
(void)
{
CoffError rc = COFF_ERR_UNKNOWN;
struct sigaction sa;
sa.sa_handler = (__signal_func_ptr)CoffSigSegv;
sa.sa_mask = 0;
sa.sa_flags = 0;
sa.sa_userdata = (void *)this;
struct sigaction old;
if (0 == sigaction(SIGSEGV, &sa, &old)) {
old_sigsegv = old.sa_handler;
rc = COFF_ERR_OK;
}
return rc;
}
おまけ(2)
.section
.text
.p2align
.global
.type
CoffSigSegv:
pushl
movl
subl
movl
movl
movl
lea
pushl
movl
pushl
movl
pushl
movl
pushl
call
movl
movl
movl
movl
popl
ret
nop
.Lfel:
.size
.rodata
2
CoffSigSegv
main, @function
%ebp
%esp, %ebp
$0x0c, %esp
%ebx, -0x04(%ebp)
%esi, -0x08(%ebp)
%edi, -0x0c(%ebp)
-0x0c(%ebp), %eax
%eax
0x10(%ebp), %eax
%eax
0x0c(%ebp), %eax
%eax
0x08(%ebp), %eax
%eax
SigSegv__4CoffiP4CoffP5vregsP8_xxxregs
-0x04(%ebp),%ebx
-0x08(%ebp),%esi
-0x0c(%ebp),%edi
%ebp, %esp
%ebp
CoffSigSegv,.Lfel - main
おまけ(3)
void
Coff::SigSegv
(int no, Coff *obj, vregs *regs, xxxregs *xregs)
{
obj->mSigSegv(regs, xregs);
}