2009-08-28 14 views
19

私は、Linux上で単純なユーザスペースELFローダを書いています(なぜ?for 'fun')。現在のところ、私のローダーは非常に単純で、位置に依存しないコードを含む静的にリンクされたELFファイルだけをロードするように設計されています。ロード時ELF再配置

通常、プログラムがカーネルのELFローダーによってロードされると、プログラムはそれ自身のアドレス空間にロードされます。そのため、データセグメントとコードセグメントは、ELFセグメントで指定されている正しい仮想アドレスにロードできます。

私のケースでは、私はmmap経由でカーネルのアドレスを要求しており、ELFセグメントで要求されたアドレスを取得しても取得しなくてもよい。これは位置に依存しないため、コードセグメントでは問題ありません。ただし、データセグメントが予想されるアドレスにロードされていない場合、コードはデータセグメントに格納されているものを正しく参照することはできません。

実際、私のローダーは、データを含まない単純なアセンブリ実行可能ファイルで正常に動作するようです。しかし、データセグメントを追加して参照すると、実行ファイルが正しく実行されないか、またはSEGFAULTが失敗します。

可能であれば、データセグメントへの参照が正しい場所を指すように修正する方法はありますか。この目的のために(静的な)ELFファイルに再配置セクションが格納されていますか?

+1

mmapを呼び出しているプロセスが要求されたアドレスを与えているときにmmap()が失敗したのは、そのページがすでにアドレス空間に割り当てられているからですか? –

+0

はい、これがおそらく理由です。私はコード/データを "どこにもない"場所に置くように 'ld'に頼むことを考えましたが、最初に汎用的な解決策が可能かどうか疑問に思っていました。私がここで何の反応も得なければ、私は先に進んでそれを試みるかもしれない。 –

答えて

8

.gotセクション(グローバルオフセットテーブル)で使用できる絶対アドレスを変更すると、プログラムが機能するはずです。 .textと.dataの間の新しい距離に対応するために、絶対アドレス計算を変更してください。あなたのアーキテクチャのために、この情報がどこから来るのか理解しておく必要があります。 Global Offset Table (Processor-Specific)

幸運:

はこれを参照してください。

+0

新しい距離を計算しようとするべきではありません。命令によっては、相対アドレス指定を使用してデータセグメントの内容を参照するものもあれば、セグメントを遠ざけるだけでそれを破るものもあります。セグメントを適切にマッピングするには、 'MAP_FIXED'を使用する必要があります。必要な領域が利用できない場合は' mmap'呼び出しが失敗し、両方のセグメントの大きな領域をアトミックにマップし、その部分をマップ解除して、の穴。 –

4

あなたがカーネルが提供する仮想アドレス空間を完全にエミュレートし、その仮想空間内でコードを実行しない限り、私はそれを行うことはできません。ファイルからデータセクションをmmapすると、ELFインタプリタの仮想アドレス空間の未知のアドレスに本来配置されているので、あなたのコードはそれを何ら参照することができません。

誇りに思うことは間違っています。ここで学ぶのはとてもクールです。

+0

ターゲットのELFとローダの機能が異なるプロセスにあります。あなたがローダーのほとんどのための標準的なツールと手順を使用するこの方法で –