Удаление символов из общей библиотеки, похоже, не работает - PullRequest
0 голосов
/ 24 октября 2019

Я пытаюсь удалить непубличные символы из моей общей библиотеки с помощью команды strip, но когда я впоследствии применяю «nm -C -D», я все равно вижу все символы.

Я уже проверенэтот и другие посты: Удаление общих библиотек Linux , а также gcc Wiki: https://gcc.gnu.org/wiki/Visibility Но с моим примером кода предлагаемое решение, похоже, не работает.

Я объявляю двапростые классы, один должен оставаться видимым, другой должен быть удален. Для общего пользования я объявляю __attribute__ ((visibility ("default"))) в исходном коде.

Когда я компилирую и связываюсь с -fvisibility = hidden, а затем запускаю "strip --strip-all --discard-all" в общей библиотеке,оба класса все еще видны в секции T (ext).

Это мой заголовочный файл:

#pragma once

#if __GNUC__ >= 4
    #define DLL_PUBLIC __attribute__ ((visibility ("default")))
#else
    #define DLL_PUBLIC
#endif

class DLL_PUBLIC PublicClass
{
public:
  PublicClass() = default;
  ~PublicClass() = default;

  void doSomethingPublic();
};

class PrivateClass
{
public:
  PrivateClass() = default;
  ~PrivateClass() = default;

  void doSomethingPrivate();
};

и это источник:

#include <iostream>
#include "test.hpp"

void PublicClass::doSomethingPublic() { std::cout << "public call" << std::endl; } 
void PrivateClass::doSomethingPrivate() { std::cout << "private call" << std::endl; } 

Я компилируюобъектный файл и свяжите общую библиотеку с gcc 7.4.0 в Ubuntu 18.04:

$ /usr/local/bin/c++ -fvisibility=hidden -O3 -DNDEBUG -fPIC -std=gnu++14 -c test.cpp -o test.cpp.o
$ /usr/local/bin/c++ -fvisibility=hidden -fPIC -DNDEBUG -O3 -shared -Wl,-soname,libtest.so -o libtest.so test.cpp.o

Применение команды strip и отображение таблицы символов:

$ strip --strip-all --discard-all --verbose libtest.so
copy from `libtest.so' [elf64-x86-64] to `stSNqAeg' [elf64-x86-64]
$ nm -C -D libtest.so
0000000000201058 B __bss_start
                 U __cxa_atexit
                 w __cxa_finalize
0000000000201058 D _edata
0000000000201060 B _end
0000000000000b84 T _fini
                 w __gmon_start__
00000000000008a8 T _init
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000000a60 T PublicClass::doSomethingPublic()
0000000000000af0 T PrivateClass::doSomethingPrivate()
                 U std::ctype<char>::_M_widen_init() const
0000000000000b80 W std::ctype<char>::do_widen(char) const
                 U std::ostream::put(char)
                 U std::ostream::flush()
                 U std::ios_base::Init::Init()
                 U std::ios_base::Init::~Init()
                 U std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
                 U std::__throw_bad_cast()
                 U std::cout

Команда strip фактически переписываетобщая библиотека (дата и размер изменены), но я все еще вижу частные символы. Я ожидаю, что метод PrivateClass :: doSomethingPrivate будет удален из таблицы символов.

Буду благодарен за любые подсказки.

1 Ответ

1 голос
/ 24 октября 2019

Вам нужно скомпилировать с -fvisibility=hidden:

$ g++ -fvisibility=hidden -shared -fPIC tmp.cc
$ readelf -D -sW a.out | grep doSomething
    9  16: 000000000000092c    58 FUNC    GLOBAL DEFAULT  10 _ZN11PublicClass17doSomethingPublicEv
...