Provided by: manpages-fr_4.23.1-1_all bug

NOM

       vdso – Présentation de l’objet partagé dynamique ELF virtuel

SYNOPSIS

       #include <sys/auxv.h>

       void *vdso = (uintptr_t) getauxval(AT_SYSINFO_EHDR);

DESCRIPTION

       Le  « vDSO »  (objet partagé dynamique virtuel, « virtual dynamic shared object ») est une
       petite  bibliothèque  partagée  que  le  noyau  projette  automatiquement  dans   l’espace
       d’adresses  de  toutes  les  applications  en  espace  utilisateur. Les applications n’ont
       normalement pas besoin de s’occuper  elles-mêmes  de  ces  détails  puisque  le  vDSO  est
       d’habitude  appelé par la bibliothèque C. Ainsi, vous pouvez écrire du code normalement en
       utilisant les fonctions standards et la bibliothèque C s’occupera  d’utiliser  toutes  les
       fonctionnalités disponibles par l’intermédiaire du vDSO.

       Pourquoi  le vDSO existe ? Certains appels système fournis par le noyau finissent par être
       utilisés fréquemment par le code en espace utilisateur, au point que  ces  appels  peuvent
       avoir  une  emprise  excessive sur les performances. C’est à la fois dû à la fréquence des
       appels qu’aux nombreux changements de contexte à force de sortir de  l’espace  utilisateur
       pour entrer dans le noyau.

       La  suite  de  cette  documentation  est  orientée  pour  les curieux et les auteurs de la
       bibliothèque C plutôt que pour les développeurs généraux. Si  vous  essayez  d’appeler  le
       vDSO  dans  vos  propres applications plutôt que d’utiliser la bibliothèque C, vous faites
       sans doute fausse route.

   Contexte exemple
       Réaliser des appels système peut être lent. Dans les systèmes  32 bits  x86,  vous  pouvez
       déclencher  une interruption logicielle (int $0x80) pour indiquer au noyau que vous voulez
       faire un appel système. Cependant, cette instruction est coûteuse : elle  passe  par  tous
       les chemins complets de traitement des interruptions dans le microcode du processeur ainsi
       que dans le noyau. Les nouveaux processeurs ont des instructions plus  rapides  (mais  non
       rétrocompatibles)  pour  initier les appels système. Plutôt que forcer la bibliothèque C à
       vérifier  si  cette  fonctionnalité  est  disponible  au   moment   de   l’exécution,   la
       bibliothèque C peut utiliser les fonctions fournies par le noyau dans le vDSO.

       Remarquez  que  cette terminologie peut être source de confusion. Sur les systèmes x86, la
       fonction vDSO utilisée pour déterminer la méthode préférée pour réaliser un appel  système
       est  appelée  « __kernel_vsyscall » alors que sous x86_64, le terme « vsyscall » se réfère
       aussi à une façon obsolète de demander au noyau l’heure ou le processeur  sur  lequel  est
       l’appelant.

       Un  appel  système fréquemment utilisé est gettimeofday(2). Cet appel système est appelé à
       la fois directement par les applications en espace utilisateur  et  indirectement  par  la
       bibliothèque C.  Remarquez  que  les horodatages, boucles temporelles ou scrutations — ont
       tous fréquemment besoin de savoir  l’heure  exacte.  Ce  n’est  pas  non  plus  un  secret
       — n’importe  quelle  application dans n’importe quel mode (superutilisateur ou utilisateur
       normal) aura la  même  réponse.  Alors  le  noyau  s’arrange  pour  que  les  informations
       nécessaires  pour  répondre  à cette question soient placées dans la mémoire accessible au
       processus. Ainsi un appel de gettimeofday(2) est transformé d’un appel système en un appel
       normal de fonction, avec peu d’accès mémoire.

   Trouver le vDSO
       L’adresse de base du vDSO (s’il existe) est passée par le noyau à tous les programmes dans
       le  vecteur  auxiliaire  initial  (consultez  getauxval(3))  à  l’aide   de   l’indicateur
       AT_SYSINFO_EHDR.

       Vous  ne  devez  pas  supposer  que  le  vDSO  est  projeté à un endroit particulier de la
       projection en mémoire de l’utilisateur. L’adresse de base sera  normalement  aléatoire  au
       moment  de  l’exécution  à  chaque  fois  qu’une nouvelle image de processus est créée (au
       moment de execve(2)). C’est ainsi pour des raisons de sécurité, afin d’éviter les attaques
       de « retour vers libc ».

       Pour certaines architectures, un indicateur AT_SYSINFO est aussi présent. Il n’est utilisé
       que pour localiser le  point  d’entrée  vsyscall  et  est  souvent  omis  ou  défini  à  0
       (signifiant  qu’il  n’est  pas disponible). Cet indicateur est un rappel du fonctionnement
       initial de vDSO (consultez Historique ci-dessous) et son utilisation devrait être évitée.

   Format de fichier
       Puisque le vDSO est une image ELF complète, vous pouvez y rechercher  des  symboles.  Cela
       permet d’ajouter de nouveaux symboles avec les versions de noyau plus récentes et permet à
       la bibliothèque C de détecter les fonctionnalités disponibles  au  moment  de  l’exécution
       lors de l’exécution sous différentes versions de noyau. D’habitude, la bibliothèque C fera
       la détection lors du premier appel puis mettra  en  cache  le  résultat  pour  les  appels
       suivants.

       Tous les appels sont aussi versionnés (en utilisant le format de version GNU). Cela permet
       au noyau de mettre à jour la signature de fonction sans casser la rétrocompatibilité. Cela
       signifie  modifier  les  arguments acceptés par la fonction et la valeur de retour. Ainsi,
       lors de la recherche de symboles dans le vDSO, vous devez toujours inclure la version pour
       correspondre à l’ABI attendue.

       Typiquement,  le  vDSO  suit  la  convention  de nommage de préfixer tous les symboles par
       « __vdso_ » ou « __kernel_ » afin de les distinguer des  autres  symboles  standards.  Par
       exemple, la fonction « gettimeofday » est nommée « __vdso_gettimeofday ».

       Utilisez  les  conventions  d’appel C  standard  pour  appeler  n’importe  laquelle de ces
       fonctions. Pas la peine de vous embêter avec les registres bizarres ou  les  comportements
       de pile.

