ELF(5)			  Formats de fichiers de FreeBSD
 

NOM

elf - format de fichiers binaires exécutables ELF

 

SYNOPSIS

#include <elf.h>

 

DESCRIPTION

L'en-tête <elf.h> définit le format des fichiers binaires exécutables ELF. Ces binaires peuvent être des fichiers exécutables, des fichiers d'objet relocalisables, des fichiers du noyau ou des bibliothèques partagées.

Un exécutable au format ELF est formé d'un en-tête ELF suivi d'une table d'en-têtes de programmes ou de sections ou des deux. L'en-tête ELF est toujours au tout début du fichier (position zéro). La table d'en-têtes de programme et la table d'en-en-têtes de sections se trouvent à l'endroit défini par l'en-tête ELF. Les deux tables décrivent le reste des particularités du fichier.

Les applications voulant traiter des binaires ELF dans leur architecture ont simplement à inclure sys/elf.h dans leur code source. Elles pourront alors se référer à tous les types et structures en utilisant leurs noms génériques "Elf_xxx" et aux macros en utilisant "ELF_xxx". De cette manière, l'application peut être compilée sur n'importe quelle architecture sans avoir besoin de savoir si la machine est 32 ou 64 bits.

Si une application a besoin d'un fichier ELF issu d'une architecture inconnue, elle devra inclure à la fois sys/elf32.h et sys/elf64.h à la place de sys/elf.h. En outre, les types et structures devront être identifiés soit par " Elf32_xxx", soit par " Elf64_xxx" et les macros soit par " ELF32_xxx" soit par " ELF64_xxx".

Quelque soit le système, l'architecture doit obligatoirement inclure sys/elf_common.h ainsi que sys/elf_generic.h.

Ces fichiers d'en-tête décrivent les structures C dont nous parlions ci-dessus ainsi que celles des sections dynamiques, de relocalisation et des tables des symboles.

Les types suivants sont à utiliser sur les architectures 32 bits :

 
	   Elf32_Addr	 adresse de prognamme non-signée
	   Elf32_Half	 champ demi-mot non-signé
	   Elf32_Off	  position de fichier non-signée
	   Elf32_Sword	grand entier signé
	   Elf32_Word	 champ ou grand entier signé
	   Elf32_Size	 taille d'objet non-signée

Pour les architectures 64 bits, nous avons les types suivants :

 
	   Elf64_Addr	adresse de prognamme non-signée
	   Elf64_Half	champ demi-mot non-signé
	   Elf64_Off	 position de fichier non-signée
	   Elf64_Sword    grand entier signé
	   Elf64_Word	champ ou grand entier signé
	   Elf64_Size	taille d'objet non-signée
	   Elf64_Quarter  champ quart-de-mot non-signé

Toutes les structures de données définies suivent la taille "naturelle" et les directives d'alignement des classes significatives. Si necéssaire, les structures de données contiennent du remplissage afin d'assurer l'alignement 4 octets pour les objets de 4 octets, afin que la taille de la structure soit un multiple de 4, etc...

L'en-tête ELF est décrit par les types Elf32_Ehdr ou Elf64_Ehdr :

 
	   typedef struct {
		   unsigned char   e_ident[EI_NIDENT];
		   Elf32_Half	   e_type;
		   Elf32_Half	   e_machine;
		   Elf32_Word	   e_version;
		   Elf32_Addr	   e_entry;
		   Elf32_Off	   e_phoff;
		   Elf32_Off	   e_shoff;
		   Elf32_Word	   e_flags;
		   Elf32_Half	   e_ehsize;
		   Elf32_Half	   e_phentsize;
		   Elf32_Half	   e_phnum;
		   Elf32_Half	   e_shentsize;
		   Elf32_Half	   e_shnum;
		   Elf32_Half	   e_shstrndx;
	   } Elf32_Ehdr;
 
	   typedef struct {
		   unsigned char   e_ident[EI_NIDENT];
		   Elf64_Quarter   e_type;
		   Elf64_Quarter   e_machine;
		   Elf64_Half	   e_version;
		   Elf64_Addr	   e_entry;
		   Elf64_Off	   e_phoff;
		   Elf64_Off	   e_shoff;
		   Elf64_Half	   e_flags;
		   Elf64_Quarter   e_ehsize;
		   Elf64_Quarter   e_phentsize;
		   Elf64_Quarter   e_phnum;
		   Elf64_Quarter   e_shentsize;
		   Elf64_Quarter   e_shnum;
		   Elf64_Quarter   e_shstrndx;
	   } Elf64_Ehdr;

