Как ограничить доступ к символам в общем объекте? - PullRequest
7 голосов
/ 01 июня 2011

У меня есть плагин в форме разделяемой библиотеки (bar.so), который связан с более крупной программой (foo).И foo, и bar.so зависят от одной и той же сторонней библиотеки (baz), но им необходимо полностью отделить свои реализации baz.Поэтому, когда я связываю foo (используя предоставленные объектные файлы и архивы), мне нужно, чтобы он игнорировал любое использование baz в bar.so и наоборот.

Прямо сейчас, если я связываю foo с --trace-symbol=baz_fun, где baz_funодин из оскорбительных символов я получаю следующий вывод:

bar.so: definition of baz_fun
foo/src.a(baz.o): reference to baz_fun

Я считаю, что это говорит мне, что foo ссылается на baz_fun из bar.so (и выполнение foo подтверждает это).

Решения, которые я попробовал:

  • Использование objcopy для «локализации» символов, представляющих интерес: objcopy --localize-symbols=local.syms bar.so, где local.syms содержит все символы, представляющие интерес.Я думаю, что я могу быть просто сбит с толку здесь и, возможно, «местный» не означает, что я думаю, что это означает.Независимо от того, я получаю такой же вывод по ссылке выше.Я должен отметить, что если я запускаю инструмент nm на bar.so до использования objcopy, то все рассматриваемые символы имеют флаг T (верхний регистр обозначает глобальный), а после objcopy они имеют t указывает на то, что они сейчас местные.Похоже, что я правильно использую objcopy.
  • Компиляция с -fvisibility=hidden, однако из-за некоторых других ограничений мне нужно использовать GCC 3.3, который не поддерживает эту функцию.Я мог бы перейти на более новую версию GCC, но хотел бы получить подтверждение того, что компиляция с этим флагом поможет мне, прежде чем идти по этому пути.

Другие примечания:

  • У меня нет доступа к исходному коду foo или baz
  • Я бы предпочел хранить все мои плагины в одном общем объекте (bar.so).baz на самом деле является библиотекой лицензирования, поэтому я не хочу, чтобы она была отделена

1 Ответ

4 голосов
/ 01 июня 2011

Используйте dlopen для загрузки вашего плагина с флагом RTLD_DEEPBIND.

(редактировать)

Обратите внимание, что RTLD_DEEPBIND зависит от Linux и требует glibc 2.3.4 или новее.

...