dladdr, dladdr1 - Traduire les adresses en informations symboliques
Bibliothèque de liens dynamiques (
libdl,
-ldl)
#define _GNU_SOURCE
#include <dlfcn.h>
int dladdr(const void *addr, Dl_info *info);
int dladdr1(const void *addr, Dl_info *info, void **extra_info,
int flags);
La fonction
dladdr() détermine si l'adresse
spécifiée dans
addr est située dans l'un des
objets partagés chargés par l'application appelante. Si c'est le
cas, alors
dladdr() renvoie des informations sur l'objet partagé
et le symbole qui recouvrent
addr. Cette information est
renvoyée dans une structure
Dl_info :
typedef struct {
const char *dli_fname; /* Chemin du fichier de l'objet partagé
contenant l'adresse */
void *dli_fbase; /* Adresse de base à laquelle l'objet partagé
est chargé */
const char *dli_sname; /* Nom du symbole dont la définition
recouvre addr */
void *dli_saddr; /* Adresse exacte du symbole dont
le nom est dli_sname */
} Dl_info;
Si aucun symbole correspondant à l'adresse
addr ne peut
être trouvé,
dli_sname et
dli_saddr sont
définis à NULL.
La fonction
dladdr1() est comme
dladdr() mais renvoie des
informations additionnelles au moyen du paramètre
extra_info.
Les informations renvoyées dépendent de la valeur
spécifiée dans
flags et qui peut avoir l'une des valeurs
suivantes :
- RTLD_DL_LINKMAP
- Obtient un pointeur vers la table d'association de liens
pour le fichier correspondant. Le paramètre extra_info
pointe vers un pointeur sur une structure link_map
(c'est-à-dire struct link_map **), définie
dans <link.h> comme :
-
struct link_map {
ElfW(Addr) l_addr; /* Différence 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'implémentation */
};
- RTLD_DL_SYMENT
- Obtenir un pointeur vers une entrée de la table de
symboles ELF du symbole correspondant. Le paramètre
extra_info est un pointeur vers un pointeur sur un symbole :
const ElfW(Sym)**. La macro ElfW() convertit son
paramètre en un nom de type de données ELF adapté
à l'architecture matérielle. Par exemple, sur un
système 64 bits, ElfW(Sym) produit le type de
données nommé Elf64_Sym qui est défini dans
<elf.h> comme :
-
typedef struct {
Elf64_Word st_name; /* Nom du symbole */
unsigned char st_info; /* Type et lien du symbole */
unsigned char st_other; /* Visibilité du symbole */
Elf64_Section st_shndx; /* Index de section */
Elf64_Addr st_value; /* Valeur du symbole */
Elf64_Xword st_size; /* Taille du symbole */
} Elf64_Sym;
- Le champ st_name est un index dans la table de
chaînes.
- Le champ st_info encode le type et le lien du
symbole. Le type peut être extrait en utilisant la macro
ELF64_ST_TYPE(st_info) (ou ELF32_ST_TYPE() sur les
plateformes 32 bits) qui retourne une des valeurs
suivantes :
Valeur |
Description |
STT_NOTYPE |
Le type de ce symbole n'est pas défini |
STT_OBJECT |
Ce symbole est associé à un objet de
données |
STT_FUNC |
Ce symbole est associé à un objet de code |
STT_SECTION |
Ce symbole est associé à une section |
STT_FILE |
Le nom de ce symbole est un nom de fichier |
STT_COMMON |
Ce symbole est un objet de données commun |
STT_TLS |
Ce symbole est un objet de données local au thread |
STT_GNU_IFUNC |
Ce symbole est un objet de code indirect |
- La correspondance de symbole peut être extraite du
champ st_info en utilisant la macro ELF64_ST_BIND(st_info)
(ou ELF32_ST_BIND() sur les plateformes 32 bits) et renvoie
l'une des valeurs suivantes :
Valeur |
Description |
STB_LOCAL |
Symbole local |
STB_GLOBAL |
Symbole global |
STB_WEAK |
Symbole faible |
STB_GNU_UNIQUE |
Symbole unique |
- Le champ st_other contient la visibilité du
symbole qui peut être extraite en utilisant la macro
ELF64_ST_VISIBILITY(st_info) (ou ELF32_ST_VISIBILITY() sur
les plateformes 32 bits) et renvoie une des valeurs
suivantes :
Valeur |
Description |
STV_DEFAULT |
Règles de visibilité par défaut du symbole |
STV_INTERNAL |
Classe cachée spécifique au processeur |
STV_HIDDEN |
Le symbole n'est pas disponible dans d'autres modules |
STV_PROTECTED |
Non préemptible, non exporté |
En cas de succès, ces fonctions renvoient une valeur non nulle. Si
l'adresse spécifiée dans
addr peut être mise en
correspondance avec un objet partagé, mais pas vers un symbole dans
l'objet partagé, alors les champs
info->dli_sname et
info->dli_saddr sont mis à NULL.
Si l'adresse spécifiée dans
addr ne peut pas être
mise en correspondance avec l'objet partagé, alors ces fonctions
renvoient
0. Dans ce cas,
aucun message d'erreur n'est
disponible avec
dlerror(3).
dladdr() est présente depuis la glibc 2.0 .
dladdr1() est apparue pour la première fois dans la
glibc 2.3.3.
Pour une explication des termes utilisés dans cette section, consulter
attributes(7).
Interface |
Attribut |
Valeur |
dladdr(), dladdr1() |
Sécurité des threads |
MT-Safe |
Ces fonctions sont des extensions GNU non standard qui sont également
présentes sur Solaris.
Quelquefois, les pointeurs de fonction passés à
dladdr()
peuvent vous surprendre. Sur certaines architectures (notablement i386 et
x86_64),
dli_fname et
dli_fbase peuvent au final pointer sur
l'objet depuis lequel vous appelez
dladdr(), même si la fonction
utilisée en paramètre devrait provenir d'une bibliothèque
liée dynamiquement.
Le problème est que le pointeur de fonction ne sera résolu que
lors de la compilation, mais pointe simplement vers la section de l'objet
original
plt (table de procédure d'édition des liens) qui
redirige l'appel après avoir demandé à l'éditeur
dynamique de liens de résoudre le symbole. Un contournement consiste
à compiler le code pour qu'il soit indépendant de son
adressage : dans ce cas le compilateur ne peut pas préparer le
pointeur à la compilation et
gcc(1) générera du
code qui chargera juste l'adresse finale du symbole depuis la table
GOT
(table d'offset globale) lors de l'exécution, avant de la passer
à
dladdr().
dl_iterate_phdr(3),
dlinfo(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]