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