Man page - dl_iterate_phdr(3)

Packages contains this manual

Available languages:

en fr ja ru

Manual

dl_iterate_phdr

NOM
BIBLIOTHÈQUE
SYNOPSIS
DESCRIPTION
VALEUR RENVOYÉE
ATTRIBUTS
VERSIONS
STANDARDS
HISTORIQUE
NOTES
EXEMPLES
Source du programme
VOIR AUSSI
TRADUCTION

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

Image grohtml-3877305-1.png

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 .