Les champs ont la signification suivante :

e_ident

Ce tableau d'octets sert à interpréter le fichier, indépendamment du processeur ou de la suite du fichier. Dans ce tableau, tout est nommé par des macros qui commencent par le préfixe EI_ et qui contiennent des valeurs qui commencent par ELF. Les macros suivantes sont définies :

EI_MAG0 : le premier octet du nombre magique. Il doit être rempli avec ELFMAG0.

EI_MAG1 : le second octet du nombre magique. Il doit être rempli avec ELFMAG1.

EI_MAG2 : le troisième octet du nombre magique. Il doit être rempli avec ELFMAG2.

EI_MAG3 : le quatrième octet du nombre magique. Il doit être rempli avec ELFMAG3.

EI_CLASS : le cinquième octet identifie l'architecture pour ce binaire :

ELFCLASSNONE: cette classe est invalide.

ELFCLASS32 : définit l'architecture 32 bits. Cela supporte les machines dont les fichiers et les adresses virtuelles vont jusqu'à 4 giga-octets.

ELFCLASS64 : pour l'architecture 64 bits.

EI_DATA : le sixième octet indique le codage des données spécifique au processeur. Actuellement, les codages sont :

ELFDATANONE : format de données inconnu.

ELFDATA2LSB : le complément de deux, petit endien.

ELFDATA2MSB : le complément de deux, grand endien.

EI_VERSION : Le numéro de version de la spécification ELF :

EV_NONE : version non-valide.

EV_CURRENT : version courante.

EI_PAD : début du remplissage. Ces octets sont réservés et mis à zéro. Les programmes qui les lisent doivent les ignorer. La valeur d' EI_PAD changera si des octets inutilisés acquièrent une signification.

EI_BRAND : début de l'identification de l'architecture.

EI_NIDENT : la taille du tableau e_ident.

e_type

Cet élément de la structure identifie les types de fichiers odjet :

ET_NONE : type inconnu.

ET_REL : fichier relocalisable.

ET_EXEC : fichier exécutable.

ET_DYN : fichier partagé.

ET_CORE : un fichier du noyau (core file).

e_machine

Cet élément indique l'architecture requise pour le fichier :

EM_NONE : machine inconnue.

EM_M32 : AT&T WE 32100.

EM_SPARC : SPARC de Sun Microsystems

EM_386 : Intel 80386.

EM_68K : Motorola 68000.

EM_88K : Motorola 88000.

EM_486 : Intel 80486.

EM_860 : Intel 80860.

EM_MIPS : MIPS RS3000 (big-endian seulement).

EM_MIPS_RS4_BE : MIPS RS4000 (big-endian seulement ).

EM_SPARC64 : SPARC v9 64 bits non-officiel.

EM_PARISC : HPPA.

EM_PPC : PowerPC.

EM_ALPHA : Compaq [DEC] Alpha.

e_version

Cet élément indique la version du fichier :

EV_NONE : version non valide.

EV_CURRENT : version courante.

e_entry

Cet élément donne l'adresse virtuelle sur laquelle le système doit transférer le contrôle puis lancer l'exécution. Si le fichier n'a pas de point d'entrée, la valeur est à zéro.

e_phoff

Cet élément contient la position dans le fichier, en octets, de la table d'en-tête du programme. Si le fichier n'a pas de table d'en-tête de programme, l'élément vaut zéro.

e_shoff

Cet élément contient la position dans le fichier, en octets, de la table d'en-tête de la section. Si le fichier n'a pas cette section, l'élément vaut zéro.

e_flags

Cet élément contient les drapeaux spécifiques au processeur associé au fichier. Leurs noms sont de la forme EF_" drapeaux-machine". Actuellement, aucun n'a été défini.

e_ehsize

Cet élément contient la taille en octets de l'en-tête ELF.

e_phentsize

Cet élément contient la taille en octets d'une entrée de la table d'en-têtes de programme. Toutes les entrées ont la même taille.

e_phnum

Cet élément contient le nombre d'entrées de la table d'en-tête de programme. Ainsi, le produit de e_phentsize par e_phnum donne la taille de la table en octets. Si un fichier n'a pas d'en-tête de programmes, e_phnum prend la valeur de zéro.

e_shentsize

Cet élément contient la taille en octets d'un en-tête de section. Un en-tête de section est une entrée de la table des en-têtes de section. Toutes les entrées ont la même taille.

