Comment tirer parti de l’object VDSO avec votre propre langage de programmation?

Les kernelx Linux récents (au moins sur amd64) fournissent un fichier object magique appelé linux-vdso.so.1 qui extrait l’interface Syscall au kernel, permettant au kernel de choisir la convention d’appel optimale. Si vous écrivez du code en C, la glibc utilise automatiquement cet object.

Maintenant, si je veux écrire un programme sans utiliser la glibc, comment puis-je utiliser cet object? L’interface fournie est-elle documentée quelque part? Qu’en est-il de la convention d’appel?

Cela dépend si votre implémentation utilise l’interface C pour les utilitaires de bas niveau ou non.

Si votre langage donne un access direct à syscalls sans passer par le wrapper C, vous n’avez pas besoin d’utiliser VDSO (vous pourriez par exemple générer l’instruction machine SYSENTER appropriée pour effectuer l’appel système). Dans ce cas, votre langage n’a même pas besoin de suivre toutes les conventions ABI, juste les conventions du kernel. (par exemple, vous n’avez pas besoin que l’ABI fournisse un distinguo de sécurité sur les registres, et vous pouvez même éviter d’utiliser des stacks).

Ma compréhension du VDSO est que c’est une abstraction, fournie par le kernel, qui permet d’abstraire les différentes petites différences (liées aux transitions utilisateur – terre) dans l’implémentation de syscalls, entre différentes familles de processeurs x86. Si vous avez choisi une cible de processeur particulière, vous n’avez pas besoin de VDSO et vous pouvez toujours l’éviter.

AFAIU, le VDSO est un object partagé ELF, assis (sur mon Debian / AMD64 avec un kernel 3.8.3 récemment compilé) dans le segment ffffffffff600000-ffffffffff601000 ; vérifiez exactement avec cat /proc/self/maps où il se trouve). Il vous suffit donc de comprendre l’organisation des objects partagés ELF et d’en récupérer les symboles. Voir cela et cela liens. Le VDSO utilise les conventions C pour appeler documentées dans la spécification ABI x86-64.

Autrement dit, si vous extrayez de votre espace de processus le VDSO et l’écrivez sur un fichier disque, le résultat est un object partagé ELF bien formé.

ELF est un format bien documenté. Il en va de même pour les conventions ABX x86-64 (qui définissent précisément les conventions d’appel C, et comment une image de processus commence exactement. Voir aussi la page de manuel execve (2) ) et bien sûr la documentation du kernel. quel est votre problème Je suis d’accord que comprendre ELF prend du temps (je l’ai fait il y a 10 ans, mais ma mémoire est rouillée). Lisez également le fichier d’en-tête sur votre machine.

Par exemple; en cours d’exécution (sous zsh sur Debian x86-64 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, ssortingpped % 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] 

Voir aussi cette réponse .

Vous voulez probablement à l’intérieur de votre runtime une version minimale d’un éditeur de liens dynamic capable d’parsingr simplement le VDSO. Vous voulez certainement comprendre l’état exact dans lequel un processus est démarré, et en particulier le rôle de l’auxiliaire, le vecteur auxiliaire (j’oublie vraiment ces détails, mais je me souviens qu’ils sont importants). Voir par exemple cet article

En fait, le démarrage fiable de votre runtime est probablement plus difficile que le problème VDSO.

Vous voudrez peut-être aussi lire le howto de l’assembly linux, qui explique également certaines choses (mais plus sur x86 que x86-64)

BTW, le code de http://musl-libc.org/ (qui est une alternative libc) est beaucoup plus facile à lire et à comprendre (et vous apprendrez facilement comment ils font des liens dynamics, pthreads, etc.)

En creusant l’internet j’ai trouvé ce lien

http://www.linuxjournal.com/content/creating-vdso-colonels-other-chicken

Je pense que cela répond à votre question

J’ai trouvé ces fichiers dans l’arborescence du kernel Linux utiles:

  • Documentation/ABI/stable/vdso (qu’est-ce que l’object vDSO?)
  • Documentation/vDSO/parse_vdso.c ( Documentation/vDSO/parse_vdso.c référence pour l’object vDSO)

L’object vDSO est un object partagé dynamic virtuel qui est toujours mappé dans l’espace d’adressage d’un processus amd64 sous Linux. Il peut être utilisé pour mettre en œuvre des appels système rapides. Pour accéder aux fonctions de l’object vDSO, vous devez

  • localiser l’object
  • extraire une adresse de la table des symboles

Les deux choses peuvent être faites avec l’implémentation de référence sous licence CC0 parse_vdso.c .