Установите флаг PIC для компиляции asm

#assembly #gcc #shared-libraries #x86-64 #dynamic-linking

#сборка #gcc #разделяемые библиотеки #x86-64 #динамическое связывание

Вопрос:

Как установить флаг PIC для компиляции asm ассемблером в сборке GCC?

   gcc -shared -o u.o -fPIC u.asm -Wa .....
  

произойдет сбой, какое правильное решение?
Редактировать
на самом деле, я на самом деле не имею никакого отношения к этому делу / знаниям. Мне просто нужно создать свой собственный libffmpeg.so как это https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu только для статической двоичной инструкции сборки.
Итак, попробовал add -fPIC для каждого на нем и суммировал их все, выполнив
gcc -shared -o libffmpeg.so -Wl,--whole-archive lib/lib*.a -Wl,--no-whole-archive
слава Богу, все прошло гладко, за исключением такой ошибки в этом случае

 /usr/bin/ld: lib/libx265.a(cpu-a.asm.o): relocation R_X86_64_PC32 against symbol x265_intel_cpu_indicator_init' can not be used when making a shared object; recompile with -fPIC    
/usr/bin/ld: lib/libx265.a(pixel-util8.asm.o): relocation R_X86_64_PC32 against symbol x265_entropyStateBits' can not be used when making a shared object; recompile with -fPIC
  

Итак, моя последняя капля, просто угадайте, что ближе всего к реальной проблеме как таковой выше

Комментарии:

1. Что бы вы ожидали от этого флага? Либо вы написали asm независимым от позиции, либо нет, и если вы этого не сделали, ассемблер ничего не сможет сделать, чтобы это исправить.

2. R_X86_64_PC32 Ошибка предполагает, что вы генерируете 64-разрядный код, и компоновщик понимает, что у вас есть инструкция, которая использует абсолютный адрес, которого может быть недостаточно для представления в виде 32-разрядного абсолютного адреса. GCC считает, что ваш код, возможно, был сгенерирован цепочкой инструментов GCC, и предлагает возможность повторной компиляции с -fpic помощью или -fPIC . Это не относится к сборке, созданной вручную. Вы должны сделать положение кода сборки независимым.

3. Способ получить такое перемещение — это если у вас есть ярлык like message и попытка сделать mov $message, %rax . Вы могли бы сделать эту позицию независимой и работать с 64-разрядным общим объектом, используя последовательную адресацию с чем-то вроде lea message(%rip), %rax

Ответ №1:

Сообщение «перекомпилировать с -fPIC помощью» в этом случае вводит в заблуждение. В сообщении предполагается, что нарушающий объектный файл был скомпилирован из исходного кода C / C , и в этом случае -fPIC компилятор сгенерирует код ассемблера, не зависящий от позиции. Но это всего лишь предположение, поскольку компоновщик на самом деле не знает, как был создан файл, и в этом случае файл был собран из рукописной сборки. -fPIC не могу с этим помочь; это флаг компилятора, и этот код никогда не компилируется. Код сборки должен быть переписан вручную, чтобы быть независимым от позиции, т. Е. Нигде Не использовать абсолютные адреса.

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

Также возможно, что кто-то уже написал независимую от позиции версию этого файла, или, возможно, есть #ifdef варианты выбора независимого от позиции кода, который был написан. Я сам не просматривал файл. Вероятно, вам следует провести некоторое исследование, чтобы узнать, существует ли существующая поддержка компиляции этой библиотеки в качестве разделяемой библиотеки; возможно, она есть, и вы просто делаете это неправильно.

Ответ №2:

произойдет сбой

Какое точное сообщение об ошибке?

Если я попробую вашу командную строку, моя версия GCC жалуется на расширение .asm , потому что она не знает, какой это тип файла. Файлы языка ассемблера в GCC обычно имеют имена .s (в нижнем регистре; нет .asm );

или .S (в верхнем регистре), если код ассемблера должен быть предварительно обработан с использованием препроцессора C (поэтому #define #include #ifdef в коде ассемблера могут использоваться инструкции препроцессора C, такие как , , #if и т.д.).

Я также предполагаю, что ваша командная строка содержит « -c «; в противном случае командная строка попытается скомпилировать и связать, а не только компилировать.

Как установить флаг PIC для компиляции asm ассемблером в сборке GCC?

Как уже писал Нейт Элдридж, это невозможно:

-fPIC сообщает компилятору, как код C (или C , Fortran …) преобразуется в код ассемблера.

Если у вас уже есть ассемблерный код, он либо зависит от позиции, либо не зависит от позиции.

Итак, правильным вопросом было бы: «Как написать ассемблерный код для x86-32 (или любой другой архитектуры) таким образом, чтобы он не зависел от положения?»