e_shnum

Cet élément contient le nombre d'entrées de la table des en-têtes de section. Ainsi le produit de e_shentsize par e_shnum donne la taille en octets de la table d' en-têtes de section. Si le fichier n'a pas cette table, e_shnum prend la valeur zéro.

e_shstrndx

Cet élément contient l'index de la table d'en-têtes de section de l'entrée associée à la table des chaines de noms de sections. Si le fichier n'a pas de table des chaines de noms de sections, cet élément prend la valeur SHN_UNDEF.

SHN_UNDEF : Cette valeur indique une référence de section indéfinie, absente, inappropriée ou autres non-sens. Par exemple, un symbole "défini" par rapport à la section numéro SHN_UNDEF est un symbole indéfini.

SHN_LORESERVE : Cette valeur indique la limite inférieure de l'intervalle des indices réservés.

SHN_LOPROC : cette valeur, jusqu'à SHN_HIPROC inclus, est réservée à la sémantique propre au processeur.

SHN_HIPROC : cette valeur, à partir de SHN_LOPROC inclus, est réservée à la sémantique propre au processeur.

SHN_ABS : indique la valeur absolue de la référence correspondente. Par exemple, les symboles définis par rapport à la section numéro SHN_ABS ont une valeur absolue et ne sont pas affectés par les relocalisations.

SHN_COMMON : Les symboles définis par rapport à cette section sont des symboles communs, comme COMMON en Fortran ou comme les variables externes non allouées en C.

SHN_HIRESERVE : Cette valeur indique la limite supérieure de l'intervalle des indices réservés entre SHN_LORESERVE et SHN_HIRESERVE, inclus. Elle ne référence pas la table des en-têtes de section. Celle-ci ne contient pas d'entrées pour les indices réservés.

Un exécutable ou une table d'en-tête de programme issue d'un fichier d'objets partagés est un tableau de structures, chacune décrivant un segment ou contenant d'autres informations utiles au système pour préparer l'exécution du programme. Un segment de fichier d'objets contient une section ou plus. Les en-têtes de programmes ne sont pertinants que dans le cas d'exécutables et de fichiers d'objets partagés. Un fichier définit ses propres tailles d'en-têtes de programme à l'aide des éléments ELF e_phentsize et e_phnum. De même que pour les en-têtes d'exécutables ELF, les en-têtes de programmes dépendent de l'architecture :

 
	   typedef struct {
		   Elf32_Word	   p_type;
		   Elf32_Off	   p_offset;
		   Elf32_Addr	   p_vaddr;
		   Elf32_Addr	   p_paddr;
		   Elf32_Size	   p_filesz;
		   Elf32_Size	   p_memsz;
		   Elf32_Word	   p_flags;
		   Elf32_Size	   p_align;
	   } Elf32_Phdr;
 
	   typedef struct {
		   Elf64_Half	   p_type;
		   Elf64_Half	   p_flags;
		   Elf64_Off	   p_offset;
		   Elf64_Addr	   p_vaddr;
		   Elf64_Addr	   p_paddr;
		   Elf64_Size	   p_filesz;
		   Elf64_Size	   p_memsz;
		   Elf64_Size	   p_align;
	   } Elf64_Phdr;
 

La principale différence entre les programmes 32 et 64 bits se situe seulement dans la position de l'élément p_flags dans la structure.

p_type

Cet élément de la structure Phdr indique le type de segment que décrit cet élément de tableau ou bien comment interpréter l'information.

PT_NULL : l'élément du tableau est inutilisé et les autres valeurs sont indéfinies. L'en-tête de programme peut ignorer ces entrées.

PT_LOAD : L'élement de tableau indique un segment chargeable, décrit par p_filesz et p_memsz. Les octets du fichiers sont en correspondance avec le début du segment mémoire. Si la taille mémoire du segment ( p_memsz) est supérieure à la taille du fichier ( p_filesz), les octets supplémentaires prennent la valeur zéro et suivent la zone initiale du segment. La taille du fichier ne doit pas dépasser celle de la mémoire. Les entrées de segments chargeables de la table des en-têtes du programme sont dans l'ordre croissant de p_vaddr.

PT_DYNAMIC : Cet élément de tableau contient des information sur les liens dynamiques.

PT_INTERP : Cet élément de tableau détermine l'endroit et la taille du chemin d'accès (terminé par null) qui permet d'appeler un interpréteur. Cette information n'est pertinente que dans le cas de fichiers exécutables (mais elle peut apparaître dans des objets partagés) et ne peut exister qu'une fois dans un fichier. Si présente, elle doit précéder tout segment chargeable.

