Autor Thema: lib in nasm / undefined reference  (Gelesen 4701 mal)

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« am: 24. March 2010, 13:41 »
ich habe in nasm eine Bibliothek erstellt. Wenn ich aber Funktionen aus dieser lib nutzen möchte findet mein Linker diese nicht:

Header der lib
// ...
extern "C" int OpenPipe(PIPE *pipe, BYTE port, bool write, pipesig signal);
// ...

Code der lib
%macro APICALL 2
[global %1 %+ :function]
%1 %+ :
    push ebp
    mov  ebp, esp

    mov  eax, %2
    mov  ebx, ebp
    add  ebx, 2*4 ; eip, ebp
    int  0xFF

    leave
    ret
%endmacro

; ...
APICALL OpenPipe,           0x00020002
; ...

Bau der lib:
nasm -f elf -o capi.o capi.asm
ar qf libreos.a capi.o

Code eines Programms
#include <reos/reosapi.hpp>
#include <fnc/strex.hpp>
//...
error = OpenPipe(...);
//...

Bau des Programms
#kompilieren zu test.o
ld -static -s -o test -L $LIBDIR -lreos -lfnc test.o

Fehler:
./pipetest.o: In function `main':
pipetest.cpp:(.text+0x1c): undefined reference to `OpenPipe'



Es wird also das Symbol OpenPipe gesucht, aber nicht gefunden.
Nochmal zur Kontrolle ein blick in die .o des Programms:
readelf -s test.o
   Num:    Value  Size Type    Bind   Vis      Ndx Name
...
     9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND OpenPipe

Nun ein Blick in die libreos.a um zu gucken, ob es ein Symbol OpenPipe gibt:
readelf -s libreos.a
Symbol table '.symtab' contains 23 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
...
    18: 0000012c     0 FUNC    GLOBAL DEFAULT    1 OpenPipe

Das Symbol ist vorhanden - aber warum findet der Linker es nicht?  :?
(Problem besteht bei allen Funktionen aus dieser lib)

Ich verwende in dem Programm eine andere Bibliothek welche ich in C++ geschrieben habe (libfnc.a) - Diese wird anstandslos gelinkt. Beide libs liegen im selben Verzeichnis.

Wo könnte mein Fehler liegen?
In der lib ist doch genau das gesuchte Symbol vorhanden.

Versionen:
nasm: "NASM version 2.07 compiled on Nov  6 2009"
ld: "GNU ld (GNU Binutils; openSUSE 11.2) 2.19.51.20090527-10.26.4"

XanClic

  • Beiträge: 261
    • Profil anzeigen
    • github
Gespeichert
« Antwort #1 am: 24. March 2010, 14:52 »
Hm, hast du mal versucht, die Libs zuletzt zu linken? Also
ld -static -s -o test -L $LIBDIR test.o -lreos -lfnc

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« Antwort #2 am: 24. March 2010, 17:23 »
 :-o
Das war ja einfach  :-) Vielen Dank.

Aber warum hat es mit der anderen lib funktioniert?  :?
Auf der man-page steht auch nirgends dass die libs ans ende gestellt werden müssen...  (im abschnitt zu -l)
« Letzte Änderung: 24. March 2010, 17:27 von RedEagle »

XanClic

  • Beiträge: 261
    • Profil anzeigen
    • github
Gespeichert
« Antwort #3 am: 24. March 2010, 18:30 »
Irgendwie gibt es da Abhängigkeiten. Wenn eine Datei A Funktionen aus einer anderen Datei B nutzt, muss zuerst A und dann B angegeben werden. Alternativ kann man sich wohl auch mit --start-group vor den Dateien und --end-group danach behelfen (unumgänglich, wenn beide Dateien Funktionen aus der jeweils anderen nutzen), wobei es sein könnte, dass das nur bei Archiven (also .a) hilft.

Dort steht dann auch:
Zitat von: LD-Manpage
Normally, an archive is searched only once in the order that it is specified on the command line. If a symbol in that archive is needed to resolve an undefined symbol referred to by an object in an archive that appears later on the command line, the linker would not be able to resolve that reference.
« Letzte Änderung: 24. March 2010, 18:35 von XanClic »

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« Antwort #4 am: 24. March 2010, 19:12 »
 :-D habs gefunden. Hab ich wohl überlesen  :|
Danke

 

Einloggen