dl_iterate_phdr(3) Library Functions Manual dl_iterate_phdr(3) NOM dl_iterate_phdr - Parcourir une liste d'objets partages BIBLIOTHEQUE Bibliotheque C standard (libc, -lc) SYNOPSIS #define _GNU_SOURCE /* Consultez feature_test_macros(7) */ #include 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 a une application de s'informer, lors de son execution, des objets partages qu'elle a charges et de l'ordre dans lequel ils ont ete charges. La fonction dl_iterate_phdr() parcourt la liste des objets partages par une application et appelle la fonction callback sur chaque objet jusqu'a ce que tous les objets partages aient ete traites ou que la fonction callback ait renvoye une valeur non nulle. Chaque appel de callback prend trois parametres : info qui est un pointeur vers une structure contenant des informations sur les objets partages ; size qui est la taille de la structure pointee par info ; et data qui est une copie de toute valeur qui est passee par le programme appelant dans le second argument (egalement nomme 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 (termine par l'octet NULL final */ const ElfW(Phdr) *dlpi_phdr; /* Pointeur vers un tableau des en-tetes ELF du programme de cet objet */ ElfW(Half) dlpi_phnum; /* Nombre d'elements dans dlpi_phdr */ /* Les champs suivants ont ete ajoutes dans la version 2.4 de la glibc, apres que la premiere version de cette structure a ete disponible. Verifier le parametre size passe a l'appel dl_iterate_phdr pour determiner si le dernier membre est ou non disponible. */ unsigned long long dlpi_adds; /* Incremente lorsqu'un nouvel objet peut avoir ete ajoute. */ unsigned long long dlpi_subs; /* Incremente lorsqu'un objet peut avoir ete supprime. */ size_t dlpi_tls_modid; /* S'il y a un segment PT_TLS, son ID de module comme utilise par les relocalisations TLS, zero 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 ete alloue dans le thread appelant, un pointeur NULL sinon. */ }; La macro ElfW() convertit son argument en un nom de type de donnees ELF adapte a l'architecture materielle. Par exemple, sur un systeme 32 bits, ElfW(Addr) produit le type de donnees nomme Elf32_Addr. Des informations supplementaires sur ces types peuvent etre trouvees dans les fichiers d'en-tete et . Le champ dlpi_addr indique l'adresse de base de l'objet partage (la difference entre l'adresse en memoire virtuelle de l'objet partage et le decalage avec cet objet dans le fichier depuis lequel il a ete charge). Le champ dlpi_name est une chaine de caracteres terminee par un caractere nul indiquant le chemin a partir duquel l'objet partage a ete charge. Pour comprendre le sens des champs dlpi_phdr et dlpi_phnum, il faut se rendre compte que les objets partages ELF sont constitue d'un certain nombre de segments, chacun d'eux possedant un en-tete decrivant le segment. Le champ dlpi_phdr est un pointeur vers un tableau des en-tetes du programme de cet objet partage. Le champ dlpi_phnum est la taille de ce tableau. Ces en-tetes de programme sont structures sous la forme suivantes : typedef struct { Elf32_Word p_type; /* Type de segment */ Elf32_Off p_offset; /* Decalage 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 memoire */ Elf32_Word p_flags; /* Drapeau du segment */ Elf32_Word p_align; /* Alignement du segment */ } Elf32_Phdr; Notez que la position en memoire virtuelle d'un en-tete de programme, x, est calculee avec la formule suivante : addr == info->dlpi_addr + info->dlpi_phdr[x].p_vaddr; Les valeurs possibles pour p_type incluent les suivantes (voir pour plus de details) : #define PT_LOAD 1 /* Segment de programme chargeable */ #define PT_DYNAMIC 2 /* Information d'edition de liens dynamiques */ #define PT_INTERP 3 /* Interpreteur de programme */ #define PT_NOTE 4 /* Information auxiliaire */ #define PT_SHLIB 5 /* Reserve */ #define PT_PHDR 6 /* Entree pour la table d'en-tete elle meme */ #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'executabilite de la pile */ #define PT_GNU_RELRO 0x6474e552 /* Lecture seule apres relocalisation */ VALEUR RENVOYEE La fonction dl_iterate_phdr() renvoie n'importe quelle valeur renvoyee par le dernier appel a callback. ATTRIBUTS Pour une explication des termes utilises dans cette section, consulter attributes(7). +---------------------------------+--------------------------+---------+ |Interface | Attribut | Valeur | +---------------------------------+--------------------------+---------+ |dl_iterate_phdr() | Securite des threads | MT-Safe | +---------------------------------+--------------------------+---------+ VERSIONS De nombreux autres systemes fournissent une version de cette fonction bien que les details de la structure dl_phdr_info soient differents. Sur les BSD et Solaris, la structure inclut les champs dlpi_addr, dlpi_name, dlpi_phdr et dlpi_phnum en plus d'autres champs specifiques a chaque implementation. Les futures versions de la bibliotheque C peuvent ajouter d'autres champs a la structure dl_phdr_info ; dans ce cas, l'argument size fournit un mecanisme pour que la fonction appelee sache si elle est executee sur un systeme possedant des champs supplementaires. STANDARDS Aucune. HISTORIQUE glibc 2.2.4. NOTES Le premier objet visite par callback est le programme principal. Pour ce programme, le champ dlpi_name est une chaine de caracteres vide. EXEMPLES Le programme suivant affiche la liste des chemins des objets partages qu'il a charge. Pour chaque objet partage, 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 systeme x86-64. Le premier objet partage pour lequel une sortie est affichee (ou le nom est une chaine de caracteres 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 #include #include #include 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; 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 a divers endroits. TRADUCTION La traduction francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot et Gregoire Scano Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.06 31 octobre 2023 dl_iterate_phdr(3)