PT_NOTE : Cet élément de tableau détermine l'endroit et la taille d'informations auxiliaires.

PT_SHLIB : Ce type de segment est réservé et ne possède pas de sémantique spécifique. Les programmes qui le possèdent ne sont pas conformes à ABI.

PT_PHDR : S'il est présent, cet élément de tableau détermine l'endroit et la taille de la table d'en-tête de programme elle-même, à la fois dans le fichier et dans l'image mémoire du programme. Ce type de segment ne doit pas aparaître plus d'une fois dans un fichier et uniquement si la table des en-têtes de programme fait partie de l'image mémoire du programme. Il doit précéder tout segment chargeable.

PT_LOPROC : Cette valeur, jusqu'à PT_HIPROC inclus, est réservée à la sémantique propre du processeur.

PT_HIPROC : Cette valeur, à partir de PT_LOPROC inclus, est réservée à la sémantique propre du processeur.

p_offset

Ce membre contient la position, à partir du début du fichier, à laquelle se trouve le premier octet du segment.

p_vaddr

Ce membre contient l'adresse virtuelle à laquelle se trouve le premier octet du segment, en mémoire.

p_paddr

Dans les systèmes pour lesquels il est pertinant, ce membre est réservé au segment d'adressage physique. Ce n'est pas le cas avec BSD où il doit être à zéro.

p_filesz

Ce membre contient le nombre d'octets de l'image fichier du segment. Il doit être à zéro.

p_memsz

Ce membre contient le nombre d'octets de l'image mémoire du segment. Il doit être à zéro.

p_flags

Ce membre contient les flags utiles au segment :

PF_X : un segment exécutable.

PF_W : un segment inscriptible.

PF_R : un segment en lecture.

En général, un segment texte a le flag PF_X et PF_R et un segment de données PF_X, PF_W et PF_R.

p_align

Ce membre contient la valeur sur laquelle sont alignés les segments, en mémoire et dans le fichier. Les segments de processus chargeables doivent avoir des valeurs de p_vaddr et p_offset congruantes modulo taille de page. Les valeurs de zéro et un signifient qu'aucun alignement n'est requis. Sinon, p_align doit être une puissance de deux et p_vaddr doit être égal à p_offset, modulo p_align.

Une table d'en-tête de section dans un fichier permet de localiser toutes les sections du fichier. Elle se présente sous la forme d'un tableau de structures Elf32_Shdr ou Elf64_Shdr. Le membre e_shoff de l'en-tête ELF donne la position en octets, par rapport au début du fichier, de la table d'en-tête de sections. e_shnum contient le nombre d'entrées de la table d'en-tête de sections. e_shentsize contient la taille en octets de chacune des ces entrées.

Un index est attaché à ce tableau et certains indices sont réservés. Un fichier objet n'a pas de sections pour ces indices spécifiques :

SHN_UNDEF

Cette valeur indique une référence de section indéfinie, absente, non-pertinente ou autrement non-significative.

SHN_LORESERVE

Cette valeur indique la limite inférieure des indices réservés.

SHN_LOPROC

Cette valeur, jusqu'à SHN_HIPROC inclus, est réservée à la sémantique propre au processeur.

SHN_HIPROC

Cette valeur, à partir de SHN_LOPROC inclus, est réservée à la sémantique propre au processeur.

SHN_ABS

Cette valeur indique la valeur absolue de la référence correspondante. Par exemple, les symboles définis par rapport à la section numéro SHN_ABS ont une valeur absolue et ne sont donc pas effectés par la relocalisation.

SHN_COMMON

Les symboles définis par rapport à cette section sont des symboles communs, comme COMMON en FORTRAN ou comme les variables externes non-localisées en C.

SHN_HIRESERVE

Cette valeur indique la limite supérieure des indices réservés. Le système réserve les indices compris entre SHN_LORESERVE et SHN_HIRESERVE, inclusivement. Cette table d'en-tête de section ne contient aucune entrée pour les indices réservés.

