Autor Thema: Linken zweier Objekt-Dateien -> undefined reference to ...  (Gelesen 6141 mal)

hrungaaz

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
Servus,

Ich möchte wie bei Teil 2 im Wiki (das letzte Beispiel) eine C-Quelldatei und eine Assembler-Quelldatei kompilieren und linken.
Ich benutze das "normale" MinGW unter Windows.

Folgendermaßen kompiliere, bzw. linke ich das ganze:
gcc main.c -c -o main.o
as fact.S -o fact.o
ld main.o fact.o -o TEST
main.o:main.c:(.text+0xa): undefined reference to `__main'
main.o:main.c:(.text+0x1e): undefined reference to `factorial'
main.o:main.c:(.text+0x36): undefined reference to `printf'
mingw32-make: *** [TEST] Error 1

Kompilieren klappt ja offensichtlich wunderbar, aber beim Linken krachts dann.

Ich weiß nicht warum die drei Funktionen angeblich undefiniert seien, der Quellcode ist ja komplett aus dem Wiki kopiert (ich habe sogar noch die Kommentare drinstehen  8-)).
Oder muss da noch irgendeine (standart) Bibliothek gelinkt werden? Wenn ja - welche?

Könnt ihr mir da weiterhelfen?
Danke schonmal.

mfg rungaaz

[EDIT]

Die Objekte schauen folgendermaßen aus:

fact.o:     file format pe-i386


Disassembly of section .text:

00000000 <factorial>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   8b 45 08                mov    0x8(%ebp),%eax
   6:   09 c0                   or     %eax,%eax
   8:   75 07                   jne    11 <recurse>
   a:   b8 01 00 00 00          mov    $0x1,%eax
   f:   eb 10                   jmp    21 <out>

00000011 <recurse>:
  11:   48                      dec    %eax
  12:   50                      push   %eax
  13:   e8 e8 ff ff ff          call   0 <factorial>
  18:   83 c4 04                add    $0x4,%esp
  1b:   8b 55 08                mov    0x8(%ebp),%edx
  1e:   0f af c2                imul   %edx,%eax

00000021 <out>:
  21:   89 ec                   mov    %ebp,%esp
  23:   5d                      pop    %ebp
  24:   c3                      ret
  25:   90                      nop
  26:   90                      nop
  27:   90                      nop


main.o:     file format pe-i386


Disassembly of section .text:

00000000 <_main>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 e4 f0                and    $0xfffffff0,%esp
   6:   83 ec 20                sub    $0x20,%esp
   9:   e8 00 00 00 00          call   e <_main+0xe>
   e:   c7 44 24 1c 05 00 00    movl   $0x5,0x1c(%esp)
  15:   00
  16:   8b 44 24 1c             mov    0x1c(%esp),%eax
  1a:   89 04 24                mov    %eax,(%esp)
  1d:   e8 00 00 00 00          call   22 <_main+0x22>
  22:   89 44 24 08             mov    %eax,0x8(%esp)
  26:   8b 44 24 1c             mov    0x1c(%esp),%eax
  2a:   89 44 24 04             mov    %eax,0x4(%esp)
  2e:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
  35:   e8 00 00 00 00          call   3a <_main+0x3a>
  3a:   b8 00 00 00 00          mov    $0x0,%eax
  3f:   c9                      leave
  40:   c3                      ret
  41:   90                      nop
  42:   90                      nop
  43:   90                      nop
« Letzte Änderung: 28. September 2010, 14:44 von hrungaaz »

XanClic

  • Beiträge: 261
    • Profil anzeigen
    • github
Gespeichert
« Antwort #1 am: 28. September 2010, 15:35 »
Bei alten gcc-Versionen muss man -fno-leading-underscore als Parameter angeben, das dürfte das factorial- und evtl. das printf-Problem beheben, ob es gegen __main hilft, weiß ich nicht.

hrungaaz

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 28. September 2010, 16:24 »
Danke für die Antwort, aber das funktioniert leider auch nicht:

ld main.o fact.o -o TEST -fno-leading-underscore -shared
Cannot export factorial: symbol not defined
main.o:main.c:(.text+0xa): undefined reference to `__main'
main.o:main.c:(.text+0x1e): undefined reference to `factorial'
main.o:main.c:(.text+0x36): undefined reference to `printf'
mingw32-make: *** [TEST] Error 1

Nachdem mir ld folgendes mitgeteilt hat: ld: -f may not be used without -shared
musste ich den genannten Parameter noch dazunehmen, hilft aber auch nicht mehr...

