Какова цель таблицы привязки процедуры?

Мне любопытно, почему существует таблица связей процедур. Какой цели это служит? Не может ли сборка напрямую вызвать таблицу глобальных смещений? Какое преимущество вызывает вызов PLT по вызову глобальной таблицы смещений?

Весь процесс по-прежнему смущает меня, и я пытаюсь понять динамику и динамическую связь, поэтому любая помощь будет оценена.

Ответ 1

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

Однако, когда PLT абсолютно необходимо, он находится в коде, отличном от PIC, который связан динамически. (Обычно это происходит только в основной программе, а на многих арках код не-PIC даже не разрешен/поддерживается в общих библиотеках.) Когда компилятор генерирует не-PIC-код для вызова функции, он не знает, что фактический адрес назначения будет динамически решен во время выполнения через GOT. Таким образом, он просто генерирует обычную команду вызова. После этого компоновщик отвечает, когда видит перемещение типа вызова для символа, который не разрешен локально и для которого требуется компоновка времени выполнения, для генерации записи PLT, которая загружает адрес из GOT и совершает косвенный переход к нему. Таким образом, исходный код вызова функции не-PIC работает без изменений.