Должен ли 32-битный x86-код быть специально скомпилирован PIC для файлов общей библиотеки?

Компиляция кода в объектный файл должна выполняться не зависящим от положения, если объектный файл предназначен для загрузки в качестве общей библиотеки (.so), поскольку базовый виртуальный адрес, в который загружен файл общих объектов в разные процессы, может быть разным,

Теперь я не сталкивался с ошибками, когда пытался загрузить файл .so скомпилированный и связанный без -fpic GCC на 32-разрядных компьютерах x86, в то время как он не работает на 64-битных компьютерах x86.

Случайные сайты, которые я нашел, говорят, что мне не нужно -fpic на 32-битной основе, потому что код, скомпилированный без -fpic работает по совпадению в соответствии с 32-разрядным ABI X86 также при использовании в независимом от позиции образом. Но я все еще нашел программное обеспечение, которое поставляется с отдельными версиями библиотек в их 32-битных версиях: один для ПОС и один для не-ПОС. Например, компилятор Intel поставляется с libirc.a и libirc_pic.a, последний компилируется для независимого от позиции режима (если вы хотите связать этот файл .a файлом .so).

Интересно, какая точная разница между использованием -fpic и не использованием его для 32-битного кода и почему некоторые пакеты, такие как компилятор Intel, по-прежнему поставляются с отдельными версиями библиотек?

Ответ 1

Это не то, что не-PIC-код работает "по совпадению" на x86 (32-разрядный). Это то, что динамический компоновщик для x86 поддерживает необходимые "текстовые реплики", необходимые для его работы. Это связано с очень высокой стоимостью потребления памяти и времени запуска, поскольку в основном весь сегмент кода должен быть исправлен во время загрузки (и, таким образом, становится нераспространяемой памятью).

Поддерживающие динамические компоновщики утверждают, что разделяемые библиотеки, не связанные с PIC, не могут поддерживаться на x86_64 из-за фундаментальных проблем в архитектуре (немедленные смещения адреса не могут быть больше 32-разрядных), но эту проблему можно легко решить, просто загружая библиотеки в первых 4gb виртуального адресного пространства. Конечно, PIC-код очень недорог на x86_64 (PIC не является производителем-убийцей, как на 32-разрядном x86), поэтому они, вероятно, правы, чтобы сохранить его неподдерживаемым и не позволять дуракам создавать библиотеки, отличные от PIC...

Ответ 2

базовый виртуальный адрес, загруженный файлом общего объекта в разные процессы, может быть различным

Поскольку общие объекты обычно загружаются по их предпочитаемому адресу, они могут работать корректно. Но fPIC - хорошая идея для всего общего кода.

Я считаю, причина, по которой не так часто бывает в двух версиях библиотеки, заключается в том, что многие дистрибутивы используют fPIC как значение по умолчанию для всего кода.