2017-12-10 1 views
1

Ich bin konfrontiert Verknüpfungsproblem. Ich werde es zeigen:Objekt Verknüpfung Auftrag Problem

A. C:

extern void b(void); 
int main() { 
    a(); 
    return 0; 
} 

void a() { 
    b(); 
} 

B. S:

.extern a 
b: 
    jmp a 

Egal, ob ich

gcc a.o b.o -o c 

oder

gcc b.o a.o -o c 
verknüpfen werden

Ich werde ungelöste Symbole bekommen. Wie verknüpfe ich diese Dateien? Ich kann sie nicht zusammenführen. Beispiel kann unsinnig sein, aber das veranschaulicht Punkt, was versuche ich zu archivieren.

+0

Ein paar Fragen: (A) Was Asm ist das Targeting? nichts von Yasm, Nasm oder Gas mag es. (b) Sie müssen 'void a()' in 'a.c' weiterleiten oder es wird nicht kompiliert. (c) Ändern von 'b()' in eine C-Funktion und versuchen Sie Ihren Link-Befehl funktioniert gut. Soweit ich weiß, ist das Verhalten der Linker für statische Bibliotheken das einzige Mal, dass Sie die Art von Abhängigkeiten erhalten, über die Sie sprechen. Können Sie die Frage aktualisieren, um ein funktionierendes Beispiel für das Problem zu geben? – lockcmpxchg8b

+0

Es ist Gnu als. Ich schreibe Betriebssystem, das groß gewachsen ist, und ich dachte über ein Beispiel wie folgt. –

+0

sry, mein Problem mit Gas war, dass meine erste Untersuchung auf Mingw war. Zu einem richtigen Linux wechseln lassen Sie mich Ihr Beispiel gut zusammenbauen. Lösung unten. TL; DR: Das Problem ist, dass "b" nicht global ist. – lockcmpxchg8b

Antwort

3

Erste Untersuchung:

A. C

extern void b(void); 
void a(void); 

int main() { 
    a(); 
    return 0; 
} 

void a() { 
    b(); 
} 

B. S

.extern a 
b: 
    jmp a 

b.c

void a(void); 

void b(void) 
{ 
    a(); 
} 

Ausgabe

$ gcc -c a.c 
$ gcc -c b.c -o b_gcc.o 
$ as b.S -o b_as.o 
$ gcc a.o b_gcc.o -o test_gcc 
$ gcc a.o b_as.o -o test_as 
a.o: In function `a': 
a.c:(.text+0x15): undefined reference to `b' 
collect2: error: ld returned 1 exit status 

Also, was soll das? Warum ist es in Ordnung mit GCC, aber nicht mit GAS?

$ objdump -t b_gcc.o > syms_gcc 
$ objdump -t b_as.o > syms_as 
$ diff syms_gcc syms_as 
2c2 
< b_gcc.o:  file format elf64-x86-64 
--- 
> b_as.o:  file format elf64-x86-64 
5d4 
< 0000000000000000 l df *ABS* 0000000000000000 b.c 
9,12c8 
< 0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack 
< 0000000000000000 l d .eh_frame 0000000000000000 .eh_frame 
< 0000000000000000 l d .comment 0000000000000000 .comment 
< 0000000000000000 g  F .text 000000000000000b b 
--- 
> 0000000000000000 l  .text 0000000000000000 b 

Okay, so macht gccb ein globales Symbol. Lets versuchen .global b in b.S:

$ as b.S -o b_as2.o 
$ gcc a.o b_as2.o 
$ 

Erfolg. So gcc/ldwird Multi-Pass-Symbol-Auflösung für alles, was nicht in einer statischen Bibliothek ist. Aber es nur sucht nach globalen Symbolen. Hier ist das letzte b.S:

.extern a 
.global b 
b: 
    jmp a 
+0

Das Problem mit der Verknüpfung meines Betriebssystems wurde gelöst, danke! –

+0

Haben Sie auch keine intellische Syntax anstelle von AT & T verwendet? –