GCC-Verknüpfung statische libc und andere Bibliotheken dynamisch, revisited?
Folgende Fragen relevant sind, aber nicht die Antwort auf meine Frage:
Verlinkung teilweise statische und teilweise dynamisch in GCC
GCC: statische Verlinkung nur einige Bibliotheken
Statische link-shared-library-Funktion im gcc
Fragte ich eine sehr ähnliche Frage schon gestellt, aber seit der letzten Frage begonnen, von mir etwas überladen in den Kommentar-Abschnitt und nicht vollständig beantwortet werden (aber ich markiert es als beantwortet, da war es eine gute Leistung und hat zumindest teilweise Antwort) ich werde eine neue Frage stellen. Die Frage ist insbesondere, wie link-libc statisch, während die Verknüpfung einige andere Bibliothek (z.B. libm) dynamisch. Dies wurde vorgeschlagen, dass nicht getan werden kann in der ersten Frage, ist das wahr? Wenn ja wäre es sehr interessant zu wissen, warum nicht.
Ist es auch möglich, dies zu tun? Jemand machte eine Bemerkung (die entfernt wurde, aus irgendeinem Grund, vielleicht war es falsch?) dass es möglich ist, aber es muss dann auch existiert eine dynamisch verknüpfte version der libc, da es erforderlich sein wird, indem Sie die dynamische Bibliothek (z.B. dynamische libm erfordern dynamische libc (?)).
Dies ist in Ordnung für mich, aber es ist mir nicht klar, wie man GCC sagen, um dies zu tun, d.h. link in der libc, da sowohl statische als auch dynamische. Wie mache ich das (ich habe ein paar versuche, einige sind weiter unten in der Frage)? Oder gibt es eine andere Möglichkeit das zu tun, was ich will?
Wir zuerst sehen, dass durch das einfache ausführen von gcc-test.c -lm, alles ist miteinander verbunden in einem dynamisch, wie folgt:
$ gcc test.c -lm
$ ldd a.out
linux-vdso.so.1 (0x00007fffb37d1000)
libm.so.6 => /lib64/libm.so.6 (0x00007f3b0eeb6000)
libc.so.6 => /lib64/libc.so.6 (0x00007f3b0eb10000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3b0f1b0000)
Link nur libm als statisch, während die libc dynamisch bleiben, können wir tun (als Z-boson schon in eine der oben genannten Fragen):
$ gcc test.c /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libm.a
$ ldd a.out
linux-vdso.so.1 (0x00007fff747ff000)
libc.so.6 => /lib64/libc.so.6 (0x00007f09aaa0c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f09aadb2000)
Aber Versuch das gleiche Verfahren, um den link statische libc und libm dynamische, scheint nicht zu funktionieren:
$ gcc test.c /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a -lm
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
collect2: error: ld returned 1 exit status
Was bedeutet diese Fehlermeldung?
Einige andere versuche (die meisten waren auch in meiner ersten Frage):
$ gcc test.c /usr/lib64/libc.a
linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
urned 1 exit status
$ gcc test.c -Wl,-Bdynamic -lm -Wl,-Bstatic -lc
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
$ gcc -Wl,-Bdynamic -lm -Wl,-Bstatic -lc test.c
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
$ gcc -Wl,-Bstatic -lc -Wl,-Bdynamic -lm test.c
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
collect2: error: ld returned 1 exit status
$ gcc test.c /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.so -lm
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
collect2: error: ld returned 1 exit status
$ gcc test.c /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.so /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a -lm
Beachten Sie, dass die Letzte kompiliert/gelinkt erfolgreich. Allerdings libc wurde nicht verknüpft statisch, nur dynamisch, so ist es ein weiterer gescheiterter Versuch.
Das test-Programm ist einfach das folgende:
$ cat test.c
#include <stdio.h>
#include <math.h>
int main(int argc, char **argv)
{
int i;
int result;
for(i = 0; i < 65535; i++) {
result = sin(i);
}
return 0;
}
Edit:
Ich habe auch versucht statifier und ermine, wie vorgeschlagen, in dieser Frage:
Statische link-shared-library-Funktion im gcc
Weder arbeitet.
libm
links zu libc
- kann das Teil des Problems (siehe ldd /usr/lib64/libm.so
).Zwinck, Es ist nicht einfach, ich versuche zu zeigen, dass eine ROP-basierte exploit ist möglich gegen Intel MPX-unter bestimmten Umständen, aber es erfordert, dass libmpx (das gibt es nur in einer dynamisch verknüpften form, kein source-code zur Verfügung, soweit ich weiß) verknüpft ist dynamisch und libc verknüpft werden, statisch. Aber wenn dies nicht möglich ist, wäre es interessant zu wissen, warum das nicht in jedem Fall, und würde ich nach einem anderen Ansatz.
ja, dass ist wahrscheinlich zumindest ein Teil des Problems, es war wies darauf hin kurz in den Kommentar-Abschnitt vor dem Kommentar verschwunden, in der anderen Frage.
Sie benötigen den ganzen libc statisch gelinkt, oder nur ein paar bestimmte Funktionen?
InformationsquelleAutor AttributedTensorField | 2014-10-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Grundsätzlich ist deine erste Ansatz ist der richtige Weg, dies zu tun:
Nach gcc fügt die implizite Bibliotheken werden sich (konzeptionell):
So, dass bedeutet, dass alle libc-Funktionen aufgerufen wird, entweder durch
crt1.o
odertest.c
sein zog auslibc.a
und statisch gelinkt, in der Erwägung, dass alle aufgerufenen Funktionen allein vonlibm
oderlibgcc
werden dynamisch gelinkt (aber es wird die Wiederverwendung der statischen Funktionen, wenn libm aufruft, etwas bereits gezogen).Der linker startet immer in der linken Datei/library, und arbeitet nach; es geht nie zurück.
.c
und.o
Dateien verknüpft sind bedingungslos, aber.a
Dateien und-l
Optionen werden nur verwendet, um Funktionen, die bereits verwiesen, aber noch nicht definiert. Daher wird eine Bibliothek auf der linken Seite ist sinnlos (und-lc
muss zweimal angezeigt, weil-lc
hängt-lgcc
, und-lgcc
hängt-lc
). Link-Reihenfolge ist wichtig!Leider, Sie scheinen vereitelt worden, was möglicherweise ein bug in
strcmp
(oder eher in der libc enthältstrcmp
):STT_GNU_IFUNC
Sache ist eine clevere Funktion, die es erlaubt, mehrere Versionen einer Funktion aufgenommen werden, und die optimale ausgewählt werden, zur Laufzeit, basierend auf dem, was die hardware verfügbar ist. Ich bin mir nicht sicher, aber es sieht aus wie dieses feature ist nur verfügbar in einer PIE (Position Independent Executable) oder gemeinsam genutzte Bibliothek erstellen.Warum, das wäre in einer statischen
libc.a
ist mir ein Rätsel, aber es gibt eine einfache Problemumgehung: setzen Sie Ihre eigenestrcmp
(eine grundlegende, langsame Implementierung ist nur ein paar Zeilen C) und verknüpfen es in vorlibc.a
.Alternativ können Sie extrahieren Sie die Funktionen von
libc.a
, dass Sie wirklich wollen, und verknüpfen Sie nur die in statisch:ar
ist.a
Dateien, wietar
ist.tar
- Dateien, obwohl die Syntax variiert ein wenig, so dieses Beispiel extrahiert die.o
Dateien aus dem.a
- Datei, und klicken Sie dann links ausdrücklich.Als eine Nebenbemerkung (die Frage wurde sehr gut beantwortet), leider bekomme ich "ein.out: error while loading shared libraries: RTLD_NEXT, die im code verwendet, die nicht dynamisch geladen werden" wenn ich das mit dem MPX-Bibliothek (libmpx). Allerdings werde ich mich mehr in ihn.
Ich denke, es ist sicher zu sagen, dass dies nicht eine bewährte Anordnung. Es kann gut sein, viele bugs. Vielleicht sogar ein show-stopper.
Ich bin froh zu sehen, Sie folgten mit dieser Frage. Der Grund, ich habe versucht, deine Frage zu beantworten ist, ich war der Bau einer gemeinsam genutzten Bibliothek und ich wollte keine Abhängigkeiten in der Bibliothek selbst. Ich fand, als ich die Bibliothek auf einer älteren Linux-Rechner, dass es abgestürzt ist, weil diese Abhängigkeiten. Es war leicht zu machen diese shared-library, ohne Abhängigkeiten, mit MSVC aber mit GCC-es war ein großer Schmerz. Auf linux-Systemen die ich kompilieren Sie die Bibliothek für jedes system (was nicht immer einfach ist, ohne root-Zugriff). Man bekommt das Gefühl, dass GCC nicht wollen, dass Sie die Dinge statisch.
Das ist ziemlich genau; statische binaries Probleme haben, und es gibt bestimmte Funktionen, die ein modernes Glibc weigert sich statische (d.h. der libc.eine version wird
dlopen
eine Bibliothek). FWIW, die gemeinsame Lösung, um die Portabilität problem zu bauen ist die Verwendung von Bibliotheken von einem alten system-Sie arbeiten in der Regel auf neuere Systeme, aber nicht die andere Weise herum. RHEL5 ist eine gute option, gerade jetzt.InformationsquelleAutor ams
Basiert auf der Antwort von ams ich habe die Folgen
mystrcmp.c
Kompilieren
Setup-Dateien
Link
Diese links und wird ordnungsgemäß ausgeführt. Allerdings
ldd
zeigtScheint es, dass dynamische
libm
erfordert dynamischelibc
. Eigentlich ist das leicht zu zeigenldd libm.so berichtet
So dass es unmöglich ist einen link zu libm.also ohne Verknüpfung libc.so gut, es sei denn, Sie verwalten, zu kompilieren, libm, ohne die Abhängigkeit von libc.
InformationsquelleAutor Z boson