Provided by: manpages-fr-dev_4.27.0-1_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.

ATTRIBUTS

       Pour une explication des termes utilisés dans cette section, consulter attributes(7).
       ┌──────────────────────────────────────────────────────────────────────┬──────────────────────┬─────────┐
       │ InterfaceAttributValeur  │
       ├──────────────────────────────────────────────────────────────────────┼──────────────────────┼─────────┤
       │ dl_iterate_phdr()                                                    │ Sécurité des threads │ MT-Safe │
       └──────────────────────────────────────────────────────────────────────┴──────────────────────┴─────────┘

VERSIONS

       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.

       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.

STANDARDS

       Aucune.

HISTORIQUE

       glibc 2.2.4.

NOTES

       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("Name: \"%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; memsz:%7jx] flags: %#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("[other (%#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 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.

Pages du manuel de Linux 6.9.1                    15 juin 2024                                dl_iterate_phdr(3)