L'en-tête de section est de cette forme :

 
	   typedef struct {
		   Elf32_Word	   sh_name;
		   Elf32_Word	   sh_type;
		   Elf32_Word	   sh_flags;
		   Elf32_Addr	   sh_addr;
		   Elf32_Off	   sh_offset;
		   Elf32_Size	   sh_size;
		   Elf32_Word	   sh_link;
		   Elf32_Word	   sh_info;
		   Elf32_Size	   sh_addralign;
		   Elf32_Size	   sh_entsize;
	   } Elf32_Shdr;
 
	   typedef struct {
		   Elf64_Half	   sh_name;
		   Elf64_Half	   sh_type;
		   Elf64_Size	   sh_flags;
		   Elf64_Addr	   sh_addr;
		   Elf64_Off	   sh_offset;
		   Elf64_Size	   sh_size;
		   Elf64_Half	   sh_link;
		   Elf64_Half	   sh_info;
		   Elf64_Size	   sh_addralign;
		   Elf64_Size	   sh_entsize;
	   } Elf64_Shdr;
 

sh_name

Ce membre donne le nom de la section. Sa valeur est un index vers l'en-tête de section de la table des chaînes, donnant la position de la chaîne terminée par null.

sh_type

Ce membre ordonne le contenu et la sémantique de la section.

SHT_NULL

Cette valeur désactive l'en-tête de section. Elle n'a pas de section associée et les autres membres ont une valeur indéfinie.

SHT_PROGBITS

La section contient des informations dont le format et la signification ne sont déterminés que par le programme.

SHT_SYMTAB

Cette section est une table de symboles. D'une manière générale, SHT_SYMTAB fournit les symboles pour l'édition de liens tant statique que dynamique. Les tables de symboles complètes peuvent aussi contenir des éléments non-nécessaires aux liens dynamiques. Un fichier objet peut aussi contenir une section SHN_DYNSYM.

SHT_STRTAB

Cette section contient une table de chaînes. Un fichier objet peut avoir plusieurs sections tables de chaines.

SHT_RELA

Cette section contient des entrées de relocalisation, avec des compléments explicites, comme le type Elf32_Rela dans le cas de classes 32 bits de fichiers objets. Un fichier objet peut avoir plusieurs sections de relocalisation.

SHT_HASH

Cette section contient une table fractionnée de symboles. Tous les objets participant aux liens dynamiques doivent avoir une telle table. Un fichier objet ne peut en avoir qu'une.

SHT_DYNAMIC

Cette section contient des informations utiles aux liens dynamiques. Un fichier objet ne peut avoir qu'une section dynamique.

SHT_NOTE

Cette section contient diverses informations sur le fichier.

SHT_NOBITS

Une section de ce type n'occupe aucune place dans le fichier mais ressemble à SHN_PROGBITS. Par ailleurs, elle ne contient aucun octet et sh_offset indique la position conceptuelle dans le fichier.

SHT_REL

Cette section contient les postions de relocalisation, sans les compléments explicites, comme le type Elf32_Rel dans le cas de classes 32 bits de fichiers objets. Un fichier objet peut avoir plusieurs sections de relocalisation.

SHT_SHLIB

Cette section, sans organisation spécifique, est réservée.

SHT_DYNSYM

Cette section contient le minimum requis de symboles dynamiques. Un fichier objet peut aussi avoir une section SHN_SYMTAB.

SHT_LOPROC

Cette valeur, jusqu'à SHT_HIPROC inclus, est réservée à la sémantique propre au processeur.

SHT_HIPROC

Cette valeur, à partir de SHT_LOPROC inclus, est réservée à la sémantique propre au processeur.

SHT_LOUSER

Cette valeur indique la limite inférieure des indices réservés à l'application.

SHT_HIUSER

Cette valeur indique la limite supérieure des indices réservés à l'application. Les types de sections compris entre SHT_LOUSER et SHT_HIUSER peuvent être utilisés par l'application sans conflits avec les types de sections actuels et futurs.

sh_flags

La section accepte les flags d'un bit décrivant divers attributs. Si un bit est positionné dans sh_flags, l'attribut correspondant est actif pour cette section sinon il est inactif. Les attributs indéfinis sont mis à zéro.

SHF_WRITE

Cette section contient des données qui peuvent être écrites pendant l'exécution du processus.

SHF_ALLOC

La section occupe une place en mémoire durant l'exécution du processus. Des sections de contrôle ne se placent pas dans l'image mémoire d'un fichier objet. Cet attribut est désactivé dans ce cas.

SHF_EXECINSTR

La section contient des instructions machine exécutables.

SHF_MASKPROC

Tous les bits de ce masque sont réservés à la sémantique propre du processeur.

sh_addr

Si la section doit apparaitre en mémoire, ce membre contient l'adresse à laquelle le premier octet doit résider. Sinon il vaut zéro.

sh_offset

