Я пытаюсь следить за this thread, что, к сожалению, не совсем решает мою проблему. Код, который я пытаюсь запустить следующим образом:X86 64-разрядная сборка Linux 'Hello World' проблема связи
; File hello.asm
section .data
msg: db "Hello World!",0x0a,0
section .text
global main
extern printf
main:
push rbp
mov rbp, rsp
lea rdi, [msg] ; parameter 1 for printf
xor eax, eax ; 0 floating point parameter
call printf
xor eax, eax ; returns 0
pop rbp
ret
Моя система Debian натяжкой:
$ uname -a
Linux <host> 4.8.0-1-amd64 #1 SMP Debian 4.8.7-1 (2016-11-13) x86_64 GNU/Linux
Я использую yasm
ассемблер следующим образом:
$ yasm -f elf64 -g dwarf2 hello.asm
Поскольку мой вход точка в указанном выше источнике равна main
с окончательной командой ret
, я предполагаю, что мне нужно связать с gcc
, а не ld -e main
:
$ gcc -lc hello.o
Однако, я получаю следующее сообщение об ошибке:
/usr/bin/ld: hello.o: relocation R_X86_64_32 against `.data' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
Эта ошибка упоминает что-то о перекомпиляции с -fPIC
, но это выбор за gcc
компилятор, не является допустимым вариантом ассемблера yasm
, Поэтому я не знаю, что делать здесь.
Просто ради тестирования, я попытался связать с ld
:
$ ld -e main -lc hello.o
, который является успешным, но я получаю ту же ошибку, как указано выше в потоке при запуске:
$ ./a.out
bash: ./a.out: No such file or directory # The file *is* there ...
(после ответа на вопрос, я попытался сравнить библиотеку .so
, указанную в двоичном файле ld
с моей системной библиотекой, и оба они являются /lib64/ld-linux-x86-64.so.2
.)
Я также попытался заменить точку входа main
с _start
(забыв вопрос о правильном выходе из программы на данный момент) и связь с ld -lc hello.o
, но я получаю ту же ошибку «Нет такой файл или каталог», как и раньше. Я продолжу играть с этим, но подумал, что и спрошу.
Любое рабочее предложение (с main
или _start
, gcc
или ld
) будет тепло оценили.
EDIT: Как предложено Джимом я добавил default rel
в верхней части hello.asm
и я получаю другое сообщение об ошибке при связывании с GCC (без изменений с ld -e main -lc
)
$ gcc -lc hello.o
/usr/bin/ld: hello.o: relocation R_X86_64_PC32 against symbol `[email protected]@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
EDIT2: Это сообщение относится к отказу на debian stretch
:
Linux: 4.8.0-1-amd64 #1 SMP Debian 4.8.7-1 (2016-11-13) x86_64 GNU/Linux
yasm: 1.3.0
gcc: (Debian 6.2.1-5) 6.2.1 20161124
ld: GNU ld (GNU Binutils for Debian) 2.27.51.20161220
Followi нг на комментарий Джима я просто проверял один и тот же код наdebian jessie
, который работает прекрасно с gcc -lc hello.o
и следующие версии:
Linux: 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) x86_64 GNU/Linux
yasm: 1.2.0
gcc: (Debian 4.9.2-10) 4.9.2
ld: GNU ld (GNU Binutils for Debian) 2.25
EDIT 3: В ожидании официального ответа от Майкла Petch: вопрос решены сgcc -static hello.o
Ваш код действительно работает для меня (в другом дистрибутиве). Ваша проблема, похоже, связана с типом перемещения 'hello.o'. Я бы предложил добавить директиву 'default rel' в начало' hello.asm' и посмотреть, работает ли это или предоставляет другую ошибку. Вы намеренно пытаетесь использовать перемещение R_X86_64_32? –
@JimD. Большое спасибо за Вашу помощь. Я опубликовал свое сообщение, чтобы указать новое сообщение об ошибке. –
Что произойдет, если вы статически статируете с помощью 'gcc -static hello.o' –