dlinfo - Obtenir des informations sur un objet chargé dynamiquement
Bibliothèque de liens dynamiques (
libdl,
-ldl)
#define _GNU_SOURCE
#include <link.h>
#include <dlfcn.h>
int dlinfo(void *restrict handle, int request, void *restrict info);
La fonction
dlinfo() obtient des informations sur l'objet chargé
dynamiquement et référencé par
handle
(habituellement obtenu par un appel préalable à
dlopen(3)
ou
dlmopen(3)). Le paramètre
request spécifie
quelle information doit être renvoyée. Le paramètre
info est un pointeur vers un tampon utilisé pour stocker les
informations renvoyées par l'appel ; le type de ce
paramètre dépend de
request.
Les valeurs suivantes sont prises en charge pour
request (avec le type
correspondant pour
info entre parenthèses) :
-
RTLD_DI_LMID (Lmid_t *)
- Récupérer l'identifiant de la liste
d'association des liens (espace de noms) dans lequel handle est
chargé.
-
RTLD_DI_LINKMAP (struct link_map **)
- Récupèrer un pointeur vers la structure
link_map correspondant à handle. Le paramètre
info pointe vers un pointeur sur une structure link_map,
définie dans <link.h> comme :
-
struct link_map {
ElfW(Addr) l_addr; /* Difference entre l'adresse
dans le fichier ELF et
l'adresse en mémoire */
char *l_name; /* Chemin absolu du fichier où
l'objet a été trouvé */
ElfW(Dyn) *l_ld; /* La section dynamique de l'objet
partagé */
struct link_map *l_next, *l_prev;
/* Chaîne des objets chargés */
/* Plus des champs supplémentaires privés
de l'implementation */
};
-
RTLD_DI_ORIGIN (char *)
- Copie le chemin du fichier de l'objet partégé
correspondant à handle vers l'endroit pointé vers
info.
-
RTLD_DI_SERINFO (Dl_serinfo *)
- Obtient les chemins de recherche de bibliothèques
pour un objet partagé indiqué par handle. L'argument
info est un pointeur vers un Dl_serinfo qui contient les
chemins de recherche. Parce que le nombre de chemins de recherche peut
varier, la taille de la structure sur laquelle info pointe peut
aussi varier. La requête RTLD_DI_SERINFOSIZE décrite
ci-dessous permet aux applications de déterminer convenablement la
taille du tampon. L'appelant doit effectur les étapes
suivantes :
- (1)
- Utiliser une requête RTLD_DI_SERINFOSIZE pour
renseigner une structure Dl_serinfo avec la taille
(dls_size) de la structure requise pour la requête
RTLD_DI_SERINFO ultérieure.
- (2)
- Allouer un tampon Dl_serinfo de la bonne taille
(dls_size).
- (3)
- Utiliser un requête RTLD_DI_SERINFOSIZE pour
remplir les champs dls_size et dls_cnt du tampon
alloué à l'étape précédante.
- (4)
- Utiliser un RTLD_DI_SERINFO pour obtenir les chemins
de recherche de bibliothèques.
- La structure Dl_serinfo est définie comme
suit :
-
typedef struct {
size_t dls_size; /* Taille en octets du
tampon entier */
unsigned int dls_cnt; /* Nombre d'éléments
dans 'dls_serpath' */
Dl_serpath dls_serpath[1]; /* En fait plus long,
'dls_cnt' éléments */
} Dl_serinfo;
- Chacun des éléments dls_serpath dans
la structure ci-dessus sont structurés sous la forme
suivantes :
-
typedef struct {
char *dls_name; /* Nom du répertoire de recherche
de chemin de bibliothèque */
unsigned int dls_flags; /* Indique d'où ce
répertoire provient */
} Dl_serpath;
- Le champ dls_flags n'est pas utilisé pour le
moment et contient toujours zéro.
-
RTLD_DI_SERINFOSIZE (Dl_serinfo *)
- Renseigne les champs dls_size et dls_cnt de
la structure Dl_serinfo sur laquelle pointe info avec des
valeurs appropriées pour allouer un tampon pouvant être
utilisé dans une requête RTLD_DI_SERINFO
ultérieure.
-
RTLD_DI_TLS_MODID (size_t *, depuis la
version 2.4 de la glibc)
- Obtient l'identifiant de module du segment TLS (stockage
local au thread) de l'objet partagé, comme utilisé dans les
relocalisations TLS. Si cet objet ne définit pas de segment TLS,
zéro est mis dans *info.
-
RTLD_DI_TLS_DATA (void **, depuis la
version 2.4 de la glibc)
- Obtenir un pointeur au bloc TLS du thread appelant
correspondant au segment TLS des objets partagés. Si cet objet ne
définit pas un segment PT_TLS, ou si le thread appelant ne lui a
pas alloué de bloc, NULL est placé dans *info.
En cas de succès,
dlinfo() renvoie
0. En cas d'erreur, elle
renvoie
-1 ; la cause de l'erreur peut être
diagnostiquée avec
dlerror(3).
dlinfo() est apparue la première fois dans la version 2.3.3
de la glibc.
Pour une explication des termes utilisés dans cette section, consulter
attributes(7).
Interface |
Attribut |
Valeur |
dlinfo() |
Sécurité des threads |
MT-Safe |
Cette fonction est une extension GNU non standard.
Cette fonction dérive de la fonction Solaris de même nom et existe
aussi sur d'autres systèmes. Les ensembles de requêtes prises en
charge par les diverses implémentations ne se recouvrent que
partiellement.
Le programme ci-dessous ouvre un objet partagé en utilisant
dlopen(3) et utilise par la suite les requêtes
RTLD_DI_SERINFOSIZE et
RTLD_DI_SERINFO pour obtenir la liste de
chemin de recherche de bibliothèques pour la bibliothèque. Voici
un exemple de ce qui pourrait être observé lors de
l'exécution du programme :
$ ./a.out /lib64/libm.so.6
dls_serpath[0].dls_name = /lib64
dls_serpath[1].dls_name = /usr/lib64
#define _GNU_SOURCE
#include <dlfcn.h>
#include <link.h>
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
void *handle;
Dl_serinfo serinfo;
Dl_serinfo *sip;
if (argc != 2) {
fprintf(stderr, "Usage : %s <libpath>\n", argv[0]);
exit(EXIT_FAILURE);
}
/* Obtenir un gestionnaire pour l'objet partagé indiqué sur la
ligne de commande. */
handle = dlopen(argv[1], RTLD_NOW);
if (handle == NULL) {
fprintf(stderr, "dlopen() failed: %s\n", dlerror());
exit(EXIT_FAILURE);
}
/* Découvrir la taille du tampon qu'il faut passer à
RTLD_DI_SERINFO. */
if (dlinfo(handle, RTLD_DI_SERINFOSIZE, &serinfo) == -1) {
fprintf(stderr, "RTLD_DI_SERINFOSIZE a échoué : %s\n", dlerror());
exit(EXIT_FAILURE);
}
/* Allouer le tampon pour l'utiliser avec RTLD_DI_SERINFO. */
sip = malloc(serinfo.dls_size);
if (sip == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
/* Initialiser les champs 'dls_size' et 'dls_cnt' fields
dans le tampon nouvellement alloué. */
if (dlinfo(handle, RTLD_DI_SERINFOSIZE, sip) == -1) {
fprintf(stderr, "RTLD_DI_SERINFOSIZE a échoué : %s\n", dlerror());
exit(EXIT_FAILURE);
}
/* Récupérer et afficher la liste de recherche des bibliothques. */
if (dlinfo(handle, RTLD_DI_SERINFO, sip) == -1) {
fprintf(stderr, "RTLD_DI_SERINFO a échoué : %s\n", dlerror());
exit(EXIT_FAILURE);
}
for (size_t j = 0; j < serinfo.dls_cnt; j++)
printf("dls_serpath[%zu].dls_name = %s\n",
j, sip->dls_serpath[j].dls_name);
exit(EXIT_SUCCESS);
}
dl_iterate_phdr(3),
dladdr(3),
dlerror(3),
dlopen(3),
dlsym(3),
ld.so(8)
La traduction française de cette page de manuel a été
créée par Christophe Blaess
<
https://www.blaess.fr/christophe/>, Stéphan Rafin
<
[email protected]>, Thierry Vignaud
<
[email protected]>, François Micaux, Alain Portal
<
[email protected]>, Jean-Philippe Guérard
<
[email protected]>, Jean-Luc Coulon (f5ibh)
<
[email protected]>, Julien Cristau
<
[email protected]>, Thomas Huriaux <
[email protected]>,
Nicolas François <
[email protected]>, Florentin
Duneau <
[email protected]>, Simon Paillard
<
[email protected]>, Denis Barbier
<
[email protected]>, David Prévot <
[email protected]> et
Grégoire Scano <
[email protected]>
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 à
[email protected]