[EDIT]
Warum findet der Linker die Funktionen nicht? Sie sind ja immerhin in den Objekt-Dateien enthalten...
« Letzte Änderung: 28. September 2010, 16:31 von hrungaaz »

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 28. September 2010, 16:40 »
Benenne die Funktionen mal mit Unterstrich vorne dran.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 28. September 2010, 16:51 »
Wenn dann musst du -fno-leading-underscore dem gcc übergeben. Aber das ist für Windows-Anwendungen nicht korrekt, weil dann die Library-Funktionen nicht mehr gefunden werden. Stattdessen musst du im Assembler-Code _factorial statt factorial schreiben. Die anderen beiden Fehler entstehen, weil ld standardmäßig nicht die nötigen Bibliotheken mitlinkt. Wenn du einfach gcc statt ld verwendest, klappt auch das.
Dieser Text wird unter jedem Beitrag angezeigt.

hrungaaz

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 28. September 2010, 20:57 »
Danke, die main- und die printf-Funktionen werden nicht mehr bemängelt, wenn ich mit dem gcc linke.
Aber _factorial (auch mit Unterstrich am Anfang) will auch gcc nicht kennen...

BTW: Welche Bibliotheken werden benötigt, um das ganze mit ld zu linken? libc.a gibt's unter Windows bzw. MinGW nicht, soviel ich gesehen habe.
Und gcc ruft doch zum Linken auch nur den ld auf, somit wäre dann doch wieder alles beim Alten, oder gibt der dann noch die nötigen Libs zum linken per Parameter mit?

[EDIT]

Die Objekt-Datei mit -S und -r gedumpt:
main.o:     file format pe-i386


Disassembly of section .text:

00000000 <_main>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 e4 f0                and    $0xfffffff0,%esp
   6:   83 ec 20                sub    $0x20,%esp
   9:   e8 00 00 00 00          call   e <_main+0xe>
                        a: DISP32       ___main
   e:   c7 44 24 1c 05 00 00    movl   $0x5,0x1c(%esp)
  15:   00
  16:   8b 44 24 1c             mov    0x1c(%esp),%eax
  1a:   89 04 24                mov    %eax,(%esp)
  1d:   e8 00 00 00 00          call   22 <_main+0x22>
                        1e: DISP32      __factorial
  22:   89 44 24 08             mov    %eax,0x8(%esp)
  26:   8b 44 24 1c             mov    0x1c(%esp),%eax
  2a:   89 44 24 04             mov    %eax,0x4(%esp)
  2e:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
                        31: dir32       .rdata
  35:   e8 00 00 00 00          call   3a <_main+0x3a>
                        36: DISP32      _printf
  3a:   b8 00 00 00 00          mov    $0x0,%eax
  3f:   c9                      leave
  40:   c3                      ret
  41:   90                      nop
  42:   90                      nop
  43:   90                      nop

main hat 3 Unterstriche, _factorial einen zusätzlichen und printf auch einen...
« Letzte Änderung: 29. September 2010, 12:33 von hrungaaz »

hrungaaz

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 29. September 2010, 13:59 »
Mein Gott, bin ich dumm.
Sorry aber ich hätte den Post von PorkChicken wohl genauer lesen sollen: "[...]Stattdessen musst du im Assembler-Code[...]". Ich hab natürlich auch im C-Code den Unterstrich angefügt...
Jedenfalls funktioniert es jetzt Prima.
Meine einzige Frage ist nur, welche Bibliotheken ich linken muss, um auch mit ld linken zu können?

Danke nochmal für die Hilfen und die Erklärungen.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 29. September 2010, 14:25 »
Hi,

gcc scheint zum Linken collect2 zu verwenden. Der macht sein Ding und ruft dann wiederrum ld auf. Also wenn du weiterhin gcc verwendest, entgehen dir keine Features.

Um deine Frage zu beantworten: Die Parameter, die gcc an collect2 übergibt, bekommst du raus, indem du gcc beim Linken mit dem Parameter -v aufrufst. Bei mir ist das ein ganzer Schwung an Bibliotheken und zusätzlicher Objektdateien. Ich weiß nicht, ob man für ein größeres Projekt damit rumexperimentieren sollte.
Dieser Text wird unter jedem Beitrag angezeigt.

hrungaaz

  • Beiträge: 33
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 29. September 2010, 14:48 »
Wow, Danke!
Werde ich mir auf jeden Fall anschauen, ist nämlich zimlich interessant, was da so alles gelinkt werden muss.

Nochmal Danke!

 

Einloggen