  The Linux ELF HOWTO
  Daniel Barlow <daniel.barlow@linux.org>
  $Date: 1999/02/22 19:20:41 $ $Revision: 1.1.1.1 $
  こじまみつひろ <isle@st.rim.or.jp> (11/4)

  この文書はあなたの Linux システムで ELF バイナリ形式のプログラムをコン
  パイルして動かすための方法をまとめたものです。この文書は大きく、(1)ELF
  とは何か、なぜ移行しなければならないか、(2)どうすれば ELF 形式が使える
  ようになるのか、(3)ELF にすれば何ができるのか、という 3 つの部分に分か
  れています。私が研究にいそしんでいるフリをしている間、この文書は放った
  らかしになっていましたが、最近 Linux 2.0 の情報を追加して全体をオーバ
  ーホールしました。

  1.  ELF とは何か？ 簡単な紹介

  ELF(Executable and Linking Format)は元々 USL(Unix System Laboratories)
  で開発されたバイナリ形式で、現在は Solaris や System V Release 4 が採
  用しています。 Linux がかって使っていた a.out 形式に比べて、ELF 形式は
  柔軟性に富むので、GCC と C ライブラリの開発者たちは Linux の標準的なバ
  イナリ形式を ELF にしようと決定しました。

  「柔軟性に富む」というのは、標準的なアプリケーションプログラマに 2 つ
  の利点を与えます。

  o  ELF 形式を使えば共有ライブラリがずっと簡単に作成できます。通常、
     -fPICオプションを付けてコンパイルしたオブジェクトファイルを、

        gcc -shared -Wl,-soname,libfoo.so.y -o libfoo.so.y.x *.o

  というコマンドラインでリンクするだけです。

  これが複雑に見えるようならば、多分 a.out 形式で同じような共有ライブラ
  リを作る方法を御存知ないのでしょう。a.out 形式で共有ライブラリを作るた
  めには、ライブラリを 2 度コンパイルして、ライブラリが将来使うであろう
  全てのデータのための空間をあらかじめ予約し、予約されたアドレス空間は全
  ての開発者間で登録しておかねばなりません(詳しくは
  <ftp://tsx-11.mit.edu/pub/linux/packages/GCC/src/tools-2.17.tar.gz> に
  ある 20ページを超える文書をご覧ください)。

  o  動的ローディング(動作中のプログラムがモジュールをロードできる機
     能)をずっと単純に実現できる。この機能は Perl 5 や Python, Java など
     で使われています(さまざまな種類のインタープリタの起動に使われま
     す)。動的ローディング機能のもう一つの使い道は super-fast MUD です。
     この場合、プログラムを停止して再起動することなく、新しいプログラム
     をコンパイルして動いているプログラムに組みこむことが可能になりま
     す。

  このような利点に対して、ELF を使うと多少遅くなる、という反論もありま
  す。 1% から 5% くらい遅くなるというのが通説ですが、実際のテストが示す
  結果を見ると、その差は同時に起っているさまざまなノイズに隠されてしまう
  程度のもののようです。TeX や Postscript のビューワ/プリンタを持ってい
  れば、 SunSite などから speed.comp-1.0.tar.gz という ELF と a.out の速
  度を比較した論文を入手して読むのもいいでしょう。

  ELF 形式が遅くなるのは ELF のライブラリコードがポジションインデペンデ
  ントでなければならないことに由来します(コンパイル時の -fPIC オプション
  が意味することです)。ポジションインデペンデントであるため、一つのレジ
  スタをオフセット保持用に使わなけれなばならなくなります。そのため、変数
  を保存するのに使えるレジスタが一つ減ってしまいます。特に 80x86 CPU で
  は一般的に使えるレジスタが元々不足しています。速度に差が出るのは共有ラ
  イブラリのコードに限られていることに注意してください。アプリケーション
  やカーネルでは a.out と ELF の間で速度差はありません。

  1.1.  ELF は何ではないか？

  ELF 化すれば何ができるかについて、多くの誤解が広まっています。

     SVR4 や Solaris のプログラムを動かすためのものではありません
        ELF は SVR4 システムと同じ形式のバイナリの`容器'ですが、だからと
        言って、 ELF にすれば SVR4 用のプログラムが突然 Linux でも使える
        わけではありません。この関係はディスクフォーマットと似ているで
        しょう -- Linux のプログラムを MSDOS や Minix のフォーマットの
        ディスクに保存したり、その逆も可能ですが、だからといってそれぞれ
        のシステムが互いのプログラムを実行できるわけではありません。

        (そのプログラム自身に依存しますが)他の x86 Unix 用のプログラムを
        Linux で動かすことも可能かも知れませんが、この HOWTO では、その
        ための説明は致しません。まず(tsx-11.mit.edu などにある)iBCS カー
        ネルモジュールについて調べることから始めましょう。

     プログラムが小さくなるわけでも、速くなるわけでもありません。
        ずっと簡単に共有ライブラリが作れるようになったので、複数のプログ
        ラム間で共通しているコードをライブラリ化すれば、結果としてより小
        さなプログラムを作成すことも可能かも知れませんが、一般的に言っ
        て、同じコンパイラオプションを指定してバイナリが a.out よりも小
        さくなったなら、たまたま運が良かったか、コンパイラのバージョンが
        違うためでしょう。もし「速く」なったら、ちょっとびっくりです。共
        有ライブラリを活用してプログラムが小さくなったため、スワップが
        減ったり、より多くのメモリを利用できるようになったならば、速くな
        ることもありえますが。

     全てのバイナリを置き替える必要はありません
        この文書の手順に従えば、ELF と a.out の双方をコンパイルして動か
        すシステムを構築できます。新しいプログラムはデフォルトでは ELF
        形式にコンパイルされますが、これはコマンドラインスイッチで変更で
        きます。ELFと a.out を同時に動かした場合、両方の C ライブラリを
        読みこまなければならなくなるなど、多少メモリの使用効率は悪くなり
        ます。もっとも、この差はメモリを 6Mb 積んだマシンではほとんど気
        づかない程度だそうですので(8Mb のマシンではもっと気づきませんで
        した)、あまり気にすることも無いでしょう。何しろ、Emacs や静的リ
        ンクされた Mosaic/Netscape といったメモリを大食いするプログラム
        を毎日のように 使っているでしょ？ :-)

     トールキンとは関係ありません
        少なくともこの文脈においては。

  1.2.  なぜ ELF へ移行すべきか

  ELF を使えるようにシステムをアップグレードするのには、主に 2 つの理由
  があります：まず第一に、上述したようにプログラムがずっと柔軟にできるこ
  と。第二に、第一とも関連しますが、だれもがそうしようとしている(あるい
  は既にそうした)から。将来の C ライブラリや GCC は ELF 用のみがリリース
  されますし、それ以外のプログラムの開発者たちも ELF の方へ進むはずで
  す。

  ELF の安定性に不安を感じている人々もいます(愉快な話ではありませんが、
  当然のことです)。Linux の世界で ELF は 1994 年の夏から存在していまし
  た。その後 1995 年の 5 月か 6 月ごろ一般に公開されました。現在では、致
  命的な問題は存在しないでしょう。大きなバージョンアップをする時にしばし
  ば起きるように、きちんと動いているシステムを壊しかねないと感じている人
  もいるかも知れません。でも、このバージョンアップはもはや最先端の技術で
  はありません。開発用のシステムや他の人がコンパイルしたバイナリを動かし
  たい場合では、ELF は必須のものになりつつあります。カーネルを v2.0 にバ
  ージョンアップする際に ELF へスイッチすることを考えてください。

  1.3.  ELF への移行の仕方

  この HOWTO が最初に書かれた時には ELF へ移行する方法は、ここに述べた方
  法一つしかありませんでした。今日では、高品質で簡単に新しいバージョンを
  インストールできるようなディストリビューションも存在します。あなたのマ
  シンをお好みの設定にチューニングすることにかかる時間を考えると、以下に
  述べるライブラリやコンパイラをごちゃごちゃにしてしまうよりは必要なデー
  タを全てバックアップして最新の Red Hat や Debian をインストールしてし
  まった方がいいかも知れません。

  強調しておきますが、以下に述べるインストール方法はそれ自身としては簡単
  な仕事です(新しいソフトウェアをダウンロードする時間を除けば一時間もあ
  れば十分でしょう)が、システムが再起動できなくなるような失敗の可能性も
  あちこちにあります。共有ライブラリをバージョンアップしたくなかったり、
  ldconfig や ldd といったコマンドを御存知なかったり、ソースコードから必
  要なプログラムを作成するのが面倒だったりするならば、「より簡単な方法」
  を選ぶ方がいいでしょう。それも嫌な場合、とにかくこういう風に考えてみて
  ください -- 「完全な ELF システム」のためには、誰かが 全てのバイナリを
  その上でコンパイルし直さなければならないのです。

  それでもやりますか？

  2.  インストール

  2.1.  バックグラウンド

  ここに示す移行手順の目的は、a.out と ELF の双方をコンパイルして動かす
  ことのできるシステムを構築することです。そのためには双方のプログラムが
  適切な共有ライブラリを見つけられなければなりません。このためには、他の
  いくつかのシステムがやっているように、単純に `/lib と /usr/lib そして
  コンパイル時に指定されたディレクトリを全て探す' という方法よりも多少な
  りとも賢い方法が必要です。

  賢い方法の中心に位置するのがシステムの上に一つ、あるいは二つ、存在する
  動的ローダです。a.out のプログラム用には /lib/ld.so、 ELF のプログラム
  用には /lib/ld-linux.so.1 がそれぞれ動的ローダになっています。コンパイ
  ラやリンカは出力するプログラムにライブラリへの絶対パスを埋めこむことは
  しません。その代りに、ライブラリ名と適切な動的ローダへの絶対パスを埋め
  こみます。そして、実行時に、(動的ローダが)適切なライブラリに結びつける
  わけです。ここに重要な秘密があります -- すなわち、あるプログラムが使っ
  ているライブラリが別のディレクトリに動かされても、プログラムを再コンパ
  イルする必要はなく、ld.so (あるいはld-linux.so.1) に新しいディレクトリ
  を探しに行くように指示するだけで済みます。これが以下に述べるディレクト
  リを入れ替える操作の骨子です。

  上記から導かれる結論として、ld.so を削除したり移動させたりすれば、動的
  リンクを使っているプログラムは全て機能しなくなる、ということがわかりま
  す。これは良くないことである、と一般に考えられています。

  ですから、基本的な計画としては、ELF 用の開発環境(コンパイラ、インクル
  ードファイル、ライブラリ)を、今は a.out 用のものがある
  /usr/{bin,lib,include}に置き、a.out 関連のファイルは
  /usr/i486-linuxaout/{bin, lib, include} へ移すことにします。
  /etc/ld.so.conf はライブラリが見つかるであろう場所全てのリストになって
  おり、ldconfig は ELF と a.out を見わける能力を持っています。

  ライブラリの場所には多くの例外があります。

  o  古いプログラムのいくつかは ld.so を使わずに作られています。これらの
     プログラムはライブラリが別の場所に移動すれば動かなくなります。です
     から、もしそのようなプログラムを使っているならば、 libc.so* や
     libm.so は/lib にそのまま残しておかねばなりません。ELF 用のライブラ
     リは主バージョン番号が異なっているので、a.out と同じディレクトリに
     置いても上書きしてしまうことはありません。古い X 関連のライブラ
     リ(version 6 以前)もそのままの場所に残しておくのがいいでしょう。一
     方、新しいバージョン(libX*so.6 は別の場所に置かねばなりません。古い
     ライブラリを動かすと、xview 関連のプログラムが動かなくなり、新しい
     ライブラリを別の場所に置くようにしないと ELF 用の X ライブラリをイ
     ンストールした際に古いものに上書きしてしまいます。

     上記以外のライブラリを必要とする ld.so を使っていないプログラムをお
     持ちなら(どのプログラムが該当するか分っていれば、前もってそれらのプ
     ログラムを ldd で調べて、必要なライブラリをチェックしておきましょ
     う)、2 つの方法があります。一つは、ELF ライブラリを仮のディレクトリ
     に展開して、必要なライブラリに上書きされるかどうかを確認することで
     す。もし上書きされるようならば、ELF 版のライブラリは /lib とは違う
     場所、例えば /usr/i486-linux-lib へ置くようにします。そして
     ldconfig してそのディレクトリが参照されるようにします。もう一つの方
     法は問題のプログラムの新しいバージョンを入手してコンパイルし直して
     しまうことです。これはソースコードが入手可能ならば、そう悪いアイデ
     アではありません。

  o  /usr と / が別のパーティションになっている場合、/lib から動かすライ
     ブラリは、/usr のあるパーティションではなく、ルートパーティションの
     あるディスク上に置く必要があります。以下の例では /lib-aout に置くよ
     うにしています。

  2.2.  始める前に --- 注意すべきポイント

  o  ELF フォーマットのバイナリを動かすことのできる 1.1.52 以降のカーネ
     ルを使っていることを確認してください。1.2.13 でも大丈夫です。ほとん
     どの 1.3.x 同様、2.0.0(この文書を書いているいる時点での最新版)でも
     動きますが、2.0 がリリースされた今となっては、古い「実験版」のカー
     ネル(1.3.x) を使う必要はないでしょう。

  o  Slackware の救急(rescue)デイスクのような boot/root ディスクを用意し
     ておきましょう。多分必要になることはありませんが、必要になった時に
     手元に無いと散々な目に遭います。同様に、mv や ln 等のファイル操作用
     のコマンド(実際のところ、shell の内蔵コマンドで必要な作業はほぼ可能
     だと思いますが)を静的リンクで作っておくことも「治療よりも予防」的な
     準備として役立つかも知れません。

  o  もし、ELF の開発を追いかけていたなら、/lib/elf に ELF 用のライブラ
     リ(通常は libc.so.4 など)があるかも知れません。これらのライブラリを
     使うアプリケーションは再コンパイルする必要があります。その上でこの
     ディレクトリは削除しましょう。/lib/elf ディレクトリは不要です。

  o  最近の Linux では `FSSTND(ファイルシステムスタンダード)' に従って、
     標準的なファイルシステムは配置されるようになってきましたが、そうで
     ないシステムもまだまだあることでしょう。もし以下の説明で `/sbin/何
     たら' を使うようになっているのに、自分のシステムには /sbin ディレク
     トリが無い場合、それらのプログラムは /bin か /etc にあるはずです。
     新しいプログラムをインストールする場合、特にこの問題には注意してく
     ださい。コマンドを検索するパスリストで /etc が /sbin よりも前になっ
     ていれば、知らないうちに(/etc/にある)古いバージョンのコマンドを起動
     してしまい、妙なエラーを起す場合があります。

  o  ELF へ移行する際には誰もコンピュータを使っていない時間を選ぶかシン
     グル・ユーザーモードで行いましょう。間違いを起さないように、フロッ
     ピーからブートして作業するのもいいアイデアでしょう。でも、私個人と
     しては多少のの面白い要素も残しておきたいと思っています :-)

  2.3.  必要なものは、、、

  必要なパッケージは、 <ftp://tsx-11.mit.edu/pub/linux/packages/GCC/> や
  <ftp://sunsite.unc.edu/pub/Linux/GCC/> から入手可能です。両サイトとも
  多くの場所にミラーされていますので、可能なかぎり近くにあるミラーサイ
  ト[訳注：日本ならば <ftp://ftp.iij.ad.jp/pub/linux/sunsite/GCC/> や
  <ftp://ftp.spin.ad.jp/pub/linux/sunsite.unc.edu/GCC/> など ] から探し
  てください。その方があなたにとっても、みんなにとっても、結局速く入手で
  きることになります。

  以下に示すパッケージ(リストにあがっているバージョンかより新しいもの)が
  必要です。これらをダウンロードして、それぞれに付属している文書を読んで
  みてください：必要な文書はたいてい release.packagename という名前に
  なっています。以下に示しているバージョンよりも新しいバージョンを入手し
  た場合、必ずリリースノートに目を通してください。それら新しいバージョン
  ではインストールの方法が変っているかも知れません。

  プログラムは常にソースからコンパイルするという人でも、以下に示すプログ
  ラムはバイナリ版を入手してお使いになることを強くお勧めします。これらの
  プログラムのほとんどは a.out 版のシステムで ELF 形式を生成するようには
  設定されておらず、a.out の環境でコンパイルしようとしても無駄です。

  2.3.1.  絶対に必要なもの

  o  ld.so-1.7.14.tar.gz --- 新しい動的リンカ。ソースとバイナリが 入って
     います。これ以降のバージョンでは a.out バイナリを使う場合でもカーネ
     ルに ELF サポート機能を組みこんでおく必要があります。もし 1.8.1 や
     それよりも新しいバージョンをお持ちの場合はインストールする前に カー
     ネルに ELF サポート機能が組みこまれているかを確認してください。

  o  libc-5.3.12.bin.tar.gz  --- ELF 形式の共有ライブラリで C と数学ライ
     ブラリ、その他関連する静的ライブラリやそれらを使ってプログラムをコ
     ンパイルするのに必要なインクルードファイルが入っています。必要でし
     たらソースコードも入手できますが、コンパイルするには時間がかかりま
     すし、ELF システムを持っていないとコンパイルすることは不可能でしょ
     う。

  o  gcc-2.7.2.bin.tar.gz --- ELF 対応の C コンパイラ。新しいディレクト
     リ・レイアウトを理解する a.out 対応の C コンパイラも入っています。
     gcc を自分でコンパイルしたい場合(やるとしても ELF 環境に移行してか
     らの方が簡単だと気づくでしょう)、GNU のオリジナルのソースコードに
     gcc-2.7.2-linux.diff.gz パッチをあてた方がいいでしょう。

  o  /binutils-2.6.0.12.bin.tar.gz --- Linux 用にパッチをあてた GNU バイ
     ナリユーティリティです。このパッケージには gas や ld、strings など
     のプログラムが含まれており、C コンパイラを使うには必須になっていま
     す。素のままの GNU binutilities (例えば prep.ai.mit.edu にあるよう
     な)では代りにならないことごに御注意ください。どうしても自分でコンパ
     イルしたい場合は GNU のものではなく、Linux 用にパッチを当てた
     binutils-2.6.0.12.tar.gz を使ってください。

  o  ncurses-1.9.9e.tar.gz --- SVR4 互換の curses ライブラリで、これから
     の Linux 用「標準 curses ライブラリ」であると考えられています。ソー
     スコードは  <ftp://prep.ai.mit.edu/gnu/> のような GNU のサイト、あ
     るいは  <ftp://ftp.netcom.com/pub/zm/zmbenhal> から入手でき、
     tsx-11 にはバイナリパッケージも用意されています。このパッケージをイ
     ンストールする時には既に完全に ELF 化された開発環境に移行しているは
     ずなので、マシンパワーがある場合はソースコードを入手した方がいいで
     しょう。

  o  gdbm-1.7.3.tar.gz ---  Unix の標準となっている dbm や ndbm ルーチン
     と互換の、拡張ハッシュ機能を持ったデータベースルーチンです。ソース
     コードは  <ftp://prep.ai.mit.edu/gnu/> から入手できます。共有ライブ
     ラリ版を作るには  <ftp://ftp.uk.linux.org/pub/Linux/libc/non-
     core/gdbm.patch> を当ててください。このパッチはその他いくつかのバグ
     を修正しています (Makefile にある一文字の typo や間違った種類のファ
     イルロッキングを使う傾向など)。

  2.3.2.  その他

  上記以外にも、必須ではありませんが入手しておいた方がいいライブラリや
  ファイルがいくつかあります。以下に示すものは ELF で使うためにバージョ
  ンアップしなければならない類いのプログラムです。この文書の後半では、そ
  のままでも使えるものの、ELF 形式でコンパイルするには修正やバージョン
  アップが必要なプログラムを紹介します。ネットとの接続が遅い場合(例えば
  フロッピーの箱を抱えて 5 分間歩いているくらい時間のかかるような)、以下
  のファイルは飛ばして、設定を終える前にこの文書の後半部にあるそれぞれの
  プログラムについての記述と合せてチェックしてください。

  o  a.out 互換ライブラリパッケージ、libc.so-4.7.6。

     このパッケージが「オプション」になっているのは、手元にある既存のバ
     イナリを動かすことのできる a.out ライブラリがあれば、それはそのまま
     使えるからです。このライブラリは何らかの理由で今後も a.out 形式のプ
     ログラムを開発せねばならない時に必要になります。

  o  BSD curses

     libcurses.so.1 を必要とするバイナリがあれば、これが古い BSD curses
     ライブラリです。このライブラリのソースコードは今のところ見つかって
     いないのですが、このライブラリでしか動かないプログラムはごく稀なは
     ずです。その種のプログラムがあれば、ncurses を使うようにコンパイル
     し直した方がいいでしょう。そうできない場合は libcurses.so が tsx-11
     とそのミラーサイトにある libc-5.0.9.bin.tar.gzに含まれています。

  o  Berkeley db

     新しい 4.4 BSD 用 libdb データベースルーチンです。ソースコードは
     <ftp://ftp.cs.berekeley.edu/ucb/4bsd/db.1.85.tar.gz/> で、Linux の
     共有ライブラリ用のパッチは
     <ftp://ftp.uk.linux.org/pub/Linux/libc/non-core/db.patch> にありま
     す。

  o  C++ 用のプログラム

     gcc パッケージは g++ と共に配布されていますが、有用な C++ ソフト
     ウェアをコンパイルするには libg++-2.7.1.4.bin.tar.gz が必要です。私
     自身は C++ を使っていませんが、聞くところによると、このライブラリを
     ソースコードからコンパイルするのは結構大変だそうです。ですから、バ
     イナリ版をお勧めします。

  o  GNU 互換の termcap

     ncurses への移行は ELF への移行と同時に起ったわけではありません。他
     の人が作ったプログラムや使い続けたいアプリケーションの中にはこのラ
     イブラリを使っているものがあるかも知れません。gdb がそのいい例で
     す。共有ライブラリをデバッグしたいけれど、gdb が自分自身へリンクし
     ているライブラリを前にして混乱するような場合、静的にリンクしたバイ
     ナリを使うべきでしょう。その場合、本当の termcap は ncurses に含ま
     れている termcap 互換のルーチンに比べてずっと小さいことに気づくで
     しょう。

     termcap-2.0.8.tar.gz は tsx-11 から入手できます。これは GNU Termcap
     とは異なりますが、完全に互換です(違いはエラーチェックの部分だけで
     す)。これはソースコードのパッケージになっています。

  o  MAKEDEV

     ある状態で起動すると、MAKEDEV は既存のデバイスファイルを削除した上
     で再度作成することがあります。/dev/zero を削除してしまえば、いくつ
     かのバージョンの ld-linux.so.1 が動かなくなります。新しいバージョン
     の MAKEDEV は
     <ftp://sunsite.unc.edu/pub/Linux/system/Admin/MAKEDEV-C-1.5.tar.gz>
     か
     <ftp://sunsite.unc.edu/pub/Linux/system/Admin/MAKEDEV-2.2.tar.gz>.
     にあります。

  o  modules-2.0.0

     モジュールを使っている場合、binutils をバージョンアップすれば
     1.3.69 以前のモジュール・ユーティリティは使用できなくなります。新し
     いモジュール・ユーティリティは  <http://www.pi.se/blox/> にありま
     す。

  o  いろいろな共有ライブラリを含む X ウィンドウシステム。

     新しいプログラムは ELF 形式になり、ELF 形式のプログラムは a.out ラ
     イブラリでは使用できませんので、X に関するプログラムを開発する場
     合、新しい X ウィンドウシステム一式をインストールする必要がありま
     す。XFree86 3.1.2 は a.out と ELF の双方の形式で提供されていま
     す。XFree86 の配布元は ftp.xfree86.orgですが、国内にも多数のミラー
     サイトがあります(例えば ftp.iij.ad.jp)ので、ネットワーク的に近いサ
     イトから入手してください。これらのサイトからcommonとelfディレクトリ
     以下を入手したら、/usr/X11R6/lib/X11/config/linux.cf ファイルの中の
     以下の2行のNOのところを

       #define LinuxElfDefault         NO
       #define UseElfFormat            NO

  YESにしてください。そうしないと xpm をコンパイルする際に jumpas で昔の
  名残りの奇妙なエラーが生じます。現在の XFree86 のバイナリは ELF 化され
  た termcap ライブラリlibtermcap.so.2 がインストールされている必要があ
  ることに注意してください。

  Motif を使っている場合は、ELF 化された Motif ライブラリを提供する予定
  があるかベンダーに問いあわせてください。私は Motif は使っていないので
  何の役にも立てません。

  o  ELF 化と同時に Linux 2.0 へアップグレードする場合、カーネルのソース
     コードと共に配布されている Documentation/Changes ファイルを忘れずに
     チェックして、必要なものがどこで入手できるか調べてください。

  2.4.  ファイルシステムの再調整

  え〜っと、私が以下で「削除する」と言った場合、「バックアップを取ってか
  ら削除する」と読みかえてください :-) まず、深呼吸して、、

  エッセンス --- バイナリ・インストール

  1. a.out バイナリを移動するためのディレクトリを作成

       mkdir -p /usr/i486-linuxaout/bin
       mkdir -p /usr/i486-linuxaout/include
       mkdir -p /usr/i486-linuxaout/lib
       mkdir /lib-aout

  2. 動的リンカのパッケージ ld.so-1.7.14 をいつものソースコードを置いて
     いる場所で展開し、取り出された ld.so-1.7.14/instldso.sh スクリプト
     を読んでください。本当に標準的なシステムをお使いなら、sh
     instldso.sh を実行してインストールすることができますが、何か非標準
     的なものを組みこんでいる場合、手動でインストールすることになりま
     す。「何か非標準的なもの」とは、

  o  zsh (いくつかのバージョンの zsh は $VERSION という変数を定義してお
     り、instldso.sh が混乱するようです)

  o  /lib/elf から /lib へのシンボリックリンク(これは必要なわけではあり
     ませんが、レスキューディスクが必要になるような場合には多少の慰めに
     なるかも知れません)

  3. /etc/ld.so.conf を修正して、 /usr/i486-linuxaout/lib を加え(必要な
     らば /lib-aout も加え)、/sbin/ldconfig -v  を再実行して、新しいディ
     レクトリを探しにいくかチェックします。

  4. /usr/*/lib にある全ての a.out 形式の「ライブラリ」を
     /usr/i486-linuxaout/lib に移します。移すものは lib*.so* や
     lib*.sa*、lib*.a などの「ライブラリ」であって、その他のファイルを移
     す必要はありません。 /usr/lib/gcc-lib などもまだ動かしてはいけませ
     ん。

  5. 次に /lib をチェックします。libc.so* や libm.so*、libdl.so* はその
     ままにしておきます。X のライブラリ(libX*.so.3*へのシンボリックリン
     クもそのままにしておきましょう --- XView 等のプログラムがそれらのラ
     イブラリを使っているかも知れません。ld.so* 、ld-linux.so* など ld
     で始まっているファイルもそのままにしておきます。残りのライブラリに
     ついては(もしあれば)： ルートパーティションに /usr があれば、そこに
     あるファイルは /usr/i486-linuxaout/lib に移します。/usr が別パー
     ティションにマウントされていれば、 /lib-aout に移します。これで
     ldconfig -v してみてください。

  6. binutils をインストールする準備として、もし /usr/lib/ldscripts ディ
     レクトリがあれば削除します(binutils がこのディレクトリを新たに作り
     ます)

  7. /usr/bin にある(ld86 と as86 以外の)全ての ld と as のコピーを削除
     します。

  8. /usr/include 以下のディレクトリを削除します。標準的なシステムでは、
     ここにあるファイルのいくつかはシステムの「核」となる機能を担ってお
     り、libc と共に配布されています。それ以外にも、あなた自身がインスト
     ールしたり、使っているディストリビューションの作成者がインストール
     したファイルもあるはずです。これらを整理するために、0 から作り直す
     ことをお勧めします。まず既存の/usr/includeを /usr/include.oldに変更
     し、libc-5.2.18.bin.tar.gzをルートディレクトリで展開します。

  9. binutils パッケージをインストールします。このためには tar - xvzf
     binutils-2.6.0.12.bin.tar.gz -C / がお勧めの方法です。

  10.
     gcc パッケージはルートディレクトリで展開する必要があります。gcc
     パッケージはいくつかのファイルを /usr/bin に、残りの多くのファイル
     を /usr/lib/gcc-lib/i486-linux/2.7.2 と /usr/lib/gcc-
     lib/i486-linuxaout/2.7.2 にインストールします。 gcc をインストール
     するには、まず

       $ tar ztf gcc-2.7.2.bin.tar.gz

  として、何が入っているかをチェックしてください。残しておきたいファイル
  に上書きするようであれば(例えば Gnu ADA をインストールしていれば
  /usr/bin/gcc を残しておきたいでしょう)、まずそれらのファイルを安全な所
  に移します。その上で、

       # tar -zxf gcc-2.7.2.bin.tar.gz -C /

  とします。この時点で、gcc -v して gcc のバージョンを確かめたり、テスト
  用のプログラムをコンパイルして、きちんと動いているかチェックしてくださ
  い。

       $ gcc -v
       Reading specs from /usr/lib/gcc-lib/i486-linux/2.7.2/specs
       gcc version 2.7.2
       $ gcc -v -b i486-linuxaout
       Reading specs from /usr/lib/gcc-lib/i486-linuxaout/2.7.2/specs
       gcc version 2.7.2
       $ ld -V
       ld version 2.6 (with BFD 2.6.0.2)
         Supported emulations:
          elf_i386
          i386linux
          i386coff

  次に伝統的な ``Hello, world'' プログラムを試してください。そのプログラ
  ムを gcc や gcc -b i486-linuxaout で、コンパイルし、 a.out と ELFのコ
  ンパイラが正しく設定されているか確認してみましょう。

  終りましたかって？もう少し頑張って。まだいくつかのライブラリが残ってい
  ます。また、シンボリックリンクをごちゃごちゃ張らないといけません。頑
  張って、、

   シンボリックリンク

  11.
     いくつかのプログラム(特にいくつかの X 関連プログラム)は /lib/cpp を
     使います。/lib/cpp は Linux では
     /usr/lib/gcc-lib/i486-linuxversion/cppにあります。ここまでの段階で
     /lib の下にあるシンボリックリンクは全て削除しているはずなので、リン
     クを張り直す必要があります。

       # cd /lib
       # ln -s /usr/lib/gcc-lib/i486-linux/2.7.2/cpp .

  12.
     /usr/include 以下を /usr/include.old 以下に移すと、カーネルのソース
     コードへのシンボリックリンクが失なわれるので、

       # cd /usr/include
       # ln -s ../src/linux/include/linux .
       # ln -s ../src/linux/include/asm .

  としてリンクを張り直してください。

  (ここではカーネルのソースコードは /usr/src/linux にあると仮定していま
  す。そうでない場合、適切な場所を指定してください)

  13.
     FSSTND の連中は、ここでも utmp と wtmp ファイルを /var/adm から
     /var/run と /var/log にそれぞれ移すことにしました。必要に応じて
     /var/log や /var/adm を作り、utmp や wtmp の現在位置へリンクを張る
     ようにしてください。私は以下の ls -l に示すような配置にしました。

       $ ls -ld /var/adm /var/log /var/run /var/log/*tmp /var/run/*tmp
       lrwxrwxrwx   1 root     root            3 May 24 05:53 /var/adm -> log/
       drwxr-xr-x   9 root     root         1024 Aug 13 23:17 /var/log/
       lrwxrwxrwx   1 root     root           11 Aug 13 23:17 /var/log/utmp -> ../run/utmp
       -rw-r--r--   1 root     root       451472 Aug 13 23:00 /var/log/wtmp
       drwxr-xr-x   2 root     root         1024 Aug 13 23:17 /var/run/
       -rw-r--r--   1 root     root          448 Aug 13 23:00 /var/run/utmp

  FSSTND の全体については sunsite にあ る LDP のアーカイブ
  <ftp://sunsite.unc.edu/pub/Linux/docs/fsstnd/>などにある文書をご覧くだ
  さい。

  おめでとう！

  ここまでで(多少なりとも)完全に機能する ELF の開発環境が完成したはずで
  す。一歩下って、しばらく静かに喜びをかみしめましょう。

  重要なソースコードのパッケージ

  14.
     ncurses のインストールはかなり時間のかかる仕事です。もっとも、その
     大部分の時間はコンパイルしながらネットニュースを読むことに費すこと
     ができますが。tar ファイルを展開したら INSTALL ファイルを、自分が
     「Linux 何たらシステム」のディストリビューションの作成/まとめ役であ
     る、と思って読んでみましょう。すなわち、コンパイルの際には、多分、
     以下のようなコマンドラインで設定する必要がある、ということです。

       $ ./configure --with-normal --with-shared --disable-termcap --enable-overwrite --prefix=/usr

  デフォルトになっているターミナルの種類にも注意しましょう。1.3 と 2.0
  のカーネルでは、起動時のデフォルトのターミナルは linux になっていま
  す。場合によっては /etc/inittab を修正して console や getty にしなけれ
  ばならないかも知れません。

  ルートパーティションのあるハードディスクに /usr/lib/terminfo が無い場
  合、ncurses の `fallback' 機能でごまかす必要があるでしょう。この機能は
  上述の INSTALL ファイルに説明してあり、単純ですが、退屈な仕事になりま
  す(ライブラリを 2 度作成する必要があります)。fallback として linux や
  vt100 を使えばいい場合、幸いなことに既存の fallback.cに置き替え可能な
  fallback.c が ftp.uk.linux.org
  <ftp://ftp.uk.linux.org/pub/Linux/libc/non-core/fallback.c> に用意され
  ています。

  ncurses をインストールした後、/usr/lib 以下で多少面倒な仕事をする必要
  があります。これは不定形な作業なので、手でやるのが最も簡単です。バー
  ジョン番号が多少不一致になっていることに注意してください。これは醜いで
  すが、健康に害があるわけではありません。

     a. /usr/lib/libncurses.so.1.9.9e を /lib に移し、シングルユーザーモ
        ードでも curses プログラムが動けるようにします。ルートパーティ
        ション に /usr/lib がある場合、特にこの作業は不要ですが、やって
        おいても害はありません。

     b. /lib ディレクトリで libncurses.so.1.9.9e から /libncurses.so.3.0
        へリンクを張ります。

     c. その他、/lib/libncurses.so.3.0 から /usr/lib/libncurses.so や
        /usr/lib/libcurses.so 、 /usr/lib/libtermcap.so へのリンクも必要
        かも知れません。

  考えるのがメンドウな人向けに簡単に言うと、以下のような作業になります。

       # cd /lib
       # mv /usr/lib/libncurses.so.1.9.9e .
       # ln -s libncurses.so.1.9.9e libncurses.so.3.0
       # cd /usr/lib
       # ln -s /lib/libncurses.so.3.0 libncurses.so
       # ln -s /lib/libncurses.so.3.0 libcurses.so
       # ln -s /lib/libncurses.so.3.0 libtermcap.so

  15.
     gdbm のインストール。ソースコード用のディレクトリでソースコードを展
     開し、gdbm.patch をあて、README と INSTALL ファイルに目を通します。

     構築の手順は以下のようなものになるはずです。

       $ tar zxf gdbm-1.7.3.tar.gz
       $ patch -p0 < gdbm.patch
       $ cd gdbm-1.7.3
       $ ./configure --prefix=/usr
       $ make
       $ make progs
       $ su
       # make install
       # make install-compat
       # cd /usr/lib
       # ln -s libgdbm.so.1 libgdbm.so
       # ln -s libgdbm.so.1 libgdbm.so.2
       # ldconfig

  最後の 2 つは古いバージョンとの互換性を保つためです。最近のディストリ
  ビューションでは libgdbm.so.2 というバージョンになっていますが、これは
  libdgbm.so.1 と全く同じコードで、バージョン番号だけが歴史的な理由から
  間違えて付けられているものです。

  オプションのソースコードパッケージ

  一般に、それぞれのパッケージに付属の指示にしたがってインストールすれば
  大丈夫なので、ここで繰り返すことはしません。ただし、例外が 2 つあり、

  16.
     GNU 風の termcap が必要な場合(厳密に言うと必須ではありませんが、実
     際には XFree86 のバイナリが必要とするので、ほぼ必須でしょう)、ソー
     スコードから構築する必要がありますが、必要な作業は以下に示す程度で
     す。

       $ tar zxf termcap-2.0.8.tar.gz
       $ cd termcap-2.0.8
       $ make
       $ su
       # cp libtermcap.so.2.0.8 /usr/lib
       # ldconfig

  決して make install は実行しないように。make install すると ncurses の
  プログラムを一部上書きしてしまいます。このライブラリを使うようにコンパ
  イルされた既存のバイナリを使うのではなく、新たにこのライブラリを使って
  プログラムをコンパイルする場合、ヘッダーファイルとスタティック・ライブ
  ラリをどこか別の場所に用意して -I と -L フラグを使ってコンパイル時にそ
  の場所を明示するようにしてください。この部分は他の部分に比べて記述が曖
  昧だと思われるかも知れませんが、それには理由があります。すなわち、よほ
  どの理由がないかぎり、 termcap を使い続けることはお勧めできないからで
  す。

  17.
     libdb は以下のように作成します。

       $ tar zxf db.1.85.tar.gz
       $ patch -p0 <db.patch
       $ cd db.1.85/PORT/linux
       $ make
       $ su
       # mkdir /usr/include/db
       # ldconfig
       # cp libdb.so.1.85.3 /usr/lib ; ( cd /usr/lib && ln -s libdb.so.1 libdb.so )
       # cp ../../include/*.h /usr/include/db

  注意点としては

  o  PORT/linux/OTHER-PATCHES をあててはいけません。 db.patch に含まれて
     います。

  o  gdbm のインクルードファイルと衝突するので、インクルードファイルは
     /usr/include 以外の部分にインストールし、libdb が必要なプログラムを
     コンパイルする場合、C コンパイラのコマンドラインに
     -I/usr/include/db と指定してください。

  2.5.  どういう風になるのか(ディレクトリ構成のアウトライン)

  以下に示すものは今までにインストールしてきたファイルのかなりおおまかな
  概観です。トラブルシューティングや削除すべきものを決める際にご利用くだ
  さい。

  2.5.1.  /lib

  o  動的リンカ ld.so (a.out 用)と ld-linux.so.1 (ELF 用)。 両者ともシン
     ボリックリンクかも知れませんが、指しているファイルがきちんと存在す
     ることを確認してください。

  o  基本的な共有ライブラリ libc.so.4と libm.so.4(a.out)。これらはシンボ
     リックリンクになっていますが、正しいファイルを指しているか確認して
     ください。

  o  基本的な共有ライブラリ libc.so.5 と libm.so.5、
     libdl.so.1、libncurses.so.1、 libtermcap.so.2 (ELF 用)。これらもま
     たシンボリックリンクになっているので、正しいファイルを指しているか
     確認してください。

  2.5.2.  /usr/lib

  o  かってここにあったライブラリ以外のファイルとディレクトリ

  o  libbfd.so*, libdb.so*, libgdbm.so* といった ELF 形式の共有ライブラ
     リ

  o  さまざまなシンボリックリンク。/lib や /usr/lib にあるライブラリへの
     シンボリックリンクがここに必要です。リンクの名前は本当のファイル名
     からバージョン番号を取ったものです。例えば、libc について言うと、

       lrwxrwxrwx   1 root     root           14 May  2 20:09 /lib/libc.so.5 -> libc.so.5.3.12
       -rwxr-xr-x   1 bin      bin        583795 Apr 25 06:15 /lib/libc.so.5.3.12
       lrwxrwxrwx   1 root     root           12 Oct 27  1995 /usr/lib/libc.so -> /lib/libc.so.5

  となります。これらのリンクは、リンク時に ldが利用します。

  o  libbsd.a、libgmon.a、libmcheck.a と /lib や /usr/lib にある ELF 形
     式の共有ライブラリ各々に用意されているlib*.a ライブラリ。これらは
     ELF 形式の静的ライブラリです。大部分の人にとっては、共有ライブラリ
     と同じ静的ライブラリがあってもそれほど有難味はないでしょう。特に
     ELF 形式を使う場合には。 ELF では、共有ライブラリを使いながら gcc
     -g オプションを指定することも可能なので、静的ライブラリを組みこむべ
     き理由はほとんどありません。でも、ライブラリ自身をデバッグしたくな
     る日のために、それらの静的ライブラリは残しておいた方がいいでしょ
     う。

  o  crt0.o と gcrt0.o。これらは a.out 形式の「プログラム起動用の」ファ
     イルです。特に避けることをしなければ、全ての a.out 形式のプログラム
     にこれらのうちの一つのファイルがまずリンクされることになります。

  o  crt1.o、crtbegin.o、crtbeginS.o、 crtend.o、crtendS.o、crti.o、
     crtn.o、gcrt1.o。これらは ELF 用の起動用ファイルです。これらは上記
     *crt0.o と同様の機能を ELF 形式のプログラムに対して行います。

  2.5.3.  /usr/lib/ldscripts

  o  このディレクトリは、その名が示す通り、 ld 用の各種ドライバスクリプ
     トを置くところです。このディレクトリには以下のようなファイルがあり
     ます。

       $ ls /usr/lib/ldscripts/
       elf_i386.x      elf_i386.xs     i386coff.xn     i386linux.xbn
       elf_i386.xbn    elf_i386.xu     i386coff.xr     i386linux.xn
       elf_i386.xn     i386coff.x      i386coff.xu     i386linux.xr
       elf_i386.xr     i386coff.xbn    i386linux.x     i386linux.xu

  2.5.4.  /usr/i486-linux/bin

  o  ar, as, gasp, ld, nm, ranlib, strip

     これらは /usr/bin にある実際のバイナリ操作用プログラムへのシンボ
     リックリンクです。

  2.5.5.  /usr/i486-linuxaout/bin

  o  a.out 用のアセンブラ as と、そのマクロ・プリプロセッサ gasp があり
     ます。

  o  ar, ld, nm, ranlib, strip --- これらは /usr/bin にある実際のバイナ
     リ操作用プログラムへのシンボリックリンクです。

  2.5.6.  /usr/i486-linux/lib

  o  ldscripts は /usr/lib/ldscripts へのシンボリックリンクです。

  2.5.7.  /usr/i486-linuxaout/lib

  o  a.out 用の共有ライブラリ本体の lib*.so* があります。 a.out 形式のプ
     ログラムを動かすには必須です。

  o  lib*.sa は a.out 形式の共有ファイルのスタブ(stub)です。共有ライブラ
     リを使う プログラムを a.out 形式にコンパイルするために必要で
     す。a.out 形式にコンパイルすることが無ければ削除してしまっても構い
     ません。

  o  lib*.a は a.out 用の静的ライブラリです。a.out 形式で静的にリンクさ
     れたバイナリを作るために必要です(例えば -g オプション付きでコンパイ
     ルする時)。このファイルも a.out 形式のプログラムを作成する必要がな
     ければ削除して構いません。

  o  ldscripts は /usr/lib/ldscripts へのシンボリックリンクです。

  2.5.8.  /usr/lib/gcc-lib/i486-linux/2.7.2

  o  このディレクトリには ELF 形式のプログラムをコンパイルするための gcc
     2.7.2 が収められています。

  2.5.9.  /usr/lib/gcc-lib/i486-linuxaout/2.7.2

  o  このディレクトリには a.out 形式のバイナリを出力するための gcc 2.7.2
     一式が収められています。この gcc は新しい(ここで示したような)ディレ
     クトリ構成を理解する機能を持っています。もし a.out にコンパイルする
     必要がない場合、このディレクトリを削除すれば約 4MB 節約できます。
     パッチ済みでない 1.2 シリーズのカーネルをコンパイルする場合には、こ
     のコンパイラが必要なことをお忘れなく。

  2.6.  よくあるエラー ――― あわてないで！

  (以下の内容の大部分は親切なメールでいただいたものです)

     何か間違ったものを動かして、何も動かなくなってしまった！
        その場合でも shell は動いているはずなので、多少工夫すれば shell
        の組みこみ機能だけでかなりの仕事をこなすことが可能です。echo *
        は ls の代わりに使え、echo >>filename はファイルに書き足すのに使
        えます。ldconfig も静的にリンクされていることをお忘れなく。例え
        ば、libc.so.4 を間違って lib-aout ディレクトリに移してしまった場
        合、echo "/lib-aout" >>/etc/ld.so.conf ; ldconfig -vすれば、復旧
        します。 /lib/ld.so を動かしてしまった場合、 静的にリンクされた
        ln があれば、sln /sillyplace/ld.so /lib/ld.soすることで、多分復
        旧するでしょう。

      bad address
        ELF 形式のプログラムを動かそうとすると、いつもbad address エラー
        になる場合、多分、カーネルの 1.3.x の x <3 のバージョンをお使い
        なのでしょうが、そのバージョンを使ってはいけません。それらは多
        分、最悪のバージョンの一つです。2.0 へバージョンアップするか
        1.2.13 にバージョンを落しましょう。似たような環境でカーネルパ
        ニックが発生すると報告している人たちもいますが、私は詳しく調べて
        いません。なぜなら、開発版のバージョンを使いたいとも思わないし、
        使う必要があるとも感じないので、最新版の追っかけはしていないから
        です。

      gcc: installation problem, cannot exec something: No such file or
        directory
        a.out 形式でコンパイルしようとして(something の部分はたいていの
        場合 cpp か cc1 のはずです)、このエラーが生じる場合、実際に cpp
        や cc1 に問題があるか、

          $ gcc -b -i486-linuxaout

     のように入力したのでしょう。実際には

          $ gcc -b i486-linuxaout

     と入力しなければなりません。`i486'の部分はダッシュではじまらないこ
     とに注意してください。

     make: *** No targets specified and no makefile found.  Stop.
        このエラーが出る場合、make にパッチをあてて再コンパイルしていな
        いか、古いバージョンの make がシステムのどこかに残っているので
        しょう。

      no such file or directory: /usr/bin/gcc
        実際にそのファイルが存在するのにこういうエラーが出る(gcc 以外の
        プログラムでもこうなるかも知れません)。この場合、ELF の動的ロー
        ダー /lib/ld-linux.so.1 をインストールしていないか、何らかの理由
        でローダーが読めない状態になっているのでしょう。先に述べたインス
        トールステップの 2 を読んで /lib/ld-linux.so.1 を正しくインスト
        ールしてください。

      not a ZMAGIC file, skipping
        このエラーは ldconfig が出しています。古いバージョンの ld.so の
        パッケージをお使いのようなので、新しいものを入手してください。も
        う一度、インストールのステップ 2 を読んでください。

      _setutent: Can't open utmp file
        このメッセージは xterm を起動した時に 3 行ずつ出力されることがよ
        くあります。インストール手順の最後のあたりにある FSSTND の長文の
        説明を読んでください。

  3.  プログラムの構築

  3.1.  一般的なプログラム

  プログラムを ELF 形式でコンパイルする場合、いつものように gcc を使いま
  す。a.out 形式でコンパイルする場合、gcc -b i486-linuxaout としてくださ
  い。

       $ cat >hello.c
       main() { printf("hello, world\n"); }
       ^D
       $ gcc -o hello hello.c
       $ file hello
       hello: ELF 32-bit LSB executable i386 (386 and up) Version 1
       $ ./hello
       hello, world

  さて、そろそろ「a.out 形式のコンパイラが出力するバイナリのデフォルト名
  が a.out なら、ELF コンパイラの出力するバイナリのデフォルト名は何とい
  うの？」という質問に答えるべき時でしょう。答は、「やっぱり a.out」なん
  です。残念でしたか？ :-)

  3.2.  ライブラリの作り方

  libfoo.so を共有ライブラリとして構築したい場合、基本的な手順は以下のよ
  うになります。

       $ gcc -fPIC -c *.c
       $ gcc -shared -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0 *.o
       $ ln -s libfoo.so.1.0 libfoo.so.1
       $ ln -s libfoo.so.1 libfoo.so
       $ export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH

  これにより、libfoo.so.1.0 と呼ばれる共有ライブラリと ld 用のシンボリッ
  クリンク(libfoo.so)、動的リンカ用のシンボリックリンク(libfoo.so.1)が作
  成されます。ライブラリのテストの際は、最後に示したように、現在のディレ
  クトリを LD_LIBRARY_PATH に加えて試してみましょう。

  ライブラリが正しく動くことが確認できれば、適切な場所、例えば
  /usr/local/lib に移し、リンクを張り直しましょう。 libfoo.so のリンクは
  libfoo.so.1 へ張られているので、バージョン番号のマイナーチェンジがあっ
  てもリンクを張り直す必要はありません。libfoo.so.1.0 から libfoo.so.1
  へのリンクは、たいていのシステムでは ldconfig が起動時に更新します。

  $ su
  # cp libfoo.so.1.0 /usr/local/lib
  # /sbin/ldconfig
  # ( cd /usr/local/lib ; ln -s libfoo.so.1 libfoo.so )

  3.3.  a.out 形式の構築

  ELF 環境の中でも古い a.out 形式のバイナリを作成しなければならない場合
  があるかも知れません。「普通の」プログラムの場合、必要なことは gcc を
  起動する時に -b i486-linuxaoutフラグを使って a.out 用のコンパイラを起
  動し、(もし) ld を起動する場合は -m i386linux フラグを使います。a.out
  形式の DLL 共有ライブラリを未だに必要とする人は、、可哀想に。私の知る
  限りでは、一言で言えば「動きません」。別の方法を御存知ならばメールで私
  に教えてください。

  4.  ELF 用パッチとELF 化済みのプログラム

  ここまでで、お好みならば終了することが可能です。ELF 形式のプログラムを
  コンパイルして動かすために必要な環境は全てインストールできました。

  「美意識」的な観点やメモリ使用量を最小化するためには、お使いのプログラ
  ムを全て ELF 形式でコンパイルし直したくなるかも知れません。ELF 形式で
  の再コンパイルはほとんどのエンドユーザー用のアプリケーションではごく簡
  単です。しかしながら、動作環境について何らかの前提のあるプログラムもい
  くつかあり、それらは以下のような理由でエラーになるかも知れません。

  o  アセンブラのアンダスコアの使い方の違い：a.out の実行形式では外部ラ
     ベルには _(アンダスコア) が頭に付いていますが、ELF の実行形式ではそ
     うなっていません。これは、手書きのアセンブラコードを組みこまない限
     り問題にはなりません。_foo の形のラベルを全て foo に翻訳してやる
     か、(移植性を高めたければ) EXTERNAL(foo) のようなマクロを用意し
     て、(__ELF__ が定義されていればそのまま変数を返し、定義されていなけ
     れば _ を付けるようにするのがいいでしょう。

  o  libc 5 と libc 4 の違い。例えば locale サポートへのインターフェイス
     は変更されています。

  o  使っているバイナリ形式をアプリケーションや構築過程が参照している場
     合。例えば emacs はその一例で、メモリイメージを実行形式としてディス
     クに書きだすので、実行形式のフォーマットをプログラムが理解している
     必要があります。

  o  共有ライブラリや共有ライブラリを含むアプリケーション(X11 が分りやす
     い例)。これらの場合、ELF 形式で共有ライブラリを作るような方法に修正
     する必要があります。

  とにかく、以下に 2 つのリストを示します。最初のリストは既に ELF 形式の
  バージョンが作成されているもの(すなわち、ELF 形式でコンパイルするには
  新しいバージョンを入手すればいいもの)で、2 つめのリストは第三者からの
  パッチが必要なプログラムです。

  4.1.  アップグレードすればいいもの：

  o  Dosemu

     現在では dosemu も ELF 形式で動きます。ただし、Makefile に多少の修
     正が必要なようです。最新版の dosemu は
     <ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/> から入手できます。
  o  e2fsutils

     e2fs ファイルシステム用の各種ユーティリティ e2fsutils は、バージョ
     ン 0.5c 以降のものは変更なく ELF 形式でコンパイルできます。

  o  Emacs

     Emacs には 2 つの潜在的な問題があります。(i) Emacs は、まず最小規模
     のシステムを動かして、必要な lisp ファイルを全て読みこんだ上で、メ
     モリイメージを実行形式のファイルとして直接ディスクへ書きだす、とい
     うかなり変った手順で作成されます。(FSF) Emacs 19.29 と XEmacs
     19.12(かっては Lucid Emacs と呼ばれていました)は ELF 形式かどうかを
     自動的に見分けて、正しい手順で構築されます。(ii) いくつかのバージョ
     ンの emacs を ncurses を使うようにコンパイルする場合、emacs のソー
     スパッケージの src/s/linux.h の先頭付近に #define TERMINFO の一行を
     加えないと、正しく構築されないことがあります。これは 19.31 では必要
     ないですが、XEmacs 19.13 には必要です。次のバージョン、19.14 では間
     違いなく修正されることでしょう。

  o  gdb 4.16

     既存の gdb でも問題なくそのまま使えますが、4.16 で採用された共有ラ
     イブラリ機能はずっと便利になっています。ですから、もしライブラリ関
     連の妙なエラーに悩まされている場合、gdb をバージョンアップするのも
     いいでしょう。

  o  Kernel 本体

     カーネルのバージョン 2.0 以降は ELF 形式で問題なく動きます。カーネ
     ル構築時の設定(make config)の時に以下の 2 つの項目に `yes' と答えて
     ください(これは 1.3 でも同じです)。1.2 をまだ使っている場合、次のリ
     ストに示すパッチを入手してください。

       Kernel support for ELF binaries (CONFIG_BINFMT_ELF) [Y/m/n/?]
       Compile kernel as ELF - if your GCC is ELF-GCC (CONFIG_KERNEL_ELF) [Y/n/?]

  o  perl 5

     Perl 5.001m 以降のバージョンは ELF システムで、動的ロード機能も完璧
     に、変更なくコンパイルできます。最新版の Perl は CPAN(Comprehensive
     Perl Archive Network)サイトから入手できます。CPAN は funet でもミラ
     ーされています  <ftp://ftp.funet.fi/pub/mirros/perl/CPAN>、が身近な
     サイトから入手するようにしてください。

  o  ps と top

     Procps 0.98 以上のバージョンは ELF 形式をサポートしています(より古
     いバージョンでも動きますが、WCHAN の名前をカーネルから読みとること
     ができません)。2.0 シリーズのカーネルには procps 0.99a 以降のバー
     ジョンが必要なことをお忘れなく。

  o  util-linux 2.2 に入っている cal プログラムは動きません。tsx-11 にあ
     る version 2.5 <ftp://tsx-11.mit.edu/pub/linux/packages/utils>以降
     のバージョンを使ってください。

  o  Mosaic

     私自身は Mosaic をコンパイルできる環境にありませんが、NCSA からリリ
     ースされている 2.7b1 以降の Mosaic のバイナリは ELF 形式になってい
     ます。ところが、X の設定が変な風になっていて、通常のシステムでは
     libXpm.so.4.5 が見付からない、というエラーになります。最後のバー
     ジョン番号(.5)が余計なので、単純な修正方法は、emacs などのバイナリ
     ファイルを操作できるエディタで直接修正してしまうことでしょう。
     libXpm.so.4.5^@ という文字列を探して(ここで ^@ は NUL キャラクタ
     --- ASCII の 0 ---です)、.5 を削除し、ファイル名の長さが変らないよ
     うに、注意深く NUL キャラクタの後に 2 つのスペースを追加しましょ
     う。

  4.2.  パッチが公開されているもの

  o  file

     file は特に問題なく動きますが、改良の余地がありま
     す：ftp.uk.linux.org <ftp://ftp.uk.linux.org/pub/Linux/libc/non-
     core/file.patch> にあるパッチをあてれば、バイナリが strip されてい
     るかどうかやエンディアンが混在した ELF バイナリかを見分けることも可
     能になります。

  o  make-3.74

     GNU の ftp サイトにあるソースコードを入手して libc-5.3.12 のリリー
     スノートにあるパッチをあてるか、tsx-11 から make-3.74.gz のバイナリ
     を入手してください。GNU の make には新しい ELF 版の libc バージョン
     でのみ露呈するバグがあります -- このバグは、実際には古い GNU の
     libc にあったバグに依存した実装になっているせいで、その libc のバグ
     はつい最近までの Linux の libc にもありました。そのため、古い a.out
     版の make プログラムを使っている場合は動作しますが、新しい ELF 用に
     はパッチが必要です。

     GNU Make の開発者たちもこのバグには気付いていて、将来のバージョンで
     は修正されるはずです。

  o  1.2.x カーネル

     1.2.x シリーズのカーネルについては 3 つのオプションがあります。

     1. Makefile を少し修正して、a.out コンパイラを使うようにします。 cd
        /usr/src/linux し、以下のパッチを切り出して patch - p1 であてて
        ください。以下のパッチを見ながら Makefile を手動で修正してもかま
        いません。以下のパッチファイルは簡単に理解できるでしょう (- で始
        まる行を削除して + で始まっている行を追加します)

          diff -u linux-1.2.13/Makefile.orig linux/Makefile
          --- linux-1.2.13/Makefile.orig  Wed Aug 16 20:53:26 1995
          +++ linux/Makefile      Fri Dec  8 16:19:49 1995
          @@ -12,9 +12,9 @@
           TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)

          -AS     =as
          -LD     =ld
          -HOSTCC =gcc -I$(TOPDIR)/include
          -CC     =gcc -D__KERNEL__ -I$(TOPDIR)/include
          +AS     =/usr/i486-linuxaout/bin/as
          +LD     =ld  -m i386linux
          +HOSTCC =gcc -b i486-linuxaout -I$(TOPDIR)/include
          +CC     =gcc -b i486-linuxaout -D__KERNEL__ -I$(TOPDIR)/include
           MAKE   =make
           CPP    =$(CC) -E
           AR     =ar

     あるいは、

     2. H.J.Lu 作のパッチをあてて、カーネルを ELF 形式でコンパイルできる
        ようにする(この場合、ELF 形式のコアダンプも可能になります)この
        パッチは <ftp://ftp.cdrom.com/pub/linux/slackware_source/kernel-
        source/v1.2/linuxelf-1.2.13.diff.gz> から入手できます。

        1.2 シリーズのカーネルを含んだELF 形式のディストリビューショ
        ン(RedHat 2.1 や Slackware 3)にはこのパッチが含まれているか、似
        たパッチが既にあたっているはずです。

        しかし、最善のアイデアは、多分、

     3. 2.0 へバージョンアップしましょう。とにかく 1.2 のころは ELF につ
        いて配慮されていませんでした。

     1.2.13 のバージョンを gcc 2.7.2 以上のバージョンでコンパイルする場
     合、別の問題も生じます。asm/io.h には gcc 2.7.2 でのみ露呈するバグ
     があり、修正するためのパッチは
     <ftp://ftp.uk.linux.org/pub/Linux/libc/misc/io.h> にあります。

  5.  より詳しい情報

  o  GCC-HOWTO <GCC-HOWTO.html>には、Linux でプログラムを開発する際に有
     益な情報が多数含まれています(少なくとも私はそう考えています。私が保
     守していますから)。GCC-HOWTO は、この文書と同じ場所にあるはずなの
     で、上記のリンクは相対指定になっています。

  o  linux-gcc メーリングリスト(これは linux.* のニュースを受信している
     場合、linux.dev.gcc ニュースグループにもなっています)は、自分からは
     投稿しなくても何が起きているかを知ることのできる最善の場所でしょ
     う。これは Usenet とは違うので、実際に開発に関わる問題のみを投稿す
     るようにしてください。メーリングリストに参加するには、 help という
     語を含むメールを majordomo@vger.rutgers.edu に送ってください。メー
     リングリストのアーカイブは  <http://www.linux.ncm.com/linux-gcc/>
     にあります。

  o  linux-gcc のメーリングリストで何が行なわれているかの情報は、私が更
     新を怠らない限り、linux-gcc web page
     <http://ftp.uk.linux.org/~barlow/linux/gcc-list.html> にあります。
     このページには、この HOWTO の最新版へのリンクもあり、本文の中で参照
     しているパッチも集めています。米国や英国の学術サイトへのリンクが細
     い人たち(英国の学術ネット以外のところではたいていそうでしょうけ
     ど)用に、このページは  <http://www.blackdown.org/elf/elf.html> にミ
     ラーされています。

  o  ELF 形式についての文書が tsx-11
     <ftp://tsx-11.mit.edu/pub/linux/packages/GCC/ELF.doc.tar.gz> にあり
     ます。この文書は多分ファイル形式を理解したい人やデバッグしたい人、
     バイナリのオブジェクトを直接操作するようなプログラムの作者にもっと
     も役立つものでしょう。

  o  H.J Lu が書いた ELF: From The Programmer's Perspective
     <ftp://tsx-11.mit.edu/pub/linux/packages/GCC/elf.latex.tar.gz> は
     ELF 形式でプログラムする際に有用な情報がずっと詳しく説明されていま
     す。もし LaTeX を処理できなければ、同じバージョンの PostScript 版が
     あります。

  o  ncurses ライブラリについての情報と terminfo データベースはEric
     Raymond's ncurses resource page
     <http://www.ccil.org/~esr/ncurses.html> にあります。

  o  ld.so パッケージに含まれている dlopen(3) の man page には関連する機
     能についての説明が書かれています。

  6.  その他

  6.1.  フィードバックのお願い

  Feedback は歓迎します。メールは daniel.barlow@linux.org へお願いしま
  す。秘密のメールを送る必要がある場合、私の web pages
  <http://ftp.uk.linux.org/~barlow/> にある PGP の公開鍵(ID 5F263625)を
  使ってください。

  この文書に答があるべき問題で、答が見つからない場合も私にメールしてくだ
  さい。この文書の中で触れられるべきではない問題で、私が答を知っているか
  も知れない問題については、まず comp.os.linux.* ニュースグループに投稿
  してみてください。たいていメールの問い合わせにも答えていますが、メール
  を無くすこともよくあるので。

  私の名前がゴミメーリングリストに載っているのを見た人は削除してくださる
  ようにお願いします。

  6.2.  翻訳版

  この文書の翻訳版を作りたい場合、積極的にやっていただいて構いませんが、
  一言連絡してください。私が話せる言語に翻訳してもらえる可能性は(悲しい
  ことに)数百分の一でしょうが、それはさておき、私の出来ることはよろこん
  でお手伝いします。

  私が知っている翻訳版は：

  o  イタリア語版 <http://www.psico.unipd.it/ildp/docs/HOWTO/ELF-
     HOWTO.html> をFavro Renata が翻訳しました。 (その他のイタリア語版
     HOWTO も <http://www.psico.unipd.it/ildp/docs/HOWTO/INDEX.html> に
     あります。

  o  こじまみつひろが日本語版を作成しました。
     <http://jf.gee.kyoto-u.ac.jp/JF/index.html>から入手できます。

  6.3.  法的な話題

  All trademarks used in this document are acknowledged as being owned
  by their respective owners.  Yow!

  The right of Daniel Barlow to be identified as the author of this work
  has been asserted in accordance with sections 77 and 78 of the
  Copyright Designs and Patents Act 1988.

  This document is copyright (C) 1996 Daniel Barlow
  <daniel.barlow@linux.org> It may be reproduced and distributed in
  whole or in part, in any medium physical or electronic, as long as
  this copyright notice is retained on all copies. Commercial
  redistribution is allowed and encouraged; however, the author would
  like to be notified of any such distributions.

  All translations, derivative works, or aggregate works incorporating
  any Linux HOWTO documents must be covered under this copyright notice.
  That is, you may not produce a derivative work from a HOWTO and impose
  additional restrictions on its distribution. Exceptions to these rules
  may be granted under certain conditions; please contact the Linux
  HOWTO coordinator at the address given below.

  In short, we wish to promote dissemination of this information through
  as many channels as possible. However, we do wish to retain copyright
  on the HOWTO documents, and would like to be notified of any plans to
  redistribute the HOWTOs.

  If you have questions, please contact Greg Hankins, the Linux HOWTO
  coordinator, at gregh@sunsite.unc.edu.

  この文書に現われたトレードマークは全てその所有者に帰属しています。

  この文書の原著者である Daniel Barlow の権利は 1988 年に制定された
  ``COpyright Desings and Patents" 法の 77 条と 78 条に規定されていま
  す。

  この文書は Daniel Barlow<daniel.barlow@linux.org> が著作権を有していま
  す。この著作権表示が示される限り、どのような物理的、電子的媒体を用い
  て、この文書の全体でも一部だけでも、コピーして再配布することが可能で
  す。商的利用も許諾され、推奨されますが、そのような場合には著者まで一言
  お知らせください。

  翻訳やこの文書から派生した文書、あらゆる Linux HOWTO 文書との組みあわ
  せた文書集なども、この著作権表示によって保護されることになります。すな
  わち、Linux の HOWTO から派生した作品に対して、その配布を妨げるような
  制限を課すことはできません。一定の条件のもとで例外を設けることも可能な
  ので、詳細については以下に示す Linux HOWTO のコーディネータに尋ねてく
  ださい。

  簡単に言えば、私たちは可能なかぎりの方法でこの文書などの情報を広く知ら
  せようと考えています。しかしながら、私たちは HOWTO 文書に著作権を設定
  し、HOWTO の再配布計画については知らせてもらいたいと思っています。

  質問があれば、現在の Linux HOWTO のコーディネータ、Grep Hankins
  gregh@sunsite.unc.edu へ連絡してください。

