Depende si su implementación usa C interfaz para utilidades de bajo nivel o no.
Si la implementación de su idioma da acceso directo a las llamadas al sistema sin pasar por la C contenedor no necesita usar VDSO (por ejemplo, podría generar el SYSENTER
apropiado instrucción de la máquina para hacer la llamada al sistema), pero podría decidir usar VDSO y luego aprovecharlo. En ese caso, su idioma ni siquiera necesita seguir todas las convenciones ABI, solo las convenciones del kernel. (por ejemplo, no necesita la distinción entre llamadas y llamadas seguras proporcionada por ABI en los registros, e incluso podría evitar el uso de pilas).
Un ejemplo de implementación de lenguaje que ni siquiera usa libc.so
es el esquema de huesos. Podrías encontrar algunos otros.
Mi comprensión del VDSO es que es una abstracción, proporcionada por el kernel, para abstraer las pequeñas diferencias (relacionadas con las transiciones del kernel-tierra del usuario) en la implementación de llamadas al sistema, entre varias familias de procesadores x86. Si ha elegido un destino de procesador en particular, no necesita VDSO y siempre puede evitarlo.
AFAIU, el VDSO es un objeto compartido ELF, ubicado (en mi Debian/AMD64 con un kernel 3.8.3 compilado recientemente) en el segmento ffffffffff600000-ffffffffff601000
; verificar exactamente con cat /proc/self/maps
donde es). Por lo tanto, solo necesita comprender la organización de los objetos compartidos de ELF y recuperar los símbolos de ellos. Ver esto y aquello enlaces. El VDSO usa las convenciones de C para llamadas documentadas en la especificación ABI x86-64.
ELF es un formato bien documentado. Y también lo son las convenciones ABI x86-64 (que definen con precisión las convenciones de llamada C y cómo comienza exactamente la imagen de un proceso. Consulte también la página del manual execve (2)) y, por supuesto, la documentación del kernel, por lo que no entiendo cual es tu problema. Estoy de acuerdo en que entender ELF lleva tiempo (lo hice hace 10 años, pero mi memoria está oxidada). Lea también el <elf.h>
archivo de encabezado en su máquina.
Por ejemplo; corriendo (bajo zsh
en Debian x86-64 de 64 bits)
% 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]
Ver también esta respuesta.
Probablemente desee dentro de su tiempo de ejecución una versión mínima de un enlazador dinámico capaz de analizar simplemente el VDSO. Seguro que desea comprender el estado exacto en el que se inicia un proceso y, en particular, el papel de auxv
, el vector auxiliar (realmente se me olvidan estos detalles, pero recuerdo que son importantes). Véase, por ejemplo. este artículo
En realidad, iniciar de manera confiable su tiempo de ejecución es probablemente más difícil que el problema de VDSO.
También es posible que desee leer el manual de ensamblaje de Linux, que también explica algunas cosas (pero más sobre x86 que sobre x86-64)
Por cierto, el código de http://musl-libc.org/ (que es una libc alternativa) es mucho más fácil de leer y comprender (y aprenderá fácilmente cómo hacen enlaces dinámicos, pthreads, etc.)
Encontré útiles estos archivos en el árbol del kernel de Linux:
Documentation/ABI/stable/vdso
(¿Qué es el objeto vDSO?)Documentation/vDSO/parse_vdso.c
(Análisis de referencia para el objeto vDSO)
El objeto vDSO es un objeto virtual dinámico compartido que siempre se asigna al espacio de direcciones de un proceso AMD64 en Linux. Se puede utilizar para implementar llamadas rápidas al sistema. Para acceder a las funciones dentro del objeto vDSO, debe
- ubica el objeto
- extraer una dirección de la tabla de símbolos
Ambas cosas se pueden hacer con la implementación de referencia con licencia CC0 parse_vdso.c.