ELF共有ライブラリ-PLTの動機


11

自己変更コードを使用して、動的にリンクされたライブラリでの関数呼び出しを高速化できますか?

私が理解している限り、ELF共有ライブラリは、一種の間接ジャンプテーブル(プロシージャリンケージテーブル、またはPLT)を使用して、ライブラリ関数の遅延バインディングを有効にします。目的は、最初の呼び出しで関数位置の遅延解決を有効にしながら、コードセグメントのテーブルを変更する必要を回避することです。

ロード時に、または場合によっては最初の関数呼び出しでさえ、そのテーブルのコードを動的に作成する方が高速ではないでしょうか?

プロセス間でコードセグメントをできるだけ共有できるようにしますか(動的テーブルはプロセス専用になります)?セキュリティ上の理由からですか(書き込み可能なコードは実行可能であってはなりません -しかし、JITは常にそうしているので、実際にプログラムを起動する前に、ローダー書き込み権限を追加および削除できます)。

それともそれらの組み合わせであり、関数呼び出しごとの小さなパフォーマンスの向上は努力の価値がないでしょうか?

回答:


8

私たちはx86アーキテクチャについて話していると思います。

コードセグメントは常に読み取り専用であるため、私が知っているほとんどのUNIXベースのオペレーティングシステムで(そしてそれだけでなく)使用されているプロテクトモードで自己変更コードを使用することはできません。ローダーはそれを制御しません-それはカーネルのメモリ管理サブシステムによって処理されているものです。

しかし、あなたが言うように「ロード時にそのテーブルのコードを作成する」ことができたとしても、それは共有ライブラリの全体的な目的に反するでしょう。このように、各プロセスは、そのアドレス空間にライブラリの関数の「プライベート」コピーを持ち、メモリフットプリントを効果的に増やします。共有ライブラリが作成された理由の1つは、この問題に対処することでした。

あなたが説明するプロセス全体は非常に複雑であり、現在使用されているPLTメソッドよりも多くの処理サイクルがかかり、おそらく、新しくて興味深いセキュリティ問題が発生するでしょう。


2
mprotect(2)システムコールを使用して、.textセグメントページを書き込み可能および実行可能にすることができます。
Bruce Ediger、

1
正解です。おそらくそれは平均的なUNIXベースのシステムではちゃんと機能しますが、mprotect(2)に制限を適用するPaXなどで誰かがシステムを強化しようとすると、リンクプロセス全体が壊れます。
dkaragasidis

(以前のコメントで@BruceEdigerについて言及し損ねたようです)
dkaragasidis

1

ELF DSOは、フラグ(DF_TEXREL)を使用して、テキストセクション(通常は読み取り専用)を変更して再配置が必要であることを通知します。ただし、PIEの位置に依存しないコードと一緒にジャンプテーブルアプローチを使用する方が最適です。

http://www.akkadia.org/drepper/dsohowto.pdfで見つかりましたが、他のリソースでもこれについて言及しています)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.