内部フラッシュから直接 2 つのアプリケーションのうちの 1 つを実行することを決定するブートローダーを持つ組み込みアプリケーションがあります。これらのアプリの位置を独立させて、両方を同じベースアドレスでコンパイルできるようにしようとしています。オペレーティング システムがないため、動的リンカーは使用できません。これまでのところ、-fpie オプション (gcc を使用) を使用してビルドを試みましたが、あまり成功していません。関数呼び出しは正しいように見えますが、グローバル データには正しいアドレスがありません。ローカルで定義されたグローバル データのアドレスは、アプリが元のベース アドレスからオフセットされた分だけオフセットされているようです。他のファイルで宣言されているグローバル データのアドレスが完全に間違っています (-fpic でビルドすると、ローカルで宣言されたグローバル データと他のファイルのグローバル データの両方が完全に間違っています)。
2 に答える
私はついにそれを機能させました。次のことを行う必要があるようです。すべてのコードは-fpicに準拠する必要があります(以前は-fpieを試していました)
また、リンカースクリプトに変更が必要でした。私はGOTをスラムセクションに押し込んでいましたが、それはフラッシュされていたダイナミックセクションの後にありました。フラッシュのダイナミックセクションの前にGOTセクションが配置されている場合は、すべてが正しく機能しているように見えます。これが重要である理由はわかりませんが、すべてが修正されたようです。これ以前は、GOTに正しい値が格納されていたため、コードがGOTを正しく見つけられなかったかのようでしたが、すべての変数のアドレスが正しくありませんでした。
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