#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);
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 */
| Interface | Attribut | Valeur |
| dl_iterate_phdr() | Sécurité des threads | MT-Safe |
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.
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
« Executable and Linking Format Specification » disponible en ligne à divers endroits.
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 à