#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 (или любой другой архитектуры) таким образом, чтобы он не зависел от положения?»