Provided by: manpages-fr-dev_4.19.0-7_all bug

NOM

       dl_iterate_phdr - Parcourir une liste d'objets partagés

BIBLIOTHÈQUE

       Bibliothèque C standard (libc, -lc)

SYNOPSIS

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

       int dl_iterate_phdr(
                 int (*callback)(struct dl_phdr_info *info,
                                 size_t size, void *data),
                 void *data);

DESCRIPTION

       La  fonction  dl_iterate_phdr()  permet  à  une  application  de  s'informer,  lors de son
       exécution, des objets partagés qu'elle a chargés et de l'ordre dans  lequel  ils  ont  été
       chargés.

       La fonction dl_iterate_phdr() parcourt la liste des objets partagés par une application et
       appelle la fonction callback sur chaque objet jusqu'à ce  que  tous  les  objets  partagés
       aient été traités ou que la fonction callback ait renvoyé une valeur non nulle.

       Chaque  appel  de  callback  prend  trois  paramètres :  info qui est un pointeur vers une
       structure contenant des informations sur les objets partagés ; size qui est la  taille  de
       la  structure  pointée par info ; et data qui est une copie de toute valeur qui est passée
       par le programme appelant dans le second argument (également nommé data) lors  de  l'appel
       de dl_iterate_phdr().

       L'argument info est une structure du type suivant :

           struct dl_phdr_info {
               ElfW(Addr)        dlpi_addr;  /* Adresse de base de l'objet */
               const char       *dlpi_name;  /* Nom de l'objet (terminé par
                                                l'octet NULL final */
               const ElfW(Phdr) *dlpi_phdr;  /* Pointeur vers un tableau des
                                                en-têtes ELF du programme
                                                de cet objet */
               ElfW(Half)        dlpi_phnum; /* Nombre d'éléments dans
                                                dlpi_phdr */

               /* Les champs suivants ont été ajoutés dans la version 2.4 de la glibc, après
                  que la première version de cette structure a été disponible. Vérifier
                  le paramètre size passé à l'appel dl_iterate_phdr pour déterminer
                  si le dernier membre est ou non disponible. */

               unsigned long long dlpi_adds;
                               /* Incrémenté lorsqu'un nouvel objet
                                  peut avoir été ajouté. */
               unsigned long long dlpi_subs;
                               /* Incrémenté lorsqu'un objet peut
                                  avoir été supprimé. */
               size_t dlpi_tls_modid;
                               /* S'il y a un segment PT_TLS, son ID de module comme
                                  utilisé par les relocalisations TLS, zéro sinon. */
               void  *dlpi_tls_data;
                               /* L'adresse dans l'instance du thread appelant
                                  de ce segment PT_TLS du module, s'il en a un
                                  et s'il a été alloué dans le thread appelant,
                                  un pointeur NULL sinon. */
           };

       La  macro  ElfW()  convertit  son  argument  en  un  nom  de  type de données ELF adapté à
       l'architecture matérielle. Par exemple, sur un système 32 bits, ElfW(Addr) produit le type
       de  données  nommé Elf32_Addr. Des informations supplémentaires sur ces types peuvent être
       trouvées dans les fichiers d'en-tête <elf.h> et <link.h>.

       Le champ dlpi_addr indique l'adresse de base  de  l'objet  partagé  (la  différence  entre
       l'adresse  en  mémoire  virtuelle de l'objet partagé et le décalage avec cet objet dans le
       fichier depuis lequel il a été chargé). Le champ dlpi_name est une  chaîne  de  caractères
       terminée  par  un  caractère nul indiquant le chemin à partir duquel l'objet partagé a été
       chargé.

       Pour comprendre le sens des champs dlpi_phdr et dlpi_phnum, il faut se rendre  compte  que
       les  objets  partagés  ELF  sont  constitué  d'un certain nombre de segments, chacun d'eux
       possédant un en-tête décrivant le segment. Le champ dlpi_phdr  est  un  pointeur  vers  un
       tableau  des en-têtes du programme de cet objet partagé. Le champ dlpi_phnum est la taille
       de ce tableau.

       Ces en-têtes de programme sont structurés sous la forme suivantes :

           typedef struct
             {
               Elf32_Word  p_type;    /* Type de segment */
               Elf32_Off   p_offset;  /* Décalage du fichier de segment (?) */
               Elf32_Addr  p_vaddr;   /* Adresse virtuelle du segment */
               Elf32_Addr  p_paddr;   /* Adresse physique du segment */
               Elf32_Word  p_filesz;  /* Taille du segment dans le fichier */
               Elf32_Word  p_memsz;   /* Taille du segment en mémoire */
               Elf32_Word  p_flags;   /* Drapeau du segment */
               Elf32_Word  p_align;   /* Alignement du segment */
           } Elf32_Phdr;

       Notez que la position en mémoire virtuelle d'un en-tête de programme, x, est calculée avec
       la formule suivante :

           addr == info->dlpi_addr + info->dlpi_phdr[x].p_vaddr;

       Les  valeurs  possibles  pour  p_type  incluent  les  suivantes (voir <elf.h> pour plus de
       détails) :

           #define PT_LOAD         1    /* Segment de programme chargeable */
           #define PT_DYNAMIC      2    /* Information d'édition de liens dynamiques */
           #define PT_INTERP       3    /* Interpréteur de programme */
           #define PT_NOTE         4    /* Information auxiliaire */
           #define PT_SHLIB        5    /* Réservé */
           #define PT_PHDR         6    /* Entrée pour la table d'en-tête elle même */
           #define PT_TLS          7    /* Segment de stockage local au thread */
           #define PT_GNU_EH_FRAME 0x6474e550 /* Segment GCC .eh_frame_hdr */
           #define PT_GNU_STACK  0x6474e551 /* Indique l'exécutabilité de la pile */
           #define PT_GNU_RELRO  0x6474e552 /* Lecture seule après relocalisation */

