Реализовать отсутствующий символ в общей библиотеке

У меня есть сторонняя библиотека (скажем, libfoobar.so), которая зависит от другой сторонней библиотеки под названием libutils.so. У меня есть только старая версия libutils.so, в его старой версии отсутствует символ (экспортированная функция), который существует только в новой версии.

Я могу закодировать функцию в новой общей библиотеке (скажем, libwrapper.so):

extern "C" int missing_function() {
    return 123;
}

И сейчас?? как можно "сказать" libfoobar.so использовать эту функцию, уже пробовал:

  • загрузить libwrapper.so перед libfoobar.so.
  • используя инструмент patchelf с patchelf --add-needed libwrapper.so libfoobar.so. Но я понимаю dlopen failed: empty/missing DT_HASH in "libfoobar.so" (built with --hash-style=gnu?)

Я не могу использовать "новую версию" из соображений совместимости. Есть какое-нибудь решение?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
377
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хорошо, я решил проблему странным образом, создав «прокси»-библиотеку, которая обертывает используемые функции.

Шаг, следующий за предыдущим примером:

  1. открыть libfoobar.so в шестнадцатеричном редакторе и исправить (изменить) ссылку на новую общую библиотеку, заменив строку libutils.so на libutilx.so (соблюдайте количество символов)
  2. также измените SONAME, в этом примере измените LIBSUTILS на LIBUTILX
  3. закодируйте оболочку и скомпилируйте как libutilx.so. Пример кода C ниже
  4. положить в ту же папку с libfoobar.so и ГОТОВО.
#include <dlfcn.h>

void *lib = dlopen("libutils.so", RTLD_LAZY);// original lib


// delegates
void *(*ORIGmalloc)(size_t size);
int (*ORIGpthread_setspecific)(pthread_key_t key, const void *value);


// functions
extern "C" void *malloc(size_t size) {
    return (*ORIGmalloc)(size_t);
}
extern "C" int pthread_setspecific(pthread_key_t key, const void *value) {
    return (*ORIGpthread_setspecific)(pthread_key_t, value);
}

// implements missing functions in libutils.so required by libfoobar.so
extern "C" const char *get_greeting_string() {
   return "Hello from libutilx.so !!";
}

extern "C" int some_number() {
   return 12345;
}


// assigns (just an example, you must check for errors)
// with the attribute "constructor" this function is called after the lib is opened
void  __attribute__((constructor)) assign_delegates() {
    *(void **) (&ORIGmalloc) = dlsym(lib, "malloc");
    *(void **) (&ORIGpthread_setspecific) = dlsym(lib, "pthread_setspecific");
}

Чтобы узнать, какие функции импортируются, используйте утилиту командной строки objdump. Пример objdump -T libfoobar.so вывод будет:

00000000      DF *UND*  00000000  LIBUTILS        pthread_setspecific
00000000      DF *UND*  00000000  LIBUTILS        malloc
00000000      DO *UND*  00000000  LIBUTILS        __sF

ваше здоровье

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