Provided by: manpages-fr-dev_4.15.0-9_all bug

NOM

       mremap - Modifier une projection de la mémoire virtuelle

SYNOPSIS

       #define _GNU_SOURCE         /* Consultez feature_test_macros(7) */
       #include <sys/mman.h>

       void *mremap(void *old_address, size_t old_size,
                    size_t new_size, int flags, ... /* void *new_address */);

DESCRIPTION

       mremap()  agrandit  (ou  diminue)  une  projection (Ndt : mapping) de mémoire virtuelle en
       mémoire réelle, en la déplaçant éventuellement (sous contrôle de l'argument flags et de la
       place disponible dans l'espace d'adressage virtuel).

       old_address  est  l'ancienne  adresse  du  bloc  de  mémoire  virtuelle  à  agrandir (ou à
       diminuer). Veuillez noter que old_address doit être alignée sur  une  frontière  de  page.
       old_size  est  l'ancienne  taille  du  bloc  de  mémoire virtuelle. new_size est la taille
       désirée pour le  nouveau  bloc  de  mémoire.  Un  cinquième  argument,  new_address,  peut
       éventuellement être fourni ; voyez la description de MREMAP_FIXED ci-dessous.

       Si  la  valeur  de  old_size  est  de  zéro  et  si  old_address  renvoie à une projection
       partageable (voir MAP_SHARED de mmap(2)), mremap()  créera  une  nouvelle  projection  des
       mêmes  pages.  new_size  sera  la  taille de la nouvelle projection et l'emplacement de la
       nouvelle  projection  peut  être  indiqué  avec  new_address ;  voir  la  description   de
       MREMAP_FIXED  ci-dessous.  Si  une  nouvelle  projection  est  demandée  à l'aide de cette
       méthode, l'attribut MREMAP_MAYMOVE doit être indiqué également.

       L'argument de masquage flags est soit 0, soit un des attributs suivants :

       MREMAP_MAYMOVE
              Par défaut, s'il n'y a pas suffisamment d'espace pour agrandir une projection à son
              emplacement  actuel,  mremap()  échoue.  Si  ce  drapeau  est utilisé, le noyau est
              autorisé à déplacer la projection à une autre adresse virtuelle si  nécessaire.  Si
              la  projection  est  déplacée,  les  pointeurs  absolus  vers l'ancienne projection
              deviennent caduques (il faut utiliser des décalages  par  rapport  à  l'adresse  de
              début de la projection).

       MREMAP_FIXED (depuis Linux 2.3.31)
              Ce  drapeau a un but similaire à MAP_FIXED pour mmap(2). S'il est utilisé, mremap()
              prend un cinquième argument void *new_address qui contient une adresse alignée  sur
              un  début  de page vers laquelle la projection doit être déplacée. Toute projection
              existant précédemment dans la zone entre new_address et new_size est supprimée.

              Si MREMAP_FIXED est indiqué, MREMAP_MAYMOVE doit également être indiqué.

       MREMAP_DONTUNMAP (depuis Linux 5.7)
              Cet attribut, qui doit être utilisé avec MREMAP_MAYMOVE, refait une projection vers
              une nouvelle adresse mais il ne supprime pas celle à old_address.

              L'attribut  MREMAP_DONTUNMAP  ne  peut être utilisé qu'avec des projections privées
              anonymes (voir la description de MAP_PRIVATE et de MAP_ANONYMOUS dans mmap(2)).

              À la fin, tous les accès à la plage indiquée par old_address et old_size  donneront
              une  erreur  de  pagination.  Elle sera gérée par un gestionnaire userfaultfd(2) si
              l'adresse se situe dans une plage  précédemment  enregistrée  avec  userfaultfd(2).
              Sinon, le noyau alloue une page remplie de zéros pour gérer cette erreur.

              L'attribut MREMAP_DONTUNMAP peut être utilisé pour déplacer de manière atomique une
              projection  tout  en  laissant  la  source  associée.  Voir  les  NOTES  pour   des
              applications possibles de MREMAP_DONTUNMAP.

       Si  le segment de mémoire indiqué par old_address et old_size est verrouillé (par mlock(2)
       ou similaire), ce verrou est maintenu quand le segment  est  modifié  et/ou  déplacé.  Par
       conséquent, la quantité de mémoire verrouillée par le processus peut changer.

VALEUR RENVOYÉE

       On success mremap()  returns a pointer to the new virtual memory area. On error, the value
       MAP_FAILED (that is, (void *) -1) is returned, and errno is set to indicate the error.

