предотвратить вставку функции в библиотеку, которая связана с библиотекой, которая выполняет вставку - PullRequest
3 голосов
/ 04 февраля 2020

Ну, я не смог найти очень хорошую короткую фразу для названия моего вопроса, но вот что я имею в виду:

У меня есть библиотека, которая вставляет некоторые системные вызовы, такие как open(2). Я использую этот метод для вставки. Я добавляю его к DYLD_INSERT_LIBRARIES, чтобы достичь своей цели.

Библиотека, которая содержит код вставки: a.dylib.

Мне нужно связать библиотеку b.dylib с a.dylib потому что он содержит некоторые функции, которые нужны a.dylib.

Проблема в том, что a.dylib также вставляет функции в b.dylib, которые мне не нужны.

Я не эксперт в ссылки. Есть ли способ предотвратить такое поведение и в чем причина этого?

ОБНОВЛЕНИЕ:

Вот как создается b.dylib:

clang -dynamiclib -fPIC -Wextra -Wall -pedantic -Wl,-single_module <object files> -o b.dylib -install_name <path>

Это как строится a.dylib:

clang -dynamiclib -fPIC -Wextra -Wall -pedantic -Wl,-single_module <object files> -o a.dylib -install_name <path> b.dylib

Только a.dylib добавляется в конец DYLD_INSERT_LIBRARIES.

1 Ответ

1 голос
/ 13 февраля 2020

Вы говорите, что a.dylib зависит от b.dylib, но b.dylib не зависит от a.dylib и что вы не хотите, чтобы вызовы в b.dylib когда-либо вставлялись. Вы привели open в качестве примера вставленной функции.

Я привел следующий пример: a.dylib необходимо вызвать processFile, который определен в b.dylib, и он открывает файлы. Вы не хотите, чтобы вызов open в b.dylib был вставлен когда-либо (независимо от того, загружен a.dylib или нет).

Единственный способ, которым я знаю, чтобы осуществить это, это для processFile динамически загружать библиотеку C вместо того, чтобы ld делал это автоматически.

При таком подходе есть две проблемы. Во-первых, каждая функция, которая должна вызывать open, будет нуждаться в одном дополнительном операторе if, чтобы выполнить код для разрешения символа.

Во-вторых, вам необходимо заранее знать имя файла C библиотека для загрузки. И если есть проблема с разрешением символа, то вам придется иметь дело с ситуацией, с которой не приходится сталкиваться большинству программ; по крайней мере, позже.

Код будет выглядеть примерно так:

void processFile (char * filename) {
    FILE *fp;
    // c_open can have file scope if thread safety isn't needed
    static int (*c_open)() = NULL;

    if (c_open == NULL) {
        // factor this if more than one function needs open
        void *dlh = dlopen(C_LIBRARY_FILENAME, RTLD_LAZY);
        if (dlh == NULL) {
           perror("cannot load C library");
           exit(1);
        }
        c_open = dlsym(dlh, "open");
        if (c_open == NULL) {
           perror("cannot resolve open in the C library");
           exit(1);
        }
    }
    c_open(filename, O_RDONLY);
    ...
}

ОБНОВЛЕНИЕ

Если вы не укажете полный путь к библиотеке C, dlopen может открыть неожиданный файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...