2017-01-25 8 views
5

Я пытаюсь следить за 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

+1

Ваш код действительно работает для меня (в другом дистрибутиве). Ваша проблема, похоже, связана с типом перемещения 'hello.o'. Я бы предложил добавить директиву 'default rel' в начало' hello.asm' и посмотреть, работает ли это или предоставляет другую ошибку. Вы намеренно пытаетесь использовать перемещение R_X86_64_32? –

+0

@JimD. Большое спасибо за Вашу помощь. Я опубликовал свое сообщение, чтобы указать новое сообщение об ошибке. –

+2

Что произойдет, если вы статически статируете с помощью 'gcc -static hello.o' –

ответ

6

GCC в Debian Stretch defaults to building position independent executables, чтобы создать исполняемый файл связан с определенным адресом, как традиционно проходят -no-pie - GCC.

В качестве альтернативы укажите правильный тип перемещения, я не знаю, как это сделать в ярости.

+0

Привет Тимоти, в то время как 'gcc -static hello.o' успешно, ссылка на' gcc -fno-pie hello.o' не работает на моей машине 'debian stretch'. Что мне не хватает? –

+0

При компоновке компиляции '-fno-pie' должно быть' -no-pie'. –

+0

Спасибо, Тимоти, «gcc -статический привет.о» и «gcc -no-pie hello.o' работают отлично! –