ERREURS

       EAGAIN L'appelant a  tenté  d'agrandir  un  segment  de  mémoire  verrouillé,  mais  c'est
              impossible sans dépasser la limite RLIMIT_MEMLOCK.

       EFAULT Une  adresse  dans l'intervalle entre old_address et old_address+old_size n'est pas
              une adresse virtuelle valable pour ce processus. On peut également  obtenir  EFAULT
              même s'il existe des projections recouvrant la zone complète demandée, mais que ces
              projections sont de types différents.

       EINVAL Un paramètre non valable a été donné. Parmi les causes possibles :

              –  old_address n'était pas aligné sur une page ;

              –  une autre valeur que MREMAP_MAYMOVE,  MREMAP_FIXED  ou  MREMAP_DONTUNMAP  a  été
                 indiquée dans flags ;

              –  new_size était zéro ;

              –  new_size ou new_address n'était pas valable ;

              –  la  nouvelle  plage  d'adresses  indiquée  par new_address et new_size chevauche
                 l'ancienne plage d'adresses indiquée par old_address et old_size ;

              –  MREMAP_FIXED ou MREMAP_DONTUNMAP était indiqué sans MREMAP_MAYMOVE ;

              –  MREMAP_DONTUNMAP était indiqué mais une ou plusieurs pages de la plage  indiquée
                 par old_address et old_size n'étaient pas privées et anonymes ;

              –  MREMAP_DONTUNMAP était indiqué et old_size n'était pas égal à new_size ;

              –  old_size  était  de  zéro  et  old_address  ne  renvoie  pas  à  une  projection
                 partageable (mais voir BOGUES) ;

              –  old_size valait zéro et l'attribut MREMAP_MAYMOVE n'était pas indiqué.

       ENOMEM Pas assez de mémoire disponible pour terminer  l'opération.  Les  causes  possibles
              sont :

              –  La  zone de mémoire ne peut pas être agrandie à l'emplacement virtuel actuel, et
                 l'option MREMAP_MAYMOVE n'a pas été fournie dans flags. Ou encore, il n'y a plus
                 assez de mémoire (virtuelle) disponible.

              –  MREMAP_DONTUNMAP a été utilisé, provoquant la création d'une nouvelle projection
                 qui dépasserait la mémoire (virtuelle) disponible. Ou alors elle  excéderait  le
                 nombre maximal de projections autorisées.

CONFORMITÉ

       Cet  appel  système  est  spécifique  à  Linux  et  ne  devrait  pas être employé dans des
       programmes destinés à être portables.

NOTES

       mremap() modifie la correspondance entre les adresses virtuelles et les pages de  mémoire.
       Ce mécanisme peut être utilisé pour implémenter un realloc(3) très efficace.

       Sous  Linux,  la  mémoire  est  divisée en pages. Un processus utilisateur dispose d'un ou
       plusieurs segments linéaires de mémoire virtuelle. À  chaque  segment  correspond  une  ou
       plusieurs  projections  dans les pages de mémoire réelle (dans la table des pages). Chaque
       segment de mémoire virtuelle dispose de ses propres droits d'accès (sa protection), ce qui
       peut  déclencher des fautes de segmentation (SIGSEGV) si l'accès à la mémoire est mal géré
       (par exemple, en écrivant dans un segment  en  lecture  seule).  De  même,  une  tentative
       d'accès à la mémoire en dehors des segments déclenche une faute de segmentation.

       Si  mremap()  est  utilisé  pour déplacer ou étendre une zone verrouillée avec mlock(2) ou
       équivalent, l'appel mremap() fera le  maximum  pour  remplir  la  nouvelle  zone  mais  il
       n'échouera pas avec ENOMEM si la zone ne peut pas être remplie.

       Avant  la  version 2.4,  la  glibc  ne fournissait pas la définition de MREMAP_FIXED et le
       prototype de mremap() ne permettait pas de passer le paramètre new_address.

   Cas d'utilisation de MREMAP_DONTUNMAP
       Parmi les applications possibles de MREMAP_DONTUNMAP :

       –  userfaultfd(2) non coopératif : une  application  peut  retirer  une  plage  d'adresses
          virtuelles  en utilisant MREMAP_DONTUNMAP, puis utiliser un gestionnaire userfaultfd(2)
          pour gérer les erreurs de pagination qui arrivent ensuite lorsque d'autres  threads  du
          processus créent des pages dans la plage retirée.

       –  Récupérateur  de  mémoire : MREMAP_DONTUNMAP peut être utilisé avec userfaultfd(2) pour
          implémenter des algorithmes de ramasse-miettes (garbage  collection)  (comme  dans  une
          machine  virtuelle  Java).  Une  telle implémentation peut être moins coûteuse (et plus
          simple) que les techniques de collecte traditionnelles qui impliquent  de  marquer  des
          pages  avec  une  protection PROT_NONE ainsi qu'un gestionnaire SIGSEGV pour capter les
          accès à ces pages.

BOGUES

       Avant Linux 4.14, si old_size valait  zéro  et  si  la  projection  à  laquelle  renvoyait
       old_address  était  une  projection  privée  (MAP_PRIVATE de mmap(2)), mremap() créait une
       nouvelle  projection  privée  sans  lien  avec  celle  d'origine.  Ce  comportement  était
       intentionnel  et  probablement  non  prévu  dans  des applications de l'espace utilisateur
       (l'intention de mremap() étant  de  créer  une  nouvelle  projection  à  partir  de  celle
       d'origine). Depuis Linux 4.14, mremap() échoue avec l'erreur EINVAL dans ce scénario.

VOIR AUSSI

       brk(2), getpagesize(2), getrlimit(2), mlock(2), mmap(2), sbrk(2), malloc(3), realloc(3)

       Votre   manuel   favori  à  propos  de  systèmes  d'exploitation,  pour  des  informations
       supplémentaires sur la mémoire paginée (par exemple Modern Operating Systems de Andrew  S.
       Tanenbaum,  Inside  Linux par Randolf Bentson, The Design of the UNIX Operating System par
       Maurice J. Bach)

COLOPHON

       Cette page fait partie de la publication 5.13 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-Philippe MENGUAL
       <jpmengual@debian.org>

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