VALEUR RENVOYÉE

       La fonction dl_iterate_phdr() renvoie n'importe quelle  valeur  renvoyée  par  le  dernier
       appel à callback.

VERSIONS

       dl_iterate_phdr() est géré depuis la glibc 2.2.4.

ATTRIBUTS

       Pour une explication des termes utilisés dans cette section, consulter attributes(7).

       ┌────────────────────────────────────────────────────────┬──────────────────────┬─────────┐
       │InterfaceAttributValeur  │
       ├────────────────────────────────────────────────────────┼──────────────────────┼─────────┤
       │dl_iterate_phdr()                                       │ Sécurité des threads │ MT-Safe │
       └────────────────────────────────────────────────────────┴──────────────────────┴─────────┘

STANDARDS

       La  fonction  dl_iterate_phdr()  n'est  spécifiée  par  aucune  norme.  De nombreux autres
       systèmes fournissent une version de cette fonction bien que les détails  de  la  structure
       dl_phdr_info  soient  différents.  Sur  les BSD et Solaris, la structure inclut les champs
       dlpi_addr, dlpi_name, dlpi_phdr et dlpi_phnum en plus d'autres champs spécifiques à chaque
       implémentation.

NOTES

       Les  futures  versions de la bibliothèque C peuvent ajouter d'autres champs à la structure
       dl_phdr_info ; dans ce cas, l'argument size fournit un  mécanisme  pour  que  la  fonction
       appelée sache si elle est exécutée sur un système possédant des champs supplémentaires.

       Le  premier  objet  visité  par callback est le programme principal. Pour ce programme, le
       champ dlpi_name est une chaîne de caractères vide.