NOTES

   Source
       Lors  de  la  compilation du noyau, le code vDSO est compilé et lié automatiquement. Il se
       trouve souvent dans le répertoire spécifique à l’architecture :

           find arch/$ARCH/ -name '*vdso*.so*' -o -name '*gate*.so*'

   Noms vDSO
       Le nom du vDSO dépend des architectures. Il est souvent visible dans des endroits comme la
       sortie  de  ldd(1)  de  la glibc. Le nom exact ne devrait affecter aucun code, donc pas la
       peine de le coder en dur.

       ABI utilisateur   Nom vDSO
       ────────────────────────────────────
       aarch64           linux-vdso.so.1
       arm               linux-vdso.so.1
       ia64              linux-gate.so.1
       mips              linux-vdso.so.1
       ppc/32            linux-vdso32.so.1
       ppc/64            linux-vdso64.so.1
       riscv             linux-vdso.so.1
       s390              linux-vdso32.so.1
       s390x             linux-vdso64.so.1
       sh                linux-gate.so.1
       i386              linux-gate.so.1
       x86-64            linux-vdso.so.1
       x86/x32           linux-vdso.so.1

   strace(1), seccomp(2) et le vDSO
       Lors du suivi des appels système avec strace(1), les symboles (appels  système)  qui  sont
       exportés  par  le  vDSO  n’apparaîtront  pas  dans la sortie du suivi. De même, ces appels
       système ne seront pas visibles par les filtres seccomp(2).

