Linuxアプリケーションは、カーネルのシステムコールABIとCライブラリという2つの異なるインターフェースに依存します。ABIは、特定のアーキテクチャでカーネルへ移行する方法を定義します。Cライブラリは、プログラムがコンパイル時にリンクするISO CおよびPOSIXインターフェースを実装し、プロセスの起動コード、動的ローダー、ネームサービス検索、スレッドサポート、ロケール処理、さらに1つのシステムコールには対応しない多数のインターフェースを追加します。したがって、カーネルは完全なCランタイムを提供しません。
GNU libcの起源とリリース #
Richard Stallmanは1983年9月27日にGNUプロジェクトを発表しました。GNU libcの開発は1980年代後半に続き、Roland McGrathが初期の公開貢献者の一人でした。1988年のGNU Bulletinには、ほとんどのライブラリが完成していたと記載されています。
初期のリリース資料は慎重に扱う必要があります。GNU FTPアーカイブにはglibcの歴史的なパッチとリリースアーカイブが保存されていますが、アーカイブの収録範囲は完全なリリースデータベースではありません。たとえば、glibc 1.x時代のリリースとパッチでは、入手可能性や日付の慣例が異なります。アーカイブは、後から作成されたバージョン一覧やパッケージメタデータより強力な証拠です。
glibc 2.0は1997年1月にリリースされ、2.x系列がGNU libcの継続的なABI系列になりました。現在のソース、リリース資料、マニュアルは、sourceware.orgおよびglibcソースリポジトリでプロジェクトによって保守されています。「glibc 2.x」はソースとABIのファミリーを表します。サポート対象の古いインターフェースとの互換性は、リリースごとにメジャーライブラリのファイル名を変更するのではなく、ABIの規則によって管理されます。
Linux libcからglibcへ #
初期のLinuxシステムはGNU libcのコードを適応していました。その後、Linux開発者はLinux固有のフォークを保守し、一方でupstreamのglibcは別個に開発されました。このフォークは一般にLinux libcと呼ばれます。その共有ライブラリ世代にはlibc4とlibc5が含まれます。
- libc4以前は、歴史的な
a.out実行可能形式の環境でプログラムをサポートしていました。 - libc5は、LinuxがELF共有オブジェクトへ移行する時期に対応し、ディストリビューションで使用される現代的な動的リンクモデルを可能にしました。
- その後、ディストリビューションはGNU libc 2.xへ移行しました。
libc6などのDebian派生パッケージ名は、glibc 2.x共有ライブラリABIの世代を示すものであり、「glibcバージョン6」を意味しません。
kernel.orgのlibc5アーカイブには、後期のソーススナップショットが保存されています。これはソースの歴史を調べる適切な出発点です。ただし、特定のフォーク時点、リリース日、またはメンテナーに関する主張は、対応するアーカイブ済みツリーまたはリリース告知と照合する必要があります。ディレクトリの再編成やコードの取り込みがあるため、単一のソース系譜を主張すると誤解を招きます。
libcの移行がABI移行である理由 #
ライブラリはプロセスABIに関与するため、libcの置き換えには実行可能ファイルの再コンパイル以上の作業が必要です。
- 起動オブジェクトが
mainへのエントリとプロセス終了を構成する。 - 動的ローダーが共有オブジェクトを検索し、シンボルを解決する。
- エクスポートされた構造体、呼び出し規約、バージョン付きシンボルによって、古いバイナリのロードを継続できるかどうかが決まる。
- リゾルバーとName Service Switch(NSS)モジュールがサービス検索を実装する。
- POSIXスレッドがユーザー空間の状態をカーネルの同期プリミティブと協調させる。
したがって、アップグレードではローダー、開発用ヘッダー、共有ライブラリ、NSSモジュール、パッケージマネージャー、リカバリーツールの整合性を維持する必要があります。あるlibcに対してビルドされたバイナリは、利用できないシンボルバージョンを必要とする場合や、ELFのPT_INTERPセグメントに記録されたインタープリターが見つからない場合、mainの前に失敗する可能性があります。glibcのABI一覧には、サポート対象アーキテクチャごとに公開されるシンボルセットとバージョンの基準が異なることが記載されています。
LinuxのCライブラリの選択肢 #
LinuxのシステムコールABIを実装するCライブラリはglibcだけではありません。
- muslは、コンパクトで標準指向の設計を重視しており、静的リンクシステムや最小構成のシステムで広く使用されています。
- uClibc-ngは、機能を構成可能な組み込みLinuxシステムを対象としています。
- AndroidのBionicは、Androidプラットフォーム向けに最適化されています。
ソース互換性は、バイナリ互換性を意味しません。glibc拡張、シンボルバージョン、動的ローダーの動作、NSSモジュール、ABIの詳細により、ソースが移植可能に見える場合でもプログラムがglibc固有になることがあります。現在の動作については保守されているプロジェクトのマニュアルを使用し、歴史的なバイナリを調査する場合は、リリースアーカイブ、元のヘッダー、対象アーキテクチャのABI、対応するカーネルバージョンを使用してください。
歴史的ドキュメントの読み方 #
現在のマニュアルページは現在のインターフェースを記載し、動作がいつ導入または変更されたかを記録している場合があります。歴史的なソースとバイナリは、元のヘッダー、Cライブラリ、アーキテクチャABI、カーネルの動作を基準に解釈する必要があります。アーカイブ資料はlibc5からglibcへの移行の背景を提供しますが、現在のビルドでは、選択したCライブラリとディストリビューションが保守するドキュメントに従う必要があります。
コメント
GitHub で閲覧・コメントする(投稿にはログインが必要です)