関数は実行時にどのように解析されますか?

関数は実行時にどのように解析されますか?

Linuxの関数は実行時にどのように解析されますか?純粋に名前ベースで、私が想像する「シンボルテーブル」ですか、それとも一種のハードコーディングされたアドレスですか? Musl libcとglibcを再コンパイルする必要があることをオンラインで読みましたが、同じシンボルをエクスポートしてはいけませんか?シンボルはどのように機能しますか?

ベストアンサー1

プログラムはランタイム前にメモリにロードされるため、関数はベースアドレスに基づいて特定のメモリアドレスにマップされます。関数へのすべての呼び出しは相対メモリアドレスにコンパイルされます。シンボルテーブルは通常バイナリに含まれていますが、アドレスマッピングはデバッグ目的で人間が読める名前に反転されます。nm -D /usr/lib/libc.so.6glibcのシンボルテーブルを表示するには、一般的なLinuxインストールを試してください。

バイナリ互換性の点で、glibcとMuslは共用標準を実装していますが、独自のヘッダファイルに反映する必要があるさまざまな機能を持っています。したがって、ほとんどのLinuxディストリビューションには共通の標準ライブラリヘッダーパッケージがない理由があります。代わりに、各ライブラリにバンドルされています。 )。

muslのよくある質問:

muslはglibcと互換性がありますか?

はい、いいえ。ソースコードとバイナリレベルでは、muslの目的は、バグ互換性ではなく、glibcとある程度機能的互換性を達成することです。 glibcを使用するアプリケーションがmuslのコンパイルに失敗した場合、その理由は通常次のいずれかです。

  • 1つのヘッダーを含めると、関連していない他のヘッダーのシンボルが公開されると想定されます。これはアプリケーションエラーであり、欠落している#includeディレクティブを追加するのと同じくらい簡単に修正できます。
  • アプリケーションに公開してはいけないglibcヘッダーの実装の詳細を使用してください。これはアプリケーションエラーでもあり、通常は検索と置換(ソースコードで__pid_tをpid_tに置き換えること)で解決できます。
  • muslで実装されていないインターフェイスを使用してください。この問題は、アプリケーションのインターフェイス使用を選択的に作成するか、または欠落しているインターフェイスをサポートするようにmuslを拡張することによってのみ解決できます。

バイナリ互換性はより制限的ですが、新しいバージョンのmuslでは着実に改善されます。現在、いくつかのglibc接続共有ライブラリはmuslを使用してロードできますが、muslが/lib/ld-linux.so.2の場所にある場合、最も単純なglibc接続アプリケーション以外のすべてのアプリケーションは失敗します。

おすすめ記事