Ce membre contient la position en octets, à partir du début du fichier, du premier octet de la section. Une section de type SHT_NOBITS n'occupe aucune place dans le fichier et son sh_offset localise son emplacement conceptuel dans le fichier.

sh_size

Ce membre contient la taille en octets de la section. A moins qu'elle ne soit de type SHT_NOBITS, la section occupe sh_size octets dans le fichier. Une section SHT_NOBITS peut avoir une taille différente de zéro mais n'occupe quand même aucune place dans le fichier.

sh_link

Ce membre contient un lien d'index de table d'en-tête de section dont l'interprétation dépend de la section.

sh_info

Ce membre contient des informations supplémentaires dont l'interprétation dépend de la section.

sh_addralign

Certaines sections possèdent des contraintes d'alignement sur les adresses. Si une section contient un mot-double, le système doit assurer l'alignement pour toute la section. C'est à dire que la valeur sh_addr doit être congrue à zéro modulo sh_addralign. Seules la valeur zéro ou une valeur positive puissance de deux est acceptée. Une valeur de zéro ou un signifie que la section n'a aucune contrainte d'alignement.

sh_entsize

Certaines sections contiennent une table dont les entrées sont de taille fixe, comme une table de symboles. Pour celles-ci, ce membre indique la taille des entrées. Ce membre est à zéro dans les autres cas.

Diverses sections contiennent des informations de programme ou de contrôle :

.bss

Cette section contient des données non-initialisées utiles à l'image mémoire du programme. Par définition, le système initialise les données à zéro lors du lancement du programme. Cette section est de type SHT_NOBITS. Les types d'attributs utilisés sont SHF_ALLOC et SHF_WRITE.

.comment

Cette section contient des informations de contrôle de version. Elle est de type SHT_PROGBITS et aucun attribut n'est utilisé.

.data

Cette section contient des données initialisées utiles à l'image mémoire du programme. Elle est de type SHT_PROGBITS et ses attributs sont SHF_ALLOC et SHF_WRITE.

.data1

Cette section contient des données initialisées utiles à l'image mémoire du programme. Elle est de type SHT_PROGBITS et ses attributs sont SHF_ALLOC et SHF_WRITE.

.debug

Cette section contient des informations pour le débogage des symboles. Son contenu n'a pas de spécification mais elle est de type SHT_PROGBITS, sans attributs.

.dynamic

Cette section, de type SHT_DYNAMIC, contient des informations sur les liens dynamiques. Ses attributs incluent le bit SHF_ALLOC. Le bit SHF_WRITE positionné est spécifique au processeur. Voir les attributs plus loin.

.dynstr

Cette section contient les chaines utiles aux liens dynamiques ou, plus courrament, les chaines représentant les noms associés aux entrées des tables de symboles. Elle est de type SHT_STRTAB et l'attribut utilisé SHF_ALLOC.

.dynsym

Cette section contient la table de symboles des liens dynamiques. Elle est de type SHT_DYNSYM et l'attribut utilisé SHF_ALLOC.

.fini

Cette section contient les instructions exécutables qui apparaissent lorsque le programme se termine. Le système s'arrange alors pour exécuter le code de cette section. Elle est de type SHT_PROGBITS et les attributs utilisés SHF_ALLOC et SHF_EXECINSTR.

.got

Cette section contient la table de positionnement global. Elle est de type SHT_PROGBITS et ses attributs dépendent du processeur.

.hash

Cette section contient la table segmentée des symboles. Elle est de type SHT_HASH et l'attribut utilisé SHF_ALLOC.

.init

Cette section contient les instructions exécutables utiles à l'initialisation du processus. Lorsqu'un programme démarre, le système s'arrange pour exécuter le code de cette section avant d'en appeler le point d'entrée principal. Elle est de type SHT_PROGBITS et les attributs utilisés SHF_ALLOC et SHF_EXECINSTR.

.interp

Cette section contient le chemin d'accès d'un interpréteur de programme. Si le fichier possède un segment chargeable avec cette section, les attributs auront le bit SHF_ALLOC positionné. Elle est de type SHT_PROGBITS.

.line

Cette section contient des informations sur les numéros de lignes pour le débogage. Elle fait la correspondance entre les sources du programme et le code machine, sans spécifications particulières. Elle est de type SHT_PROGBITS sans attributs.

.note

Cette section contient des informations dans le format "Section de notes" décrit plus loin. Elle est de type SHT_NOTE sans attributs.

.plt

