Таблица технологической привязки и глобальная таблица смещений

Я читаю эту статью о PLT (Таблица технологической привязки) и GOT (глобальная таблица смещений). Хотя цель PLT мне понятна, я все еще смущен GOT. Из статьи я понял, что GOT необходим только для переменных, объявленных как extern в общей библиотеке. Для глобальных переменных, объявленных как static в коде общей библиотеки, это не требуется.

Я правильно понимаю, или я полностью не понимаю смысла.

Ответ 1

Возможно, ваше замешательство связано со значением extern. Поскольку привязка по умолчанию extern, любая переменная, объявленная вне области внешней функции без ключевого слова static, равна extern.

Причина, по которой GOT является необходимой, заключается в том, что адрес переменных, к которым обращается код общей библиотеки, неизвестен на момент генерации общей библиотеки. Это зависит либо от адреса загрузки, в который загружается библиотека (если определение находится в самой библиотеке), либо для стороннего кода, в котором определена переменная (если определение находится в другом месте). Поэтому вместо того, чтобы помещать адрес inline в код, компилятор генерирует код для чтения общей библиотеки GOT, а затем загружает адрес из GOT во время выполнения.

Если известно, что переменная определена в одной и той же общей библиотеке (либо из-за того, что она используется static, либо для атрибута видимости hidden или protected), тогда адрес, относящийся к коду в библиотеке, может быть исправлен в то время, когда генерируется файл общей библиотеки. В этом случае, вместо того, чтобы выполнять поиск через GOT, компилятор просто генерирует код для доступа к переменной с обращением к программному счету. Это дешевле как во время выполнения, так и во время загрузки (поскольку весь процесс поиска и перемещения символа можно пропустить во время загрузки).