2017-01-25 3 views
5

Je tente de suivre sur this thread qui malheureusement ne résout pas tout à fait mon problème. Le code que je suis en train de courir est la suivante:X86 64 bits Assemblage Linux 'Hello World' problème de liaison

; 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 

Mon système est debian extensible:

$ uname -a 
Linux <host> 4.8.0-1-amd64 #1 SMP Debian 4.8.7-1 (2016-11-13) x86_64 GNU/Linux 

J'utilise l'assembleur yasm comme suit:

$ yasm -f elf64 -g dwarf2 hello.asm 

Parce que mon entrée point dans la source ci-dessus est main avec une instruction finale ret, je devine que je dois lier avec gcc plutôt que ld -e main:

$ gcc -lc hello.o 

Cependant, je reçois le message d'erreur suivant:

/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 

Cette erreur mentionne quelque chose recompiler avec -fPIC mais cela est une option de compilateur gcc, pas une option valide de l'assembleur yasm . Donc je ne sais pas quoi faire ici.

juste pour des tests, nous avons tenté de créer un lien avec ld:

$ ld -e main -lc hello.o 

qui réussit, mais j'obtiens la même erreur que mentionné dans le thread ci-dessus lors de l'exécution:

$ ./a.out 
bash: ./a.out: No such file or directory  # The file *is* there ... 

(suite à la réponse du thread, j'ai essayé de comparer la bibliothèque .so mentionnée dans le fichier binaire ld avec la bibliothèque de mon système, et ils sont tous deux /lib64/ld-linux-x86-64.so.2.)

J'ai également essayé de remplacer le point d'entrée main par _start (en oubliant la sortie correcte du programme pour l'instant) et de lier avec ld -lc hello.o mais la même erreur 'Aucun fichier ou répertoire' comme précédemment. Je vais continuer à jouer avec cela, mais je pensais que je demanderais aussi.

Toute suggestion de travail (avec main ou _start, gcc ou ld) serait apprécié chaleureusement.

EDIT: Comme suggéré par Jim j'ai ajouté default rel en haut de hello.asm et j'obtenir un message d'erreur différent lors de la liaison avec gcc (pas de changement avec 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: Cette publication concerne un échec sur 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 

ng sur le commentaire de Jim Je viens de tester le même code surdebian jessiequi fonctionne parfaitement bien avec gcc -lc hello.o et les versions suivantes:

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: En attendant une réponse formelle de Michael Petch: question résolu avecgcc -static hello.o

+1

Votre code fonctionne réellement pour moi (sur une distribution différente). Votre problème semble être lié au type de relocation de 'hello.o'. Je suggère d'ajouter la directive 'default rel' au début de' hello.asm' et de voir si cela fonctionne ou fournit une erreur différente. Essayez-vous délibérément d'utiliser la relocalisation R_X86_64_32? –

+0

@JimD. Merci beaucoup pour votre aide. J'ai modifié mon message pour indiquer un nouveau message d'erreur. –

+2

Que se passe-t-il si vous construisez statiquement avec 'gcc -static hello.o' –

Répondre

6

GCC dans Debian Stretch defaults to building position independent executables, pour générer un exécutable lié à une adresse spécifique comme le passe traditionnel -no-pie à GCC.

Vous pouvez également spécifier le type de relocalisation correct, je ne sais pas comment le faire dans yasm.

+0

Salut Timothy, alors que 'gcc -static hello.o' réussit, la commande de liaison' gcc -fno-pie hello.o' échoue sur ma machine 'debian stretch'. Qu'est-ce que je rate? –

+0

Désolé, cela devrait être '-no-pie' lors de la liaison,' -fno-pie' contrôle la compilation. –

+0

Merci Timothy, à la fois 'gcc -static hello.o' et' gcc -no-pie hello.o' fonctionnent parfaitement! –