Lowlevel
Lowlevel => Softwareentwicklung => Thema gestartet von: RedEagle 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"
-
Hm, hast du mal versucht, die Libs zuletzt zu linken? Also
ld -static -s -o test -L $LIBDIR test.o -lreos -lfnc
-
:-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)
-
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:
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.
-
:-D habs gefunden. Hab ich wohl überlesen :|
Danke