Непредвиденные последствия objcopy для статических библиотек

Фон

У меня есть набор из трех почти идентичных статических библиотек c (скомпилирован с -fPIC), для которого я не могу их перекомпилировать. Все библиотеки экспортируют одни и те же символы, поэтому единственный способ, которым я могу связать их вместе, - это изменить символы с префиксом для каждой статической библиотеки через objcopyт.е.

for i in pineapple coconut banana
do
    objcopy --prefix-symbols=${i}_ lib${i}.a
done

Теперь у меня есть три библиотеки с уникальными символами, и я могу приступить к написанию заголовка, чтобы иметь дело с тремя почти дублирующимися файлами заголовков /API для каждой из библиотек.


Вопрос

Это просто переименование экспортированных символов библиотеки, как это безопасно? Есть ли у него какие-либо "ошибки" или непредвиденные последствия, которые могут привести к проблемам со стабильностью во время выполнения? Все ли ссылки на символ в самой библиотеке исправлены автоматически, или возможно, что какой-то фрагмент кода библиотеки (кроме таких вещей, как dlsym() звонки) попробует ссылаться на старый символ и сегфо?

2 ответа

Решение

Предполагая, что библиотеки были созданы из нескольких исходных файлов, символы, экспортируемые из библиотеки, почти наверняка будут ссылаться на другие места в библиотеке. Таким образом, изменение имен символов приведет к проблемам со связью позже.

Это просто переименование экспортированных символов библиотеки, как это безопасно?

Зависит от "безопасного против чего".

Есть ли у него какие-либо "ошибки" или непредвиденные последствия

Да, смотрите ниже.

что может привести к проблемам со стабильностью во время выполнения?

Нет. Если вам удастся связать конечный двоичный файл (большой IF), то полученный двоичный файл будет работать.

Все ли ссылки на символ в самой библиотеке автоматически исправляются

Да. --prefix-symbols flag изменяет как определения, так и неразрешенные ссылки (как вы увидите на мгновение, это вызовет проблемы).

Если библиотека полностью автономна (не ссылается ни на какие символы, кроме тех, которые она сама определяет), то префикс всех символов будет работать: вновь переименованные неразрешенные ссылки теперь будут вызывать pineapple_foo вместо foo, и эта ссылка будет разрешена во время ссылки на переименованное определение с новым именем, так же, как и желательно.

Проблема возникает, когда целевая библиотека вызывает что-то вне себя (например, что-нибудь из libc). Эти вызовы также будут иметь префикс, так что вы получите неразрешенную ссылку на что-то вроде pineapple_open, или же pineapple_printf,

Вы можете подумать: я просто предоставлю замену где-нибудь еще:

int pineapple_open(const char *filename, int flag, int mode)
{
   return open(filename, flag, mode);
}

Это утомительно, но работает для функций. Где это ломается, с глобальными переменными: errno, h_errno, так далее.

Так как вы упомянули -fPICобратите внимание, что поддержка динамических библиотек зависит от _GLOBAL_OFFSET_TABLE_, который вы не хотите переименовывать либо.

Другие вопросы по тегам