Moja wiedza na temat VDSO polega na tym, że jest to abstrakcja dostarczana przez jądro, aby usunąć różne małe różnice (związane z użytkownik-ziemia -> przejścia jądra) we wdrażaniu syscalls pomiędzy różnymi rodzinami procesorów x86. Jeśli wybrałeś konkretny cel procesora, nie potrzebujesz VDSO i zawsze możesz tego uniknąć.
AFAIU, VDSO jest obiektem wspólnym ELF, siedzi (na moim Debianie/AMD64 z ostatnio skompilowanym jądrem 3.8.3) w segmencie ffffffffff600000-ffffffffff601000
; sprawdź dokładnie, gdzie jest cat /proc/self/maps
). Musisz więc po prostu zrozumieć organizację obiektów wspólnych ELF i pobrać z niej symbole. Zobacz linki: this & that. VDSO używa konwencji C dla wywołania udokumentowanego w specyfikacji ABI x86-64.
Oznacza to, że jeśli wyodrębnić z przestrzeni procesowej VDSO i zapisać go na dysku plik, wynik jest dobrze uformowane ELF obiekt udostępniony
ELF jest dobrze udokumentowana Format. Tak samo jest z x86-64 ABI conventions (która dokładnie definiuje konwencje wywoływania C i jak dokładnie zaczyna się obraz procesu (zobacz także execve(2)) oraz dokumentację jądra, więc nie rozumiem, jaki jest twój problem. Zgadzam się, że zrozumienie ELF wymaga czasu (zrobiłem to 10 lat temu, ale moja pamięć jest zardzewiała). Przeczytaj także plik nagłówkowy <elf.h>
na swoim komputerze.
Na przykład; działa (w zsh
na 64 bitów x86-64 Debiana)
% file $(which sash)
/bin/sash: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
statically linked, for GNU/Linux 2.6.26,
BuildID[sha1]=0x0347fcc08fba2f811f58af99f26111d0f579a9f6, stripped
% ldd $(which sash)
not a dynamic executable
% sash
Stand-alone shell (version 3.7)
> ps |grep sash
21635 pts/3 00:00:00 sash
> cat /proc/21635/maps
00400000-004da000 r-xp 00000000 08:01 4985590 /bin/sash
006da000-006dc000 rw-p 000da000 08:01 4985590 /bin/sash
006dc000-006e1000 rw-p 00000000 00:00 0
017e3000-01806000 rw-p 00000000 00:00 0 [heap]
7fe4950e5000-7fe4950e7000 rw-p 00000000 00:00 0
7fff3f130000-7fff3f151000 rw-p 00000000 00:00 0 [stack]
7fff3f173000-7fff3f175000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Patrz także this answer.
Prawdopodobnie chcesz w swoim środowisku wykonawczym minimalną wersję dynamicznego linkera, który będzie w stanie po prostu przeanalizować VDSO.Na pewno chcesz zrozumieć dokładny stan, w którym rozpoczyna się proces, a zwłaszcza rolę auxv
, pomocniczego wektora (naprawdę zapominam o tych szczegółach, ale pamiętam, że są one ważne). Zobacz np. this article
Rzeczywiście, uruchomienie niezawodnie Twój czas pracy jest prawdopodobnie trudniejszy niż problem VDSO.
Można też przeczytać linux assembly howto która wyjaśnia również pewne rzeczy (ale o x86 niż x86-64)
BTW, kod http://musl-libc.org/ (który jest alternatywą libc) jest znacznie łatwiejsze do odczytania i zrozumieć (i będziesz łatwo nauczyć robią dynamiczne linkowanie, pthreads, etc ..)
Z ciekawości, jaki jest twój język, który nie korzysta z interfejsu * C * dla syscalls? Czy zapewniasz dla niego darmową implementację oprogramowania? –
@Basile Próbuję napisać Forth, aby dowiedzieć się, jak działa Forth. Chcę programować w złożeniu bez żadnych istniejących bibliotek, podobnych do [jonesforth] (http://git.annexia.org/?p=jonesforth.git). Obiekt VDSO jest po prostu przyjemnym i wydajnym sposobem realizacji wywołań systemowych. – fuz