Cette section contient la table des liens de procédures. Elle est de type SHT_PROGBITS et les attributs dépendent du processeur.

.relNOM

Cette section, de type SHT_REL, contient des informations de relocalisation, comme décrit plus loin. Si un segment chargeable a une telle section, le bit SHF_ALLOC sera positionné. Par convention, "NOM" est donné par la section concernée par la relocalisation. De cette manière, une section .text aura le nom .rel.text.

.relaNOM

Cette section, de type SHT_RELA, contient des informations de relocalisation, comme décrit plus loin. Si un segment chargeable a une telle section, le bit SHF_ALLOC sera positionné. Par convention, "NOM" est donné par la section concernée par la relocalisation. De cette manière, une section .text aura le nom .rela.text.

.rodata

Cette section contient des données en lecture seule qui, typiquement, contribuent au segment non-inscriptible de l'image du processus. Elle est de type SHT_PROGBITS et l'attribut utilisé SHF_ALLOC.

.rodata1

Cette section contient des données en lecture seule qui, typiquement, contribuent au segment non-inscriptible de l'image du processus. Elle est de type SHT_PROGBITS et l'attribut utilisé SHF_ALLOC.

.shstrtab

Cette section est celle des noms. Elle est de type SHT_STRTAB sans attributs.

.strtab

Cette section, de type SHT_STRTAB, contient des chaines qui représentent, la plupart du temps, les noms associés aux entrées des tables de symboles. Si le fichier a des segments chargeables possèdant la table des chaines de symboles, l'attribut aura le bit SHF_ALLOC positionné, sinon non.

.symtab

Cette section, de type SHT_SYMTAB, contient une table de symboles. Si le fichier a des segments chargeable possédant une table de symboles, l'attribut aura le bit SHF_ALLOC positionné, sinon non.

.text

Cette section contient les instructions "texte" ou exécutables du programme. Elle est de type SHT_PROGBITS et les attributs utilisés sont SHF_ALLOC et SHF_EXECINSTR.

Les sections table de chaines contiennent des suites de caractères terminées par null, appelées chaines. Le fichier objet les utilise comme noms de symboles et de sections. Les références se font par index vers cette section. Le premier octet, à l'index zéro, contient le caractère null par définition. Le dernier octet contient aussi le caractère null, de manière à ce que toutes les chaines soient terminées par celui-ci.

Une table de symboles d'un fichier objet contient les informations utiles à la localisation et à la relocalisation des références et définitions des symboles du programme. Un index de table de symbole désigne un endroit de cette table.

 
	   typedef struct {
		   Elf32_Word	   st_name;
		   Elf32_Addr	   st_value;
		   Elf32_Size	   st_size;
		   unsigned char     st_info;
		   unsigned char     st_other;
		   Elf32_Half	   st_shndx;
	   } Elf32_Sym;
 
	   typedef struct {
		   Elf64_Half       st_name;
		   unsigned char    st_info;
		   unsigned char    st_other;
		   Elf64_Quarter    st_shndx;
		   Elf64_Addr       st_value;
		   Elf64_Size       st_size;
	   } Elf64_Sym;
 

st_name

Ce membre contient un index vers la table des chaines de symboles du fichier objet, qui contient le nom du symbole. Si la valeur est différente de zéro, il s'agit d'un index vers la table de chaines qui donne le nom du simbole sinon la table de symbole n'a pas de nom.

st_value

Ce membre donne la valeur du symbole associé.

st_size

La plupart des symboles ont une taille. Ce membre contient zéro s'il n'en a pas ou si elle est inconnue.

st_info

Ce membre indique le type de symbole et ses attributs liés :

STT_NOTYPE

Le type n'est pas défini.

STT_OBJECT

Le symbole est associé à un objet de données.

STT_FUNC

Le symbole est associé à une fonction ou autre code exécutable.

STT_SECTION

Le symbole est associé à une section. Les entrées de table de symbole de ce type existaient pour la localisation et avaient des liens STB_LOCAL.

STT_FILE

Par convention, le nom de symbole donne le nom du fichier source associé au fichier objet. Un symbole fichier a des liens STB_LOCAL, son index de section est SHN_ABS et il précède tout autre symbole STB_LOCAL du fichier.

STT_LOPROC

Ces valeurs jusqu'à STT_HIPROC inclus sont réservées à la sémantique propre du processeur.

STT_HIPROC

Ces valeurs à partir de STT_LOPROC inclus sont réservées à la sémantique propre du processeur.

STB_LOCAL

