ldd -r -v Как мне добавить символ версии в файл?

#linux #gcc #binutils

#linux #gcc #binutils

Вопрос:

 Version information:
./VideoEncoderFilter.so:
    libgcc_s.so.1 (GCC_3.0) => /lib/x86_64-linux-gnu/libgcc_s.so.1
    libva.so.1 (VA_API_0.34.0) => not found
    libdl.so.2 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libdl.so.2
    libstdc  .so.6 (GLIBCXX_3.4.20) => /usr/lib/x86_64-linux-gnu/libstdc  .so.6
    libstdc  .so.6 (CXXABI_1.3.8) => /usr/lib/x86_64-linux-gnu/libstdc  .so.6
    libstdc  .so.6 (CXXABI_1.3.9) => /usr/lib/x86_64-linux-gnu/libstdc  .so.6
    libstdc  .so.6 (CXXABI_1.3) => /usr/lib/x86_64-linux-gnu/libstdc  .so.6
    libstdc  .so.6 (GLIBCXX_3.4.15) => /usr/lib/x86_64-linux-gnu/libstdc  .so.6
  

Мне любопытно, как этот символ версии VA_API_0.34.0 добавлен в VideoEncoderFilter.so .

Если у меня есть foo.c и я хочу создать символ версии FOO_API_0.34.0 , что мне делать?

 gcc -c -fPIC foo.c -o foo.o
gcc foo.o -shared -o libfoo.so
  

Ответ №1:

GNU ld поддерживает сценарии версий. Если вы хотите добавить версию FOO_API_0.34.0 к символу foo , вы можете сделать это следующим образом:

 $ cat libfoo.versions
FOO_API_0.34.0 {
  global: foo;
};
$ gcc -c -fPIC foo.c -o foo.o
$ gcc foo.o -shared -o libfoo.so -Wl,--version-script=libfoo.versions
  

Вы можете убедиться, что этот символ присутствует, используя readelf :

 $ readelf --dyn-syms -W libfoo.so

Symbol table '.dynsym' contains 7 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTable
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
     4: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@GLIBC_2.2.5 (3)
     5: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  ABS FOO_API_0.34.0
     6: 00000000000010f5    11 FUNC    GLOBAL DEFAULT   12 foo@@FOO_API_0.34.0
  

Комментарии:

1. таким образом, компоновщик автоматически откажется от ссылки libfoo.so кроме FOO_API_0.34.0?

2. Извините, я не понимаю. Не могли бы вы перефразировать?

3. Извините, мой плохой английский. Например, я компилирую main.c с libfoo.so (FOO_API_0.34.0) на «a.out», а затем я заменяю libfoo.so (FOO_API_0.34.0) с libfoo.so (FOO_API_0.35.0). Программа «a.out» теперь не может быть запущена, верно? Предположим libfoo.so (FOO_API_0.35.0) точно такой же, как и у более старого, за исключением libfoo.versions.

4. Итак, по сути, «-Wl,—version-script=libfoo.versions» просто добавьте символ в libfoo.so . И исполняемый файл должен найти все существующие символы. Используя этот метод, можно архивировать, избегая неправильного использования пользователем неподдерживаемой динамической библиотеки. Я прав?

5. Да, это в основном правильно. Вы можете экспортировать несколько версий одного и того же символа из общей библиотеки, например, используя атрибут функции GCC symver (доступен в GCC 10 или более поздней версии).