Provided by: manpages-fr_4.13-4_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.txt.

   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_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

       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

       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
       ────────────────────────────────────
       __kernel_rt_sigreturn    LINUX_4.15
       __kernel_gettimeofday    LINUX_4.15
       __kernel_clock_gettime   LINUX_4.15
       __kernel_clock_getres    LINUX_4.15

       __kernel_getcpu          LINUX_4.15
       __kernel_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.txt
           Documentation/vDSO/* (contient des exemples d’utilisation du vDSO)

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

COLOPHON

       Cette page fait partie de la publication 5.10 du projet man-pages Linux. Une description du projet et des
       instructions pour signaler des anomalies et la dernière version de cette page  peuvent  être  trouvées  à
       l'adresse https://www.kernel.org/doc/man-pages/.

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 ⟨⟩.