NOTES SPÉCIFIQUES AUX ARCHITECTURES

       Les sous-sections suivantes fournissent des notes spécifiques  aux  architectures  sur  le
       vDSO.

       Remarquez  que le vDSO utilisé est basé sur l’ABI du code en espace utilisateur et non sur
       l’ABI du noyau. Ainsi, par exemple, si vous exécutez un binaire  ELF  32 bits  i386,  vous
       obtiendrez  le  même vDSO que vous l’exécutiez avec un noyau 32 bits i386 ou avec un noyau
       64 bits x86_64. Par conséquent, le nom de l’ABI en espace utilisateur devrait être utilisé
       pour déterminer la section suivante adéquate.

   Fonctions ARM
       Le tableau suivant indique les symboles exportés par le vDSO.

       symbole                version
       ────────────────────────────────────────────────────────────
       __vdso_gettimeofday    LINUX_2.6 (exported since Linux 4.1)
       __vdso_clock_gettime   LINUX_2.6 (exported since Linux 4.1)

       De  plus,  le  portage  ARM a une page de code pleine de fonctions utilitaires. Puisque ce
       n’est qu’une page de code brut, aucune information ELF n’existe pour faire la recherche de
       symboles  ou  le  versionnage.  Elle  fournit cependant une prise en charge pour plusieurs
       versions.

       Pour des renseignements sur cette page de code, mieux vaut consulter la  documentation  du
       noyau  puisqu’elle  est  extrêmement  détaillée  et couvre tous ce que vous devez savoir :
       Documentation/arm/kernel_user_helpers.rst.

   Fonctions aarch64
       Le tableau suivant indique les symboles exportés par le vDSO.

       symbole                  version
       ──────────────────────────────────────
       __kernel_rt_sigreturn    LINUX_2.6.39
       __kernel_gettimeofday    LINUX_2.6.39
       __kernel_clock_gettime   LINUX_2.6.39
       __kernel_clock_getres    LINUX_2.6.39

   Fonctions bfin (Blackfin) (portage supprimé dans Linux 4.17)
       Comme ce processeur n’a pas d’unité de gestion mémoire (MMU), il ne définit pas de vDSO au
       sens  usuel.  À  la place, il projette au démarrage quelques fonctions brutes à un endroit
       spécifique de la  mémoire.  Les  applications  en  espace  utilisateur  appellent  ensuite
       directement  dans  cette  zone.  Aucune mesure de rétrocompatibilité n’est prise à part en
       sniffant les codes opératoires bruts, mais comme il s’agit d’un  processeur  embarqué,  il
       peut  s’en  sortir  impunément  – certains  formats d’objet qu’il exécute ne sont même pas
       basés sur ELF (ils sont bFLT/FLAT).

       Pour des renseignements sur cette page de code,  mieux  vaut  consulter  la  documentation
       publique :
       http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:fixed-code

   Fonctions mips
       Le tableau suivant indique les symboles exportés par le vDSO.

       symbole                  version
       ──────────────────────────────────────────────────────────────────
       __kernel_gettimeofday    LINUX_2.6 (exportation depuis Linux 4.4)
       __kernel_clock_gettime   LINUX_2.6 (exportation depuis Linux 4.4)

   Fonctions ia64 (Itanium)
       Le tableau suivant indique les symboles exportés par le vDSO.

       symbole                      version
       ───────────────────────────────────────
       __kernel_sigtramp            LINUX_2.5
       __kernel_syscall_via_break   LINUX_2.5
       __kernel_syscall_via_epc     LINUX_2.5

       Le  portage  Itanium  est  un  peu  périlleux.  En  plus du vDSO ci-dessus, il a aussi des
       « appels système légers » (aussi appelés « appels  système  rapides »  ou  « fsys »).  Ils
       peuvent  être  appelés  à  l’aide de l’assistant vDSO __kernel_syscall_via_epc. Les appels
       système indiqués ici ont la même sémantique que si vous les appeliez directement à  l’aide
       de  syscall(2),  donc  consultez  la  documentation  adéquate  pour chacun d’entre eux. Le
       tableau suivant indique les fonctions disponibles par ce mécanisme.

       fonction
       ────────────────
       clock_gettime
       getcpu
       getpid
       getppid
       gettimeofday
       set_tid_address

   Fonctions parisc (hppa)
       Le portage parisc à une page de code pleine de  fonctions  utilitaires  appelée  une  page
       passerelle. Plutôt que d’utiliser l’approche classique du vecteur auxiliaire ELF, il passe
       l’adresse de la page au processus à l’aide du registre SR2. Les permissions  sur  la  page
       sont  telles qu’exécuter simplement ces adresses s’exécute automatiquement avec les droits
       du noyau et pas en espace utilisateur.  C’est  ainsi  afin  de  correspondre  au  mode  de
       fonctionnement HP-UX.

       Puisque  ce  n’est qu’une page de code brut, aucune information ELF n’existe pour faire la
       recherche de symboles ou le versionnage. Appelez simplement l’adresse adéquate à l’aide de
       l’instruction de branche, par exemple :

           ble <offset>(%sr2, %r0)

       offset   fonction
       ───────────────────────────────────────────────────
       00b0     lws_entry (opérations CAS)
       00e0     set_thread_pointer (utilisé par la glibc)
       0100     linux_gateway_entry (syscall)

   Fonctions ppc/32
       Le  tableau suivant indique les symboles exportés par le vDSO. Les fonctions marquées avec
       un * ne sont disponibles que si le noyau est PowerPC64 (64 bits).

       symbole                    version
       ────────────────────────────────────────
       __kernel_clock_getres      LINUX_2.6.15
       __kernel_clock_gettime     LINUX_2.6.15
       __kernel_clock_gettime64   LINUX_5.11
       __kernel_datapage_offset   LINUX_2.6.15
       __kernel_get_syscall_map   LINUX_2.6.15
       __kernel_get_tbfreq        LINUX_2.6.15
       __kernel_getcpu *          LINUX_2.6.15
       __kernel_gettimeofday      LINUX_2.6.15
       __kernel_sigtramp_rt32     LINUX_2.6.15
       __kernel_sigtramp32        LINUX_2.6.15
       __kernel_sync_dicache      LINUX_2.6.15
       __kernel_sync_dicache_p5   LINUX_2.6.15

       Avant Linux 5.6, les horloges CLOCK_REALTIME_COARSE et CLOCK_MONOTONIC_COARSE ne sont  pas
       prises  en  charge  par les interfaces __kernel_clock_getres et __kernel_clock_gettime. Le
       noyau a recours à l’appel système réel.

   Fonctions ppc/64
       Le tableau suivant indique les symboles exportés par le vDSO.

       symbole                    version
       ────────────────────────────────────────
       __kernel_clock_getres      LINUX_2.6.15
       __kernel_clock_gettime     LINUX_2.6.15
       __kernel_datapage_offset   LINUX_2.6.15

       __kernel_get_syscall_map   LINUX_2.6.15
       __kernel_get_tbfreq        LINUX_2.6.15
       __kernel_getcpu            LINUX_2.6.15
       __kernel_gettimeofday      LINUX_2.6.15
       __kernel_sigtramp_rt64     LINUX_2.6.15
       __kernel_sync_dicache      LINUX_2.6.15
       __kernel_sync_dicache_p5   LINUX_2.6.15

       Avant Linux 4.16, les horloges CLOCK_REALTIME_COARSE et CLOCK_MONOTONIC_COARSE ne sont pas
       prises  en  charge  par les interfaces __kernel_clock_getres et __kernel_clock_gettime. Le
       noyau a recours à l’appel système réel.

   Fonctions riscv
       Le tableau suivant indique les symboles exportés par le vDSO.

       symbole                version
       ──────────────────────────────────
       __vdso_rt_sigreturn    LINUX_4.15
       __vdso_gettimeofday    LINUX_4.15
       __vdso_clock_gettime   LINUX_4.15
       __vdso_clock_getres    LINUX_4.15
       __vdso_getcpu          LINUX_4.15
       __vdso_flush_icache    LINUX_4.15

   Fonctions s390
       Le tableau suivant indique les symboles exportés par le vDSO.

       symbole                  version
       ──────────────────────────────────────
       __kernel_clock_getres    LINUX_2.6.29
       __kernel_clock_gettime   LINUX_2.6.29
       __kernel_gettimeofday    LINUX_2.6.29

   Fonctions s390x
       Le tableau suivant indique les symboles exportés par le vDSO.

       symbole                  version
       ──────────────────────────────────────
       __kernel_clock_getres    LINUX_2.6.29
       __kernel_clock_gettime   LINUX_2.6.29
       __kernel_gettimeofday    LINUX_2.6.29

   Fonctions sh (SuperH)
       Le tableau suivant indique les symboles exportés par le vDSO.

       symbole                 version
       ──────────────────────────────────
       __kernel_rt_sigreturn   LINUX_2.6
       __kernel_sigreturn      LINUX_2.6
       __kernel_vsyscall       LINUX_2.6

   Fonctions i386
       Le tableau suivant indique les symboles exportés par le vDSO.

       symbole                 version
       ──────────────────────────────────────────────────────────────────
       __kernel_sigreturn      LINUX_2.5
       __kernel_rt_sigreturn   LINUX_2.5
       __kernel_vsyscall       LINUX_2.5
       __vdso_clock_gettime    LINUX_2.6 (exportation depuis Linux 3.15)
       __vdso_gettimeofday     LINUX_2.6 (exportation depuis Linux 3.15)
       __vdso_time             LINUX_2.6 (exportation depuis Linux 3.15)

   Fonctions x86-64
       Le tableau suivant indique les symboles exportés par le vDSO. Tous ces symboles sont aussi
       disponibles  sans  le préfixe « __vdso_ », mais vous devriez les ignorer et vous cantonner
       aux noms suivants.

       symbole                version
       ─────────────────────────────────
       __vdso_clock_gettime   LINUX_2.6
       __vdso_getcpu          LINUX_2.6
       __vdso_gettimeofday    LINUX_2.6
       __vdso_time            LINUX_2.6

   Fonctions x86/x32
       Le tableau suivant indique les symboles exportés par le vDSO.

       symbole                version
       ─────────────────────────────────
       __vdso_clock_gettime   LINUX_2.6
       __vdso_getcpu          LINUX_2.6
       __vdso_gettimeofday    LINUX_2.6
       __vdso_time            LINUX_2.6

   Historique
       Le vDSO n’était à l’origine qu’une seule fonction — le vsyscall. Dans les anciens  noyaux,
       ce  nom  pourrait  être  vu  dans  une  projection  en  mémoire de processus à la place de
       « vdso ». Le temps passant, les gens ont réalisé que ce mécanisme était un excellent moyen
       pour  passer plus de fonctionnalités à l’espace utilisateur, il a donc été reconçu en tant
       que vDSO au format actuel.

