Разница в позиционно-независимом коде: x86 против x86-64 - PullRequest
24 голосов
/ 30 июня 2010

Недавно я создавал определенную разделяемую библиотеку (ELF), ориентированную на архитектуру x86-64, например:

g++ -o binary.so -shared --no-undefined ... -lfoo -lbar

Сбой из-за следующей ошибки:

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

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

Но это прекрасно работаетна x86 с точно такими же аргументами сборки.Итак, вопрос в том, как перемещение на x86 отличается от x86-64 и почему мне не нужно компилировать с -fPIC на первом?

Ответы [ 3 ]

17 голосов
/ 02 августа 2010

Я нашел хорошее и подробное объяснение , которое сводится к:

  1. x86-64 использует IP-относительное смещение для загрузки глобальных данных, x86-32 не может, поэтому оно разыменовывает глобальное смещение.
  2. IP-относительное смещение не работает для разделяемых библиотек, поскольку глобальные символы могут быть переопределены, поэтому x86-64 не работает, если не создан с помощью PIC.
  3. Если x86-64 построен с PIC, разыменование относительного смещения IP теперь дает указатель на запись GOT , которая затем разыменовывается.
  4. x86-32, однако, уже использует разыменование глобального смещения, поэтому оно напрямую преобразуется в запись GOT.
4 голосов
/ 30 июня 2010

Это проблема модели кода. По умолчанию статический код создается при условии, что вся программа останется в нижней части 2G адресного пространства памяти. Код для разделяемых библиотек должен быть скомпилирован для другой модели памяти, либо PIC, либо с -mcmodel = large, который будет компилироваться без такого предположения.

Обратите внимание, что -mcmodel = large не реализован в более старой версии gcc (это в 4.4, это не в 4.2, я не знаю для 4.3). .

0 голосов
/ 30 июня 2010

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

...