2016-07-04 9 views
1

Ich versuche, eine gemeinsame Bibliothek auf x86-64 erstellen, aber fehlgeschlagen. Das Problem läuft darauf hinaus, den folgenden Code nach unten (bitte nicht dagegen, dass es nicht viel Sinn macht):Generieren positionsunabhängigen Code mit Gas (-fPIC)

.section .data 
newline: 
    .ascii "\n" 

.section .text 
.globl write_newline 
    .type write_newline, @function 
write_newline: 
    mov $newline, %rax  
    ret 

Gebäude wie folgt:

as minimal.s -o minimal.o 
ld -shared minimal.o -o libmin.so 

führt zu folgendem Fehler:

ld: minimal.o: relocation R_X86_64_32 against `.data' can not be used when making a shared object; recompile with -fPIC 
minimal.o: error adding symbols: Bad value 

Aber Gas nicht weiß Option -fPIC, so kann ich mit ihm nicht neu kompilieren:

as -fPIC minimal.s -o minimal.o 
as: unrecognized option '-PIC' 

Was kann stattdessen getan werden?

+0

-fpic wäre eine Option für einen Compiler, wie gcc. Wenn du asm schreibst, müsstest du das Bild selbst schreiben. –

+0

@MarcB Wie könnte das gemacht werden? Wo soll ich anfangen? – ead

+2

@ead Für Anfänger, schreiben Sie 'mov newline @ GOTPCREL (% rip),% rax '. Überprüfen Sie, welche Ausgabe Ihr C-Compiler generiert, um eine Idee für das Schreiben von PIC zu erhalten. – fuz

Antwort

2

Wie Marc B in den Kommentaren sagte, geht die Fehlermeldung davon aus, dass Sie GCC oder einen anderen Compiler verwendeten. Da Sie den Code in Assembly geschrieben haben, liegt es in Ihrer Verantwortung sicherzustellen, dass Ihr Code positionsunabhängig ist.

Auf x86-64 Ziele können Sie diesen Fehler beheben RIP relativ Adressierung:

 .section .data 
newline: 
    .ascii "\n" 

.section .text 
.globl write_newline 
    .type write_newline, @function 
write_newline: 
    lea newline(%rip), %rax 
    ret 

Beachten Sie, dass Sie nicht über die GOT hier verwenden müssen, weil newline ein lokales Symbol ist. Wenn es global wäre und Sie möchten, dass der Verweis auf newline in Ihrem Code auf eine andere Definition von newline in einer anderen Laufzeitkomponente verweist, müssen Sie eine @GOTPCREL-Verschiebung verwenden. Das würde dem dynamischen Linker ermöglichen, den Eintrag im GOT so zu ändern, dass er auf eine andere Definition von newline zeigt.

+0

Danke, das hat funktioniert! Aber warum gibt es keine Notwendigkeit für @ GOTPCREL wie in newline @ GOTPCREL (% rip) wie gcc tun würde und @ FUZxxl hat vorgeschlagen? – ead

+0

Nun, GCC würde kein @GOTPCREL für den entsprechenden C-Code erzeugen. Es würde eine LEA-Anweisung und relative RIP-Adressierung verwenden, da "newline" nicht global ist. Wenn es global wäre, dann bedeutet dynamisches Verknüpfen, dass irgendeine andere globale 'Newline'-Definition in einem anderen Modul Vorrang hat, so dass es über das GOT darauf zugreifen wird. –

+0

Sie haben Recht, mein Test-C-Code hat eine globale Variable, aber Assembler-Code eine lokale Variable. Freut mich, dich gefragt zu haben. Vielen Dank! – ead