Les symboles locaux ne sont pas visibles hors du fichier objet contenant leur description. Des symboles locaux de même nom peuvent exister dans plusieurs fichiers sans interférer entre eux.

STB_GLOBAL

Les symboles globaux sont visibles à partir de tous les fichiers objets auxquels ils sont combinés. La définition d'un symbole global dans un fichier satisfera une référence non-définie dans un autre fichier au même symbole.

STB_WEAK

Les symboles faibles (weak) ressemblent aux symboles globaux mais leur définition a une moindre préséance.

STB_LOPROC

Ces valeurs jusqu'à STB_HIPROC inclus sont réservées à la sémantique propre du processeur.

STB_HIPROC

Ces valeurs à partir de STT_LOPROC inclus sont réservées à la sémantique propre du processeur.

Il existe des macros qui permettent de paqueter et dépaqueter les liens et les types de champs :

ELF32_ST_BIND(info) ou ELF64_ST_BIND(info)

Récupère un lien à partir d'une valeur st_info.

ELF64_ST_TYPE(info) ou ELF32_ST_TYPE(info)

Récupère un type à partir d'une valeur st_info.

ELF32_ST_INFO(lien, type) ou ELF64_ST_INFO(lien, type)

Convertie un lien et un type en valeur st_info.

st_other

Ce membre ne contient actuellement que des zéros et n'a pas de signification définie.

st_shndx

Chaque entrée de table de syboles est "définie" par rapport à une action. Ce membre contient l'index vers la table d'en-tête de section qui correspond.

La relocalisation est le processus qui consiste à associer les références de symboles aux définitions de symboles. Les fichiers relocalisables doivent avoir des informations sur la façon dont le contenu de leur sections est modifiable, permettant aux exécutables et aux objet partagés d'obtenir la bonne information pour l'image du programme. Les entrées de relocalisation sont ces données.

Les structures de relocalisation ne nécessitant aucun complément :

 
	   typedef struct {
		   Elf32_Addr	   r_offset;
		   Elf32_Word	   r_info;
	   } Elf32_Rel;
 
	   typedef struct {
		   Elf64_Addr	   r_offset;
		   Elf64_Size	   r_info;
	   } Elf64_Rel;
 

Les structures de relocalisation nécessitant des compléments :

 
	   typedef struct {
		   Elf32_Addr	   r_offset;
		   Elf32_Word	   r_info;
		   Elf32_Sword	   r_addend;
	   } Elf32_Rela;
 
	   typedef struct {
		   Elf64_Addr	   r_offset;
		   Elf64_Size	   r_info;
		   Elf64_Off	   r_addend;
	   } Elf64_Rela;

 

r_offset

Ce membre donne la position à laquelle appliquer la relocalisation. Pour un fichier relocalisable, la valeur correspond au nombre d'octets, à partir du début de la section, des données concernées. Pour un fichier exécutable ou un objet partagé, la valeur est l'adresse virtuelle de ces données.

r_info

Ce membre donne à la fois l'index de la table des symboles auquel appliquer la relocalisation et le type de relocalisation à appliquer. Ces derniers dépendent du processeur. Lorsque le texte se réfère à un type d'entrée de relocalisation ou à un index de table de symbole, il se réfère, en fait, au résultat de ELF_[32|64]_R_TYPE ou ELF[32|64]_R_SYM sur le membre r_info de l'entrée.

r_addend

Ce membre spécifie un complément constant utilisé pour calculer la valeur à enregistrer dans le champ relocalisable.

 

VOIR AUSSI

as(1), gdb(1), ld(1), objdump(1), execve(2), core(5)

 

Hewlett Packard, Elf-64 Object File Format.

Santa Cruz Operation, System V Application Binary Interface.

Unix System Laboratories, "Object Files", Executable and Linking Format (ELF).

 

HISTORIQUE

Les fichiers ELF font leur apparition avec FreeBSD 2.2.6. ELF lui-même apparait dans UNIX AT&T System V. Ce format est un standard adopté.

 

AUTEURS

Cette page de manuel a été écrite par Jeroen Ruigrok van der Werven <asmodai@wxs.nl> en s'inspirant de celle issue de BSD/OS de BSDI.

La version française est de Guillain SEUILLOT <Guillain@lycosmail.com>.

 

FreeBSD 3.3

31 juillet 1999, 12 mai 2000 pour la version française.


NOM | SYNOPSIS | DESCRIPTION | VOIR AUSSI | HISTORIQUE | AUTEURS