VOIR AUSSI

       syscalls(2), getauxval(3), proc(5)

       Les documents, exemples et le code source dans l’arborescence du code source de Linux :

           Documentation/ABI/stable/vdso
           Documentation/ia64/fsys.rst
           Documentation/vDSO/* (contient des exemples d’utilisation du vDSO)

       find arch/ -iname '*vdso*' -o -iname '*gate*'

TRADUCTION

       La traduction française de cette  page  de  manuel  a  été  créée  par  Christophe  Blaess
       <https://www.blaess.fr/christophe/>,  Stéphan  Rafin  <stephan.rafin@laposte.net>, Thierry
       Vignaud <tvignaud@mandriva.com>, François Micaux, Alain  Portal  <aportal@univ-montp2.fr>,
       Jean-Philippe    Guérard   <fevrier@tigreraye.org>,   Jean-Luc   Coulon   (f5ibh)   <jean-
       luc.coulon@wanadoo.fr>,   Julien    Cristau    <jcristau@debian.org>,    Thomas    Huriaux
       <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin
       Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>,  Denis
       Barbier  <barbier@debian.org>,  David  Prévot <david@tilapin.org> et Jean-Paul Guillonneau
       <guillonneau.jeanpaul@free.fr>

       Cette traduction est une documentation libre ; veuillez vous reporter  à  la  GNU  General
       Public   License   version 3  ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩  concernant  les
       conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

       Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un
       message à ⟨debian-l10n-french@lists.debian.org⟩.