Демонстрация проблемы по ссылке. Дело не в линкере, а ещё в
компиляторе. При задании опций -mpic-register=r10 -msingle-pic-base
-mno-pic-data-is-text-relative -fpic все обращения к данным идут
относительно GOT. Без -mno-pic-data-is-text-relative локальные
(static) данные адресуются относительно PC, а глобальные через GOT.
С -pie всё адресуется через PC. Почему всё через GOT -- непонятно. Мог бы относительно начала GOT адресовать статические символы и через GOT глобальные (там таблица нужна, потому, что они неизвестно знает где могут оказаться из-за связи с другими модулями, а для локальных всё срелоцировать относительно самой GOT можно в момент линковки). Потенциально можно генерировать код в ассемблер и обрабатывать ассемблер скриптом, который выкрутасы вокруг GOT выкинет для локальных символов. Я видел в одном проекте так делали и весьма успешно (для уменьшения объёма кода).
В nuttx патчили код (https://cwiki.apache.org/confluence/display/NUTTX/NxFlat) но для другого (там .text в ОЗУ и data-text = const).
Ну и в целом позиционно-независимый код менее эффективен.
Демонстрация проблемы:
https://godbolt.org/z/YsY7Ej