Почему fPIC абсолютно необходим на 64, а не на 32-битных платформах? - PullRequest
25 голосов
/ 27 августа 2011

Я недавно получил:

... перемещение R_X86_64_32 против `локального символа 'нельзя использовать при создании общего объекта; перекомпилировать с -fPIC

ошибка при попытке скомпилировать программу как общую библиотеку.

Теперь решение этого не слишком сложно (перекомпилируйте все зависимости с -fPIC), но после некоторых исследований выясняется, что эта проблема присутствует только на платформах x86-64. На 32-битном языке любой позиционно-зависимый код все еще может быть перемещен динамическим загрузчиком.

Лучший ответ Я мог бы найти:

x86 имеет поддержку для перемещения .text (что происходит, когда у вас есть позиционно-зависимый код). Эта поддержка платная, а именно: страница, содержащая такое перемещение, становится практически не общей, даже если она сидит в общей библиотеке, тем самым портя саму концепцию общего ЛИЭС. Поэтому мы решили запретить это на amd64 (плюс он создает проблемы, если значение требует более 32 бит, потому что все .text перемещает только иметь размер 'word32')

Но я не считаю это вполне адекватным. Если в этом случае перемещение портит концепцию разделяемых библиотек, почему это можно сделать на 32-битных платформах? Кроме того, если были внесены изменения в формат ELF для поддержки 64-битного формата, то почему не все поля были увеличены в размере для размещения?

Это может быть второстепенным моментом, но оно мотивируется тем фактом, что а) рассматриваемый код является научным кодом, и было бы неплохо не испытывать снижения производительности и б) эту информацию было невозможно найди на первом месте!

[Редактировать: «Ответ»

@ awoodlands ответ , вероятно, лучший «буквальный ответ», @servn добавил некоторую полезную информацию.

В поиске, чтобы найти больше о различных типах перемещений, я нашел это и, в конечном итоге, x86_64 ABI Reference (см. Стр. 68) ]

Ответы [ 3 ]

11 голосов
/ 28 августа 2011

Насколько я понимаю, проблема в том, что в x86-64 появился новый, более быстрый способ ссылки на данные относительно указателя инструкций, которого не было в x86-32.

Эта статья содержит хороший углубленный анализ и дает следующее резюме:

Возможность x86-64 использовать относительное смещение указателя инструкции к адресам данных неплохая оптимизация, но в shared-библиотеке Ситуационные предположения об относительном расположении данных неверны и не может быть использован. В этом случае доступ к глобальным данным (т.е. все, что может измениться на вас) должно пройти через слой абстракции, а именно глобальная таблица смещения.

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

7 голосов
/ 28 августа 2011

Но я не считаю это вполне адекватным.Если это тот случай, когда перемещения портят концепцию разделяемых библиотек, почему это можно сделать на 32-битных платформах?

Это может быть сделано, но это не особенно эффективно ... вычисление перемещенийимеет затраты времени выполнения, перемещенные исполняемые файлы занимают дополнительную память, а механизм вносит большую сложность в исполняемый загрузчик.Кроме того, дистрибутивы Linux действительно хотят, чтобы весь код компилировался с -fPIC, потому что изменение базового адреса исполняемого файла - это стратегия смягчения, которая затрудняет написание эксплойтов для уязвимостей безопасности.

Стоит также отметить, что -fPIC, как правило, не приводит к значительным потерям производительности, особенно если вы используете -fvisibility = скрытый или эквивалентный.

почему не все поля были увеличены в размерах?

«Поле», о котором идет речь, является непосредственным полем режимов адресации x86-64, которое не находится под контролем разработчиков ELF.

0 голосов
/ 08 апреля 2013

Вы можете использовать опцию -mcmodel = large для создания общих библиотек без -fpic на x86_64

Ссылка: http://eli.thegreenplace.net/2012/01/03/understanding-the-x64-code-models/

...