EXEMPLES

       Le programme suivant affiche la liste des chemins des objets partagés qu'il a chargé. Pour
       chaque  objet  partagé,  le  programme  liste  plusieurs  informations (adresse virtuelle,
       taille, drapeaux et type) pour chacun des segments des objets ELF.

       La session shell suivante montre la sortie produite sur  un  système  x86-64.  Le  premier
       objet  partagé pour lequel une sortie est affichée (où le nom est une chaîne de caractères
       vide) est le programme principal.

           $ ./a.out
           Name: "" (9 segments)
                0: [      0x400040; memsz:    1f8] flags: 0x5; PT_PHDR
                1: [      0x400238; memsz:     1c] flags: 0x4; PT_INTERP
                2: [      0x400000; memsz:    ac4] flags: 0x5; PT_LOAD
                3: [      0x600e10; memsz:    240] flags: 0x6; PT_LOAD
                4: [      0x600e28; memsz:    1d0] flags: 0x6; PT_DYNAMIC
                5: [      0x400254; memsz:     44] flags: 0x4; PT_NOTE
                6: [      0x400970; memsz:     3c] flags: 0x4; PT_GNU_EH_FRAME
                7: [         (nil); memsz:      0] flags: 0x6; PT_GNU_STACK
                8: [      0x600e10; memsz:    1f0] flags: 0x4; PT_GNU_RELRO
           Name: "linux-vdso.so.1" (4 segments)
                0: [0x7ffc6edd1000; memsz:    e89] flags: 0x5; PT_LOAD
                1: [0x7ffc6edd1360; memsz:    110] flags: 0x4; PT_DYNAMIC
                2: [0x7ffc6edd17b0; memsz:     3c] flags: 0x4; PT_NOTE
                3: [0x7ffc6edd17ec; memsz:     3c] flags: 0x4; PT_GNU_EH_FRAME
           Name: "/lib64/libc.so.6" (10 segments)
                0: [0x7f55712ce040; memsz:    230] flags: 0x5; PT_PHDR
                1: [0x7f557145b980; memsz:     1c] flags: 0x4; PT_INTERP
                2: [0x7f55712ce000; memsz: 1b6a5c] flags: 0x5; PT_LOAD
                3: [0x7f55716857a0; memsz:   9240] flags: 0x6; PT_LOAD
                4: [0x7f5571688b80; memsz:    1f0] flags: 0x6; PT_DYNAMIC
                5: [0x7f55712ce270; memsz:     44] flags: 0x4; PT_NOTE
                6: [0x7f55716857a0; memsz:     78] flags: 0x4; PT_TLS
                7: [0x7f557145b99c; memsz:   544c] flags: 0x4; PT_GNU_EH_FRAME
                8: [0x7f55712ce000; memsz:      0] flags: 0x6; PT_GNU_STACK
                9: [0x7f55716857a0; memsz:   3860] flags: 0x4; PT_GNU_RELRO
           Name: "/lib64/ld-linux-x86-64.so.2" (7 segments)
                0: [0x7f557168f000; memsz:  20828] flags: 0x5; PT_LOAD
                1: [0x7f55718afba0; memsz:   15a8] flags: 0x6; PT_LOAD
                2: [0x7f55718afe10; memsz:    190] flags: 0x6; PT_DYNAMIC
                3: [0x7f557168f1c8; memsz:     24] flags: 0x4; PT_NOTE
                4: [0x7f55716acec4; memsz:    604] flags: 0x4; PT_GNU_EH_FRAME
                5: [0x7f557168f000; memsz:      0] flags: 0x6; PT_GNU_STACK
                6: [0x7f55718afba0; memsz:    460] flags: 0x4; PT_GNU_RELRO

   Source du programme

       #define _GNU_SOURCE
       #include <link.h>
       #include <stdint.h>
       #include <stdio.h>
       #include <stdlib.h>

       static int
       callback(struct dl_phdr_info *info, size_t size, void *data)
       {
           char *type;
           int p_type;

           printf("Nom : \"%s\" (%d segments)\n", info->dlpi_name,
                      info->dlpi_phnum);

           for (size_t j = 0; j < info->dlpi_phnum; j++) {
               p_type = info->dlpi_phdr[j].p_type;
               type =  (p_type == PT_LOAD) ? "PT_LOAD" :
                       (p_type == PT_DYNAMIC) ? "PT_DYNAMIC" :
                       (p_type == PT_INTERP) ? "PT_INTERP" :
                       (p_type == PT_NOTE) ? "PT_NOTE" :
                       (p_type == PT_INTERP) ? "PT_INTERP" :
                       (p_type == PT_PHDR) ? "PT_PHDR" :
                       (p_type == PT_TLS) ? "PT_TLS" :
                       (p_type == PT_GNU_EH_FRAME) ? "PT_GNU_EH_FRAME" :
                       (p_type == PT_GNU_STACK) ? "PT_GNU_STACK" :
                       (p_type == PT_GNU_RELRO) ? "PT_GNU_RELRO" : NULL;

               printf("    %2zu : [%14p ; taille mémoire :%7jx] drapeaux : %#jx; ", j,
                       (void *) (info->dlpi_addr + info->dlpi_phdr[j].p_vaddr),
                       (uintmax_t) info->dlpi_phdr[j].p_memsz,
                       (uintmax_t) info->dlpi_phdr[j].p_flags);
               if (type != NULL)
                   printf("%s\n", type);
               else
                   printf("[autre (%#x)]\n", p_type);
           }

           return 0;
       }

       int
       main(void)
       {
           dl_iterate_phdr(callback, NULL);

           exit(EXIT_SUCCESS);
       }

VOIR AUSSI

       ldd(1), objdump(1), readelf(1), dladdr(3), dlopen(3), elf(5), ld.so(8)

       « Executable and Linking Format Specification » disponible en ligne à divers endroits.

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  Grégoire  Scano
       <gregoire.scano@malloc.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⟩.