Auf 32-Bit-Linux-Systemen wird dies aufgerufen
$ /lib/libc.so.6
und auf 64-Bit-Systemen dies
$ /lib/x86_64-linux-gnu/libc.so.6
liefert in einer Shell eine Ausgabe wie diese:
GNU C Library stable release version 2.10.1, by Roland McGrath et al.
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.4.0 20090506 (Red Hat 4.4.0-4).
Compiled on a Linux >>2.6.18-128.4.1.el5<< system on 2009-08-19.
Available extensions:
The C stubs add-on version 2.1.2.
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
RT using linux kernel aio
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.
Warum und wie geschieht dies und wie ist es möglich, dasselbe in anderen gemeinsam genutzten Bibliotheken zu tun?
Ich habe nach /usr/lib
ausführbaren Dateien gesucht und gefunden /usr/lib/libvlc.so.5.5.0
. Das Ausführen führte zu einem Segmentierungsfehler . : - /
Antworten:
Diese Bibliothek verfügt über eine
main()
Funktion oder einen entsprechenden Einstiegspunkt und wurde so kompiliert, dass sie sowohl als ausführbare Datei als auch als freigegebenes Objekt nützlich ist.Hier ist ein Vorschlag, wie man das macht, obwohl es bei mir nicht funktioniert.
Hier ist eine weitere Antwort auf eine ähnliche Frage zu SO , die ich schamlos plagiieren, optimieren und ein wenig erläutern werde.
Zuerst Quelle für unsere Beispielbibliothek
test.c
:Kompiliere das:
Hier kompilieren wir eine gemeinsam genutzte Bibliothek (
-fPIC
), teilen dem Linker jedoch mit, dass es sich um eine reguläre ausführbare Datei handelt (-pie
) und dass die Symboltabelle exportierbar ist (-Wl,-E
), sodass eine sinnvolle Verknüpfung mit ihr möglich ist.Und obwohl
file
es sich um ein gemeinsam genutztes Objekt handelt, funktioniert es als ausführbare Datei:Jetzt müssen wir sehen, ob es wirklich dynamisch verknüpft werden kann. Ein Beispielprogramm
program.c
:Durch die Verwendung von müssen
extern
wir keinen Header erstellen. Nun kompiliere das:Bevor wir es ausführen können, müssen wir den Pfad
libtest.so
für den dynamischen Lader hinzufügen :Jetzt:
Und
ldd a.out
zeigt die Verknüpfung zulibtest.so
.Beachten Sie, dass ich bezweifle, dass glibc so kompiliert wird, da es wahrscheinlich nicht so portabel ist wie glibc selbst (siehe
man gcc
in Bezug auf die Schalter-fPIC
und-pie
), aber es demonstriert den grundlegenden Mechanismus. Für die wahren Details müssten Sie sich das Quell-Makefile ansehen.quelle
nm
die gemeinsam genutzte Bibliothek zu verwenden, aber es war keine Debug-Version. Also, warumlibvlc
und andere stürzen ab?libc
eine Ausnahme.ld
undlibpthread
.ld.so
ist in anderer Hinsicht besonders. In gewissem Maße ist es eher eine echte ausführbare Datei als eine normale dynamisch verknüpfte ausführbare Datei.Lassen Sie uns für eine Antwort in zufälligen Glibc Repo in Github tauchen. Diese Version stellt ein „Banner“ zur Verfügung
version.c
.In derselben Datei gibt es einige interessante Punkte:
__libc_print_version
Die Funktion, die das Drucken auf denselben Text und dasselbe Symbol ermöglicht,__libc_main (void)
die als Einstiegspunkt dokumentiert sind. Dieses Symbol wird also beim Ausführen der Bibliothek aufgerufen.Woher weiß der Linker / Compiler, dass dies genau die Einstiegsfunktion ist?
Tauchen wir in das Makefile ein . In Linker Flags gibt es interessante Flags:
Dies ist also das Linker-Flag zum Festlegen des Einstiegspunkts in der Bibliothek. Beim
-e function_name
Erstellen einer Bibliothek können Sie für Linker ausführbares Verhalten erstellen. Was macht es wirklich? Schauen wir uns das Handbuch an (etwas veraltet, aber immer noch gültig) :(aktuelle Dokumentation finden Sie hier )
Wirklich
ld
Linker erstellt eine ausführbare Datei mit Einstiegspunktfunktion, wenn Sie sie mit einer Befehlszeilenoption versehen-e
(praktischste Lösung), ein Funktionssymbol bereitstellenstart
oder eine Symboladresse in Assembler einfügen.Bitte beachten Sie jedoch, dass es eindeutig nicht garantiert ist, mit anderen Linkern zu arbeiten (ich weiß nicht, ob die lld von llvm das gleiche Flag hat). Warum dies für andere Zwecke als die Bereitstellung von Informationen in dieser Datei nützlich sein sollte, ist mir nicht bekannt.
quelle