2009-04-16 14 views
5

WindowsホストでRVDSコンパイラを使用して* .oオブジェクトコードファイル(Cソースコード)を使用して共有ライブラリ(* .so)を作成しました。共有ライブラリからシンボルをエクスポートする方法

私は(Linuxホスト上のアームの目標のためのgccを使用して)アプリケーションで、この共有オブジェクトをリンクし、実行中にセグメンテーションフォールトを生成し、実行し、取得します。(私はそれをデバッグする必要があります知っている!)

の代わりに共有ライブラリを作成して、同じソースファイルを持つ静的ライブラリを作成し、アプリケーションとリンクしてからアプリケーションを実行すると、正常に動作します。

だから私の質問は以下のとおりです。 - リンクされたときに、それが正常に動作するように

  1. は、私はいくつかの構築物を用いて、私のソースファイルでは、明示的に、シンボル(アプリケーションにエクスポート機能)、または任意の他のシンボルをエクスポートする必要がありますかアプリケーションと一緒に?何が必要なのですか、どうすればいいですか?

  2. ライブラリの作成時に、共有ライブラリがどのように機能しますか?つまり、関数がロードされて実行されるアドレスはライブラリに与えられますか?アプリケーション(main())は、ライブラリ関数が実行されるアドレスをどのように解決するのですか?

  3. 静的ライブラリはどのように機能しますか。静的ライブラリの場合、このアドレスの指定と解決はどのように行われますか?

ありがとう。

1)いいえ、あなたは何もする必要はありません。

答えて

11

これは、Linux上でどのように動作するかです。ただし、gcc -fvisibilityコマンドライン引数を使用してエクスポート変数を制限し、visibility属性を使用してエクスポートされたエントリに明示的にフラグを立てることができます。

2)実行可能ファイルには、インポートするすべての関数のテーブルがあります(これらはすべてデフォルトの可視性を持つ関数です)。ローダー/リンカーは、実行の直前にライブラリをロードしてこのテーブルに書き込むためのアドレスを選択します。これらの関数の呼び出しは間接呼び出しです。 (共有オブジェクトの場合も同様です)

3)静的リンクはリンク時(コンパイル後)に実行されます。実際のアドレスはアセンブリで置き換えられ、直接呼び出しです。

注:PIC(position independent code)というものがあります。 AFAIKでは、同じ共有オブジェクト内のデータ/関数への参照を扱うので、リンカーはライブラリをロードするときにコードの半分のコードを上書きする必要はありません。自分のデータ。あなたはそれを実験しようとするかもしれません。

0

あなたはクラッシュの原因について何か知っていますか?

共有ライブラリーを動的にロードすると(たとえば、dlopen()を介して)、ライブラリーがロードされていないときにOKをロードしてからヌルポインターを介して関数を実行しようとしていることが考えられます。

+0

@Jonathan:dlopen()呼び出しを使用して共有ライブラリをロードしていません。 – goldenmean

+0

OK - 私はアイデアがありません。私はUnix/Linuxにもっと精通しています。私はもっ​​と助けになるかもしれない。 –

3
  1. あなたはそれがデフォルトですべてのシンボルをエクスポートして、gccでシンボルをエクスポートする必要はありません。しかし、RVDSは同じことをしてもしなくてもかまいません。 RVDSコンパイラのドキュメントを確認してください( 'Relocatable ELF'の出力を設定してみてください)。)

  2. Linux上の共有ライブラリは、実行時にベースアドレスが決定されるため、再配置可能でなければなりません。位置に依存しないコードを生成することは、ライブラリの再配置に必要な作業量を削減する上で理想的です。ライブラリが再配置可能でない場合は、がクラッシュします(つまり、ダイナミックライブラリを作成する前に、オブジェクトファイルから再配置情報を削除しないでください)。シンボルは、ベースアドレスが選択され、内部参照が再配置された後、実行時にアドレスに解決されます。

  3. スタティックライブラリでは、すべてのシンボルの解決、再配置、およびロードアドレスの割り当てはコンパイル時に行われます。

コンパイラが出しているコードは、実行時に再配置可能ではないと思います。しかし、静的ライブラリを破ることなくどうしたらどうなるかは私には謎です...

静的ライブラリと共有ライブラリをRVDSから直接生成する場合、その静的ライブラリを変換することをお勧めします共有ライブラリへ:

gcc -shared -o libfoo.so libfoo.a 

これは、その後、RVDSの共有ライブラリリンカー(またはその構成)を助けた場合は可能性が壊れています。

関連する問題