Dipende se l'implementazione utilizza C interfaccia per i servizi di basso livello o no.
Se la lingua consente di accedere direttamente alle chiamate di sistema senza passare attraverso il C involucro non è necessario utilizzare VDSO (si potrebbe per esempio generare l'istruzione di SYSENTER
macchina adeguata per fare la chiamata di sistema). In quel caso, la tua lingua non ha nemmeno bisogno di seguire tutte le convenzioni ABI, solo le convenzioni del kernel. (per esempio, non è necessario che l'ABI fornisca distinguo sicuro per i chiamanti sicuro da calle sui registri, e si potrebbe persino evitare di utilizzare qualsiasi stack).
La mia comprensione del VDSO è che è un'astrazione, fornita dal kernel, per astrarre le varie piccole differenze (relative a user-land -> transizioni del kernel) nell'implementazione di syscalls, tra varie famiglie di processori x86. Se hai scelto un particolare target del processore, non hai bisogno di VDSO e puoi sempre evitarlo.
AFAIU, il VDSO è un oggetto ELF condiviso, seduto (sul mio Debian/AMD64 con un kernel 3.8.3 recentemente compilato) nel segmento ffffffffff600000-ffffffffff601000
; controllare esattamente con cat /proc/self/maps
dove si trova). Quindi devi solo capire l'organizzazione degli oggetti condivisi ELF e recuperare i simboli da esso. Vedi i link this & that. Il VDSO utilizza le convenzioni C per le chiamate documentate nella specifica ABI x86-64.
Cioè, se si estrae dal proprio spazio di elaborazione VDSO e scrivere su un file su disco, il risultato è un oggetto ELF condiviso ben formato
ELF è un formato ben documentato. E lo è anche lo x86-64 ABI conventions (che definisce con precisione le convenzioni di chiamata C e come esattamente l'immagine di un processo inizia. Vedere anche execve(2)) man page e, naturalmente, la documentazione del kernel, quindi non capisco qual è il problema. Sono d'accordo che la comprensione dell'ELF richiede tempo (l'ho fatto 10 anni fa, ma la mia memoria è arrugginita). Leggi anche il file di intestazione <elf.h>
sul tuo computer.
Ad esempio; esecuzione (sotto zsh
su 64 bit Debian x86-64)
% 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]
Vedi anche this answer.
Probabilmente si desidera all'interno del proprio runtime una versione minima di un linker dinamico in grado di analizzare semplicemente VDSO.Certamente vuoi capire lo stato esatto in cui è stato avviato un processo, e in particolare il ruolo di auxv
, il vettore ausiliario (ho davvero dimenticato questi dettagli, ma ricordo che sono importanti). Vedi per es. this article
In realtà, l'avvio affidabile del runtime è probabilmente più difficile del problema VDSO.
Si consiglia inoltre di leggere il linux assembly howto che spiega anche alcune cose (ma di più su x86 di x86-64)
BTW, il codice di http://musl-libc.org/ (che è un libc alternativa) è molto più facile da leggere e capire (e imparerete facilmente come lo fanno il collegamento dinamico, pthreads, ecc ..)
Per curiosità, qual è il tuo linguaggio che non usa l'interfaccia * C * per le syscalls? Fornisci un'implementazione software gratuita per questo? –
@Basile Cerco di scrivere un Forth per sapere come funziona Forth. Voglio programmare in assembly senza alcuna libreria esistente, simile a [jonesforth] (http://git.annexia.org/?p=jonesforth.git). L'oggetto VDSO è solo un modo piacevole ed efficace per implementare le chiamate di sistema. – fuz