Как внешние символы разделяемой библиотеки разрешаются в основной программе? - PullRequest
0 голосов
/ 20 февраля 2019

Я много читал о семантике связывания во время загрузки разделяемых библиотек, и мне трудно понять, как основная программа может ссылаться на функции, определенные в разделяемых библиотеках?Например, скажем, у меня есть этот код

myShared.sh

int get(){
   return 0;
}

main.c

  extern int get();
  int main(){
    int a = get();
  }

Я понимаю, что общие библиотеки не могут делать никаких утверждений огде они будут размещены, они должны использовать GOT и PLT, чтобы делать ссылки на свои собственные функции и глобальные данные.Но как фактическая программа, использующая указанные библиотеки, узнает, куда будут загружены функции, чтобы она могла ссылаться на них?Очевидно, что компоновщик понятия не имеет, поскольку связывание таких библиотек происходит только во время загрузки.Таким образом, я могу думать только о двух способах, которые позволили бы ссылаться на такие внешние функции.

  1. Компоновщик просто помещает некоторые заполнители, где вызывается get (в приведенном выше примере), и затем добавляет некоторые метаданные, необходимые загрузчику, чтобы затем прийти и заменить местоДержатель с фактическим адресом функции (например, как совместно используемые библиотеки использовали перераспределение времени загрузки перед PIC) Но это вызвало заметные накладные расходы и было самой мотивацией (я думаю) для введения PIC в первую очередь

  2. Основная программа также имеет свои собственные GOT и PLT, и загрузчик должен будет также заполнить GOT основной программы вместе с GOT общей библиотеки (либо все сразу во время загрузки в случае глобальных переменных, либоленивым образом с использованием PLT для функций) Но это звучит как серьезное дублирование усилий.

Итак, какой из этих двух, если таковые имеется, является методом, используемым для разрешения общих библиотек'внешние символы?

1 Ответ

0 голосов
/ 20 февраля 2019

Разрешение символов в основной программе мало чем отличается от разрешения в разделяемых библиотеках и достигается с помощью таблиц GOT и PLT основной программы.Вы правы, что это влечет за собой определенное количество дублирования между статическими (ld) и динамическими (ld.so) компоновщиками и замедляет запуск программы, но, с другой стороны, обеспечивает повышенную гибкость во время выполнения (например, вставка символов через LD_PRELOAD),

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