Что делает символ в библиотеке ELF объектом или обычным? - PullRequest
1 голос
/ 04 апреля 2019

У меня есть приложение, которое загружает некоторые плагины через dlopen, в частности dlopen(name, RTLD_LAZY|RTLD_DEEPBIND).Есть некоторые плагины (предоставленные в двоичной форме), которые загружаются нормально, но плагин, который я пытаюсь создать, не может загрузить с ошибкой:

/opt/app/plugins/plugin.so: undefined symbol: Log_Modules

Все плагины ссылаются на этот символ и библиотеку, котораяпри условии, что он загружен в процессе.Однако запись, напечатанная objdump -D, отличается.В загружаемых плагинах написано

00000000      DO *UND*       00000000              Log_Modules

, а в библиотеке, определяющей его, написано

000130dc g    DO .data       00000004  Base        Log_Modules

, а в модуле, который я создал, -

00000000      D  *UND*       00000000              Log_Modules

Страница руководства по objdump просто говорит, что флаг означает

Символ - это имя функции (F), файла (f) или объекта (O) или просто обычный символ (пробел).

, но я не вижу никаких намеков на разницу между объектом и нормальным символом.Итак,

  • в чем разница,
  • , что делает символ тем или иным на уровне языка C или C ++ или на уровне компоновщика, и
  • действительно ли он долженсделать символ не разрешенным?

Ответы [ 2 ]

2 голосов
/ 05 апреля 2019

в чем разница

Таблица символов .st_info содержит STT_OBJECT вместо STT_FUNC.

что делает символ одним или другим на уровне языка C или C ++ или на уровне компоновщика

На уровне C компилятор пометит метки функций @function при выдаче кода сборки, а ассемблер добавит флаг STT_FUNC при выдаче таблицы символов.

действительно ли предполагается, что символ не разрешается?

Нет. Скорее всего, ваша проблема не связана с этим.

Как правило, objdump - это неправильный инструмент для просмотра файлов ELF (он сопоставляется с моделью данных BFD, которая устарела в течение последних 20+ лет). Вместо этого используйте readelf.

Дикая догадка: ваш plugin.so определяет, но не экспортирует символ. Используйте

nm -D plugin.so | grep ' Log_Modules$'
nm    plugin.so | grep ' Log_Modules$'

Если Log_Modules появляется во втором выводе команды, но не в первом, тогда мое предположение верно.

0 голосов
/ 08 апреля 2019

в чем разница

Флаг O соответствует флагу STT_OBJECT, обозначающему объект, который является переменной.

что делает символ одним или другим на уровне языка C или C ++ или на уровне компоновщика

Очевидно, что компоновщик помечает символы флагом STT_OBJECT, только если он действительно видит определение, то есть когда библиотека, которая его определяет, предоставляется как зависимость. Только внешние объявления не помечены.

действительно ли предполагается, что символ не разрешается?

При разрешении символов компоновщик просматривает явно перечисленные зависимости и библиотеки, загруженные RTLD_GLOBAL, который включает зависимости основного исполняемого файла. Поэтому, когда основной исполняемый файл уже связывает определяющую библиотеку, плагину не удастся явно связать его, но если он сам загружен с dlopen (без RTLD_GLOBAL), он не будет.

Отсутствие самого флага не является проблемой, но намекает на реальную проблему отсутствия ссылки на библиотеку.

...