11

内部フラッシュから直接 2 つのアプリケーションのうちの 1 つを実行することを決定するブートローダーを持つ組み込みアプリケーションがあります。これらのアプリの位置を独立させて、両方を同じベースアドレスでコンパイルできるようにしようとしています。オペレーティング システムがないため、動的リンカーは使用できません。これまでのところ、-fpie オプション (gcc を使用) を使用してビルドを試みましたが、あまり成功していません。関数呼び出しは正しいように見えますが、グローバル データには正しいアドレスがありません。ローカルで定義されたグローバル データのアドレスは、アプリが元のベース アドレスからオフセットされた分だけオフセットされているようです。他のファイルで宣言されているグローバル データのアドレスが完全に間違っています (-fpic でビルドすると、ローカルで宣言されたグローバル データと他のファイルのグローバル データの両方が完全に間違っています)。

4

2 に答える 2

12

私はついにそれを機能させました。次のことを行う必要があるようです。すべてのコードは-fpicに準拠する必要があります(以前は-fpieを試していました)

また、リンカースクリプトに変更が必要でした。私はGOTをスラムセクションに押し込んでいましたが、それはフラッシュされていたダイナミックセクションの後にありました。フラッシュのダイナミックセクションの前にGOTセクションが配置されている場合は、すべてが正しく機能しているように見えます。これが重要である理由はわかりませんが、すべてが修正されたようです。これ以前は、GOTに正しい値が格納されていたため、コードがGOTを正しく見つけられなかったかのようでしたが、すべての変数のアドレスが正しくありませんでした。

于 2011-02-22T03:36:34.840 に答える
6

PIE (および PIC) コードは、あるアドレス (デフォルトとは異なる) にロードした後、実行する前に再配置プロセスを必要とします。のコードを参照することをお勧めします ld.so。また、バイナリの再配置テーブルを確認する必要があります (例: を使用readelf -r)。

これは PIE に関する優れたプレゼンテーションです (これは OpenBSD に関するものですが、プロセスは同じです)。http://www.openbsd.org/papers/nycbsdcon08-pie/またはhttp://www.dcbsdcon.org/speakers/slides/miller_dcbsdcon2009.pdf

GOTを変更するだけでなく、すべての再配置を見つけて実行する必要があると思います。

基本的に、ld.so による PIE バイナリの処理は、PIC での動的ライブラリの処理とほぼ同じであり、ライブラリではなく、実行イメージ自体が再配置されます。

表示される「間違ったアドレス」は、再配置解決によって実際の値が書き込まれる場所です。i386 http://books.google.com/books?id=Id9cYsIdjIwC&pg=PA174に関しては、移転があります:

  • R_386_GOTPC
  • R_386_GOT32
  • R_386_GOTOFF
  • R_386_RELATIVE

コードがグローバル データにアクセスする前に、リンカはそれらすべてを解決する必要があります。

Readelf -r サンプル:

動的にリンクされたもの

$ readelf -r fdyn

Relocation section '.rel.dyn' at offset 0x27c contains 1 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
08049ff0  00000106 R_386_GLOB_DAT    00000000   __gmon_start__

Relocation section '.rel.plt' at offset 0x284 contains 2 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0804a000  00000107 R_386_JUMP_SLOT   00000000   __gmon_start__
0804a004  00000207 R_386_JUMP_SLOT   00000000   __libc_start_main

パイ:

$ readelf -r fPIE

Relocation section '.rel.dyn' at offset 0x388 contains 6 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00001fe8  00000008 R_386_RELATIVE
00001ff0  00000008 R_386_RELATIVE
00002010  00000008 R_386_RELATIVE
00001fe0  00000106 R_386_GLOB_DAT    00000000   __gmon_start__
00001fe4  00000206 R_386_GLOB_DAT    00000000   _Jv_RegisterClasses
00001fec  00000406 R_386_GLOB_DAT    00000000   __cxa_finalize

Relocation section '.rel.plt' at offset 0x3b8 contains 3 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00002000  00000107 R_386_JUMP_SLOT   00000000   __gmon_start__
00002004  00000307 R_386_JUMP_SLOT   00000000   __libc_start_main
00002008  00000407 R_386_JUMP_SLOT   00000000   __cxa_finalize
于 2011-02-17T02:24:23.467 に答える