2017-01-08 3 views
4

dladdrで動作する間接関数を持つelfにgnu拡張を取得できません。dladdrを使ってgnu間接関数の名前を取得する方法は?

fabsおよびsinは、libmの2つの動的関数です。ここで、sinは間接関数です。ポインタからfabsを検索するとうまく動作しますが、sinが見つかりません。私はdlopen-rdynamicへの様々なフラグを試してみました。

デバッガは、gnu-indirect-function variable__sin_avxまでからから評価する方法sin示します。

ここに何かが見つからないか、間接機能がdladdrでサポートされていませんか?

/* 
    compiled with g++-5 -fPIC -ldl 
*/ 

#include <cmath> 
#include <dlfcn.h> 
#include <iostream> 

char const * name (void * arg) 
{ 
    void * h = dlopen (NULL, RTLD_LAZY); 

    if (h) 
    { 
     Dl_info res; 
     int status = dladdr (arg, & res); 
     dlclose (h); 

     if (status && res.dli_sname && arg == res.dli_saddr) 
      return res.dli_sname; 
    } 

    return ""; 
} 

int main() 
{ 
    std::cout << fabs (0.0) << " " << name ((void *) fabs) << std::endl; // found 
    std::cout << sin (0.0) << " " << name ((void *) sin) << std::endl; // not found 
} 
+0

興味深いことに、 '-fPIC'を削除するとうまく動作します。 – yugr

答えて

3

アム私はここで何かが足りないか、間接的な機能はdladdrによってサポートされていませんか?

これは面白かったです。

iffunctionsは、元の関数のアドレス(この場合はsin)を、現在のプラットフォーム上のダイナミックリンカによって解決されたものに置き換えます。 sinは、CPUの能力に応じて4つの実装の1つに解決することができます。

libm_ifunc (__sin, (HAS_ARCH_FEATURE (FMA4_Usable) ? __sin_fma4 : 
        HAS_ARCH_FEATURE (AVX_Usable) 
        ? __sin_avx : __sin_sse2)); 
weak_alias (__sin, sin) 

今、各__sin_XXXlibm.soからをエクスポートしdladdrはそれを見つけることができない理由ですないある内部glibcの関数です。

だから、答えはノー、dladdrはifuncsとうまく動作しません。基本的には...

あなたは-fPIC

を削除する場合は、W/Oコンパイルするたびにこれが起こる動作するように管理します-fPICコンパイラは、現在のソースファイルがメイン実行可能ファイルに移動し、実行時関数アドレスが実行可能ファイルのPLTエントリに解決されることが保証されていることを認識します。したがって、GOTからロードする代わりに、PLTアドレスをnamedladdrに渡すだけで、うれしく実行可能ファイルのsymtabにsinが配置されます。

EDIT:glibcの人々hereによって確認

+0

ありがとうございました。私はifuncと可視性についていくつかの[posts](https://gcc.gnu.org/ml/gcc/2016-08/msg00138.html)を見つけましたが、その件はかなり新しくなっています。回避策として、元の間接関数、 '__attribute__ ifunc'を持つ関数を参照する方法はありますか? – listcrawler

+0

私は個人的にGOTテーブルを手動で解析するより簡単な方法は分かりません(例:[here](http://vxheaven.org/lib/vrn00.html#c6))。 [libc-help](https://sourceware.org/ml/libc-help/)で尋ねることができます。 – yugr

+0

[こちら](https://sourceware.org/ml/libc-help/2017-01/msg00010.html)は、libc-helpに関する私の質問に対する答えです。要するに、元のifuncシンボル名に関する情報は、その実装に解決されると失われます。 私のアセンブリを解析することについて - しかし、私は生成されたコードから読み取ることができます、ifuncsがプログラムの開始時に既に解決されていないと、最初の呼び出しではないかどうかはわかりません。もしそうなら、元のifuncアドレスのためにGOTを解析する機会はありませんでしょうか? – listcrawler

関連する問題