私は組み込みプラットフォーム向けに開発しています。共有ライブラリを動的にリンクする方法を検討するのは苦労しています。私はbFLTファイル形式を使用しており、実行可能ファイルと共有ライブラリがロードされている場所を制御することはできません。位置独立コード、共有ライブラリ、コードベニア - それらを連携させる
ローダーは共有ライブラリと実行可能ファイルを正しくメモリにロードし、実行時に実行可能ファイルのGOTを変更して共有ライブラリにリンクします。
私は正常に関数のアドレスを取得することができますし、その場所でコードを逆アセンブルするのが正しいことを知っています。しかし、関数を呼び出そうとすると、すべてがクラッシュします。
共有ライブラリ関数を呼び出すときにGCCが 'コードベニア'を追加し、関数が呼び出されたときに迂回し、実際に関数のアドレスに分岐しません。コードベニアが分岐するアドレスは、実行可能バイナリ内の再配置のリストに表示されないため、正しく再配置されません。
ベニヤの分解は、次のようになります。私は、関数のアドレスを取得し、関数ポインタに入れて(そのため、「コードベニヤ」をバイパスして)、それを呼び出す場合
000008d0 <__library_call_veneer>:
8d0: e51ff004 ldr pc, [pc, #-4] ; 8d4 <__library_call_veneer+0x4>
8d4: 03000320 .word 0x03000320 ; This address isn't correctly relocated!
、共有ライブラリは完全に機能します。例えばので
:
#define DIRECT_LIB_CALL(x, args...) do { \
typeof(x) * volatile tmp = x; \
tmp(#args); \
} while (0)
DIRECT_LIB_CALL(library_call); /* works */
library_call(); /* crashes */
はどちらかへの道は、GOTに位置アドレスに直接コードベニヤとブランチを作るか、何らかの方法でそのコードベニヤ分岐アドレスをしないためにGCCを伝える、あります実行する再配置のリストに表示されますか?
extern Cを使用してライブラリのプロトタイプを宣言していますか? –
私はCの下でコンパイルしていますので、extern "C"は冗長でしょうか? – tangrs
ベニアは、ARMシステム上で必要以上に必要とされるため、ベニアを実行するのが適切です。しかし、アドレスを更新しないのは...あなたのファイル形式を見ると、http://docs.blackfin.uclinux.org/doku.php?id=toolchain:executable_file_formatsとhttp://docs.blackfin.uclinux.org /doku.php?id=toolchain:creating_librariesが表示されます。競合する共有ライブラリIDがあるか、リンクフラグを変更する必要があるようです(ここで説明しています)。申し訳ありませんが、ずっと助けてくれることはありません –