Должен ли 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
как значение по умолчанию для всего кода.