GNU/Linux >> Linux の 問題 >  >> Linux

Linux 共有ライブラリのストリッピング

プライベート部分を匿名の名前空間にラップすると、 std::abs もありません private_function でもありません 記号表で見ることができます:

namespace{
#include<cmath>
  float private_function(float f)
  {
    return std::abs(f);
  }
}
extern "C" float public_function(float f)
{
        return private_function(f);
}

コンパイル中 (g++ 4.3.3):

g++ -shared -o libtest.so test.cpp -s

検査:

# nm -DC libtest.so
         w _Jv_RegisterClasses
0000200c A __bss_start
         w __cxa_finalize
         w __gmon_start__
0000200c A _edata
00002014 A _end
000004a8 T _fini
000002f4 T _init
00000445 T public_function

Ulrich Drepper が、Linux/Unix の共有ライブラリを作成する際の (すべての?) 側面に関するエッセイを書いたことに注意してください。このエッセイでは、他の多くのトピックの中でも、エクスポートされたシンボルの制御について説明しています。

これは、共有ライブラリからホワイトリストの関数のみをエクスポートする方法を明確にするのに非常に便利でした.


デフォルトの表示属性と -fvisibility=hidden の使用は、-fvisibility-inlines-hidden で強化する必要があります。

また、stdlib エクスポートを非表示にしようとすることも忘れてください。理由については、この GCC バグを参照してください。

また、特定のヘッダーにすべてのパブリック シンボルがある場合は、それらを #pragma GCC visibility push(default) でラップできます。 と #pragma GCC visibility pop 属性を使用する代わりに。ただし、クロス プラットフォーム ライブラリを作成している場合は、Windows DLL と Linux DSO のエクスポート戦略を統合する手法について、共有ライブラリのエクスポートされたシンボルの制御を参照してください。


したがって、現時点での解決策は次のとおりです。

test.cpp

#include <cmath>
#include <vector>
#include <typeinfo>

struct private_struct
{
    float f;
};

float private_function(float f)
{
    return std::abs(f);
}

void other_private_function()
{
    std::vector<private_struct> f(1);
}

extern "C" void __attribute__ ((visibility ("default"))) public_function2()
{
    other_private_function();
}

extern "C" float __attribute__ ((visibility ("default"))) public_function1(float f)
{
    return private_function(f);
}

exports.version

LIBTEST 
{
global:
    public*;
local:
    *;
};

でコンパイル

g++ -shared test.cpp -o libtest.so -fvisibility=hidden -fvisibility-inlines-hidden -s -Wl,--version-script=exports.version

与える

00000000 A LIBTEST
         w _Jv_RegisterClasses
         U _Unwind_Resume
         U std::__throw_bad_alloc()
         U operator delete(void*)
         U operator new(unsigned int)
         w __cxa_finalize
         w __gmon_start__
         U __gxx_personality_v0
000005db T public_function1
00000676 T public_function2

これは、私たちが探しているものにかなり近いものです。ただし、いくつかの落とし穴があります:

  • 内部コードで "exported" プレフィックス (この単純な例では "public" ですが、この場合は明らかにもっと便利なもの) を使用しないようにする必要があります。
  • まだ多くのシンボル名が文字列テーブルに残っており、これは RTTI にかかっているようです。-fno-rtti を使用すると、私の簡単なテストではそれらがなくなりますが、核となる解決策です。

誰かが思いついたより良い解決策を喜んで受け入れます!


Linux
  1. Linux での ipcs コマンドの例

  2. Linux で実行可能ファイルが使用するすべての共有ライブラリを表示するには?

  3. Linux で googleTest を共有ライブラリとして設定する方法

  1. CでのLinuxソフトウェアライブラリを理解するためのガイド

  2. Linux の共有ライブラリが実行可能であるのはなぜですか?

  3. Ubuntu Linux - 共有 VHDX

  1. Linuxで動的ライブラリと静的ライブラリを処理する方法

  2. 共有ライブラリの読み込み中にエラーが発生しましたlibcrypto.so.1.1–OpenSSL[修正]

  3. 共有ライブラリの「どれ」に相当しますか?