Wywoływanie tego w 32-bitowych systemach Linux
$ /lib/libc.so.6
a na systemach 64-bitowych to
$ /lib/x86_64-linux-gnu/libc.so.6
w powłoce zapewnia wyjście takie jak to:
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>.
Dlaczego i jak to się dzieje i jak to zrobić w innych bibliotekach współdzielonych?
Spojrzałem na /usr/lib
pliki wykonywalne i znalazłem /usr/lib/libvlc.so.5.5.0
. Uruchomienie spowodowało błąd segmentacji . : - /
Odpowiedzi:
Ta biblioteka ma
main()
funkcję lub równoważny punkt wejścia i została skompilowana w taki sposób, że jest użyteczna zarówno jako plik wykonywalny, jak i obiekt współdzielony.Oto jedna sugestia, jak to zrobić, chociaż to nie działa dla mnie.
Oto kolejna odpowiedź na podobne pytanie dotyczące SO , którą bezwstydnie plagiatuję, poprawiam i dodam trochę wyjaśnień.
Najpierw źródło naszej przykładowej biblioteki
test.c
:Skompiluj, że:
Tutaj kompilujemy bibliotekę współdzieloną (
-fPIC
), ale mówimy linkerowi, że jest to zwykły plik wykonywalny (-pie
), i że jego tablica symboli-Wl,-E
może zostać wyeksportowana ( ), dzięki czemu można go użytecznie połączyć.I chociaż
file
powie, że jest to obiekt współdzielony, działa jako plik wykonywalny:Teraz musimy sprawdzić, czy naprawdę można go dynamicznie połączyć. Przykładowy program
program.c
:Używanie
extern
oszczędza nam konieczności tworzenia nagłówka. Teraz skompiluj, że:Zanim będziemy mogli go wykonać, musimy dodać ścieżkę
libtest.so
do dynamicznego modułu ładującego:Teraz:
I
ldd a.out
pokaże powiązanie zlibtest.so
.Zauważ, że wątpię w to, jak faktycznie kompiluje się glibc, ponieważ prawdopodobnie nie jest tak przenośny jak sam glibc (patrz
man gcc
w odniesieniu do przełączników-fPIC
i-pie
), ale pokazuje podstawowy mechanizm. Aby zobaczyć prawdziwe szczegóły, musisz spojrzeć na źródłowy plik makefile.źródło
nm
w bibliotece współdzielonej, ale nie była to wersja do debugowania. Więc dlaczegolibvlc
i inni się zawieszają?libc
jest wyjątkiem.ld
ilibpthread
.ld.so
jest wyjątkowy pod innymi względami. W pewnym stopniu jest to bardziej prawdziwy plik wykonywalny niż normalny plik wykonywalny z dynamicznym łączeniem.Zanurzmy się w poszukiwaniu odpowiedzi w losowym repozytorium glibc w github. Ta wersja zawiera „banner” w pliku
version.c
.W tym samym pliku znajduje się kilka interesujących punktów:
__libc_print_version
funkcja, która zapewnia drukowanie na tym samym tekście i symbolu,__libc_main (void)
co jest udokumentowane jako punkt wejścia. Tak więc ten symbol jest wywoływany podczas uruchamiania biblioteki.Skąd więc linker / kompilator wie, że jest to dokładnie funkcja punktu wejścia?
Zanurzmy się w makefile . W flagach linkera jest ciekawa flaga:
To jest flaga linkera do ustawiania punktu wejścia w bibliotece. Podczas budowania biblioteki możesz zapewnić
-e function_name
linkerowi tworzenie plików wykonywalnych. Co to naprawdę robi? Spójrzmy na instrukcję (nieco przestarzałą, ale wciąż aktualną) :(aktualna dokumentacja znajduje się tutaj )
Naprawdę
ld
linker tworzy plik wykonywalny z funkcją punktu wejścia, jeśli podasz mu opcję wiersza poleceń-e
(najbardziej praktyczne rozwiązanie), podasz symbol funkcjistart
lub wstrzykujesz adres symbolu w asemblerze.Należy jednak pamiętać, że wyraźnie nie gwarantuje się współpracy z innymi linkerami (nie wiem, czy llvm's lld ma tę samą flagę). Dlaczego nie powinno to być przydatne do celów innych niż podawanie informacji na temat takiego pliku, nie wiem.
źródło