1

組み込みシステム用のプログラムをクロスコンパイルしています。プログラムは共有ライブラリを使用します。これは、このようにオープンエンドします。

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>      //needed for dynamic linking

void  *FunctionLib;     //Handle to shared lib file
int   (*Function)();    //Pointer to loaded routine
const char *dlError;    //Pointer to error string

int main( argc, argv )
{
    int   rc;               //return codes
    printf("start...\n");

    //Open Dynamic Loadable Libary with absolute path
    FunctionLib = dlopen("/lalabu/sharedLib.so",RTLD_LAZY | RTLD_GLOBAL);
    dlError = dlerror();
    printf("Open sharedLib.so returns: %s \n", dlError);
    if( dlError ) exit(1);

    //Find function
    Function = dlsym( FunctionLib, "getSomething");
    dlError = dlerror();
    printf("Find symbol getSomething returns: %s \n", dlError);
    if( dlError ) exit(1);
...

次のコマンドでコードをコンパイルしています

mips-linux-uclibc-gcc -Wall -ldl ./dynamic_linking.c -o /dynamic_linking

警告などなしで動作します。
デバイスでこのコードを実行しようとすると、次のエラーが表示されます。

# ./dynamic_linking
start...
Open sharedLib.so returns: (null)
Find symbol getSomething returns: Unable to resolve symbol
./dynamic_linking: can't resolv '_ZNSt8ios_base4InitD1Ev'

IDA でどの関数 sharedLib.so をインポートしたいかを見ると、関数 (またはシンボル?) '_ZNSt8ios_base4InitD1Ev' とそれがあるべき場所 (libc.so.0) が表示されます。
IDA を使用して libc.so.0 を見てみると、このように呼び出された関数は見当たりません。また、ios_base、ios、または base のようなものはありません。
RTLD_LAZY の代わりに RTLD_NOW を使用する場合を除いて、常に上記のエラーが発生する dlopen() でさまざまなフラグの組み合わせを既に試しました。

Segmentation fault (core dumped)

それ以外の

./dynamic_linking: can't resolv '_ZNSt8ios_base4InitD1Ev'

さらに、rdynamic のようないくつかの gcc リンク オプションを試しましたが、常に同じ結果が得られました。
さらに、_ZNSt8ios_base4InitD1Ev、「libc.so.0」を使用しない共有ライブラリを使用して、C コードが機能しているかどうかを確認しようとしました。名前と絶対パスだけを変更し、検索機能部分を削除しました。エラーなく動作しました。
私の投稿からわかるように、私はクロス コンパイルと動的ライブラリの使用を開始したばかりなので、私のせいは別の場所にあるのかもしれません。また、問題がどこにあるのかさえ理解できていないので、ヒントがあれば大歓迎です。さらに情報が必要な場合は、喜んで提供いたします。
はじめまして、ピングー

4

1 に答える 1

3

これ_ZNSt8ios-base4InitD1Evは C シンボルではなく、C++ シンボルです。

$ echo _ZNSt8ios-base4InitD1Ev | c++filt

手がかりはありませんが、-を aに置き換えた場合_(おそらくタイプミスですか?):

$ echo _ZNSt8ios_base4InitD1Ev | c++filt
std::ios_base::Init::~Init()

これは、C++ STD ライブラリの内部クラスのデストラクタです。libstdc++.soそのため、代わりにライブラリを確認する必要がありますlibc.so

私のアドバイスは、G++ を使用してプログラムをコンパイルすることです。これにより、C++ ライブラリが適切に初期化されます。動的にロードされることを意図していないため、セグメンテーション違反が発生します。

于 2012-12-17T17:54:51.507 に答える