GNU/Linux >> Tutoriels Linux >  >> Linux

Principes de base du format de fichier objet Linux ELF (et de la structure d'en-tête ELF)

ELF signifie format de fichier exécutable et pouvant être lié.

ELF est utilisé comme format de fichier standard pour les fichiers objets sous Linux. Auparavant, le format de fichier a.out était utilisé comme standard, mais dernièrement, ELF a pris le relais en tant que standard.

ELF prend en charge :

  • Différents processeurs
  • Encodage de données différent
  • Différentes classes de machines

Cet article explique les différents types de fichiers d'objet ELF et d'en-tête ELF.

Fichiers objet ELF

Un fichier contenant du code compilé est appelé fichier objet. Un fichier objet peut être de l'un des types suivants :

1. Fichier déplaçable

Ce type de fichier objet contient des données et du code qui peuvent être liés à d'autres fichiers transférables pour produire un binaire exécutable ou un fichier objet partagé. En termes simples, un fichier relocalisable est identique au fichier .o produit lorsque nous compilons un code de la manière suivante :

 gcc -Wall -c test.c -o test.o

Ainsi, le test.o produit après l'opération ci-dessus serait un fichier relocalisable.

2. Fichier objet partagé

Ce type de fichier objet est utilisé par l'éditeur de liens dynamique pour le combiner avec l'exécutable et/ou d'autres fichiers objet partagés afin de créer une image de processus complète. En termes simples, un fichier objet partagé est identique au fichier .so produit lorsque le code est compilé avec le drapeau -fPIC de la manière suivante :

gcc -c -Wall -Werror -fPIC shared.c
gcc -shared -o libshared.so shared.o

Une fois les deux commandes ci-dessus effectuées, un fichier objet partagé libshared.o est produit en sortie.

REMARQUE :Pour en savoir plus sur les bibliothèques partagées Linux, consultez notre article Bibliothèques partagées Linux

3. Fichier exécutable

Ce type de fichier objet est un fichier capable d'exécuter un programme lorsqu'il est exécuté. En termes simples, il s'agit de la sortie de commandes comme celle-ci :

 gcc -Wall test.c -o test

Ainsi, la sortie "test" serait un exécutable qui, lorsqu'il serait exécuté, exécuterait la logique écrite dans le fichier test.c.

Ainsi, comme on peut le déduire des types de fichiers objets ci-dessus, un fichier objet participe de la construction du programme à son exécution ou nous pouvons dire de la liaison à l'étape d'exécution (pour en savoir plus sur les étapes de compilation Linux/GCC, reportez-vous à notre article Journey of un programme C).

En-tête ELF

Tous les fichiers objets décrits ci-dessus sont de type ELF sous Linux.

Cela peut facilement être prouvé en examinant chacun de ces fichiers. Par exemple, j'ai examiné chacun des trois fichiers de mon système :

Fichier réadressable :

 $ vim func.o

^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^A^@>^@^A^@^@^@^@^@^@^@^@^@^@^@
^@UHå¿^@^@^@^@è^@^@^@^@¸^@^@^@^@è^@^@^@^@ÉÃ^@^@
 Inside func()^@^@GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3^@^T^@^@^@^@
^@^@^@^AzR^@^Ax^P^A^[^L^G^H^A^@^@^\^@^.symtab^@.strtab^@.shstrtab^
@.rela.text^@.data^@.bss^@.rodata^@.comment^@.note.GNU-stack^@.rela.eh_frame
^@^@^@^@^@^@^@^@^@^@^@^@^@

Fichier objet partagé :

$ vim libshared.so

^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^C^@>^@^A^@^@^@ ^@^@^@^@^@^A^@^@^@^F^@^
^@^@^@^@^@è^A^@^@^@^@^@^@è^A^@^@^@^@^@^@^A^@^@^@^@^@^@^@^D^@^@^@^T^@^@^
@^C^@^@^@GNU^@·YG®z^L^ZÊ7uÈí,?^N^@^@^@^@^C^@^@^@^L^@^@^@

Fichier exécutable :

$ vim test

^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^B^@>^@^A^@^@^@P@^@^@^@^@^@@^@^@^@^@^@<
^@^@^@D^@^@^^B^@^@^@^@^@^@^A^@^@^@^@^@^@^@/lib64/ld-linux-x86-64.so.2^@^D^
@^@^@^D^@^@^@^T^@^@^@^C^@^@^@GNU^@òÁ}CKbE;ära`6"^O^N\^C^@^@^@

Nous voyons donc que, comme il s'agit de fichiers binaires, rien de plus n'est compréhensible à l'exception de la chaîne ELF au début de chaque fichier. Cela montre que ces fichiers sont uniquement au format ELF.

Chaque fichier commence par un en-tête ELF qui indique à peu près l'organisation complète du fichier. Par exemple, les fichiers d'objets réadressables et partagés contiennent des sections, mais à l'autre extrémité, le fichier exécutable est composé de segments. Ainsi, selon le type de fichier objet, l'en-tête ELF donne des informations détaillées sur le fichier.

Généralement dans le cas de fichiers exécutables, un en-tête ELF est suivi d'une table d'en-tête de programme. Une table d'en-tête de programme aide à créer une image de processus. Puisqu'il aide à créer une image de processus (qui est créée après l'exécution de l'exécutable), la table d'en-tête du programme devient obligatoire pour les fichiers exécutables mais est facultative pour les fichiers d'objets transférables et partagés.

Voici l'organisation de l'en-tête ELF :

#define EI_NIDENT 16
typedef struct {
e_ident[EI_NIDENT];
unsigned char e_type;
Elf32_Half e_machine;
Elf32_Half e_version;
Elf32_Word e_entry;
Elf32_Addr e_phoff;
Elf32_Off e_shoff;
Elf32_Off e_flags;
Elf32_Word e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Ehdr;

On voit donc que l'organisation présentée ci-dessus se présente sous la forme d'une structure. Expliquer chaque membre en détail ici rendrait les choses complexes, alors passons en revue la signification de base et les informations détenues par chaque membre de cette structure pour avoir une idée de ce domaine particulier.

1. e_ident

Comme nous le savons déjà, le format ELF prend en charge différentes classes de machines, de processeurs, etc. Ainsi, afin de prendre en charge tout cela, les informations initiales du fichier ELF contiennent des informations sur la manière d'interpréter le fichier indépendamment du processeur sur lequel l'exécutable est exécuté. Le tableau ‘e_ident’ fournit exactement les mêmes informations :

Name     Value      Purpose
EI_MAG     0          File identification
EI_MAG1    1          File identification
EI_MAG2    2          File identification
EI_MAG3    3          File identification
EI_CLASS   4          File class
EI_DATA    5          Data encoding
EI_VERSION 6          File version
EI_PAD     7          Start of padding bytes
EI_NIDENT  16         Size of e_ident[]
  • EI_MAG Les quatre premiers octets ci-dessus contiennent le nombre magique "0x7fELF".
  • EI_CLASS Un ELF peut avoir deux classes, 32 bits ou 64 bits. Cela rend le format de fichier portable.
  • EI_DATA Ce membre donne les informations sur l'encodage des données. En termes simples, ces informations indiquent si les données sont au format big endian ou little endian.
  • EI_VERSION Ce membre fournit des informations sur la version du fichier objet.
  • EI_PAD Ce membre marque le début des octets inutilisés dans le tableau d'informations e_indent.
  • EI_NIDENT Ce membre fournit la taille du tableau e_indent. Cela aide à analyser le fichier ELF.

2. e_type

Ce membre identifie le type de fichier objet. Par exemple, un fichier objet peut être des types suivants :

Name    Value    Meaning
ET_NONE  0       No file type
ET_REL   1       Relocatable file
ET_EXEC  2       Executable file
ET_DYN   3       Shared object file
ET_CORE  4       Core file

REMARQUE :La liste ci-dessus n'est pas exhaustive, mais donne tout de même des informations sur les principaux types de fichiers objets auxquels ELF peut se référer.

3. e_machine

Ce membre donne des informations sur l'architecture requise par un fichier ELF.

Name            Value      Meaning
ET_NONE           0          No machine
EM_M32            1          AT&T WE 32100
EM_SPARC          2          SPARC
EM_386            3          Intel Architecture
EM_68K            4          Motorola 68000
EM_88K            5          Motorola 88000
EM_860            7          Intel 80860
EM_MIPS           8          MIPS RS3000 Big-Endian
EM_MIPS_RS4_BE   10          MIPS RS4000 Big-Endian
RESERVED       11-16         Reserved for future use

4. Membres supplémentaires

Outre les trois membres ci-dessus, il compte également les membres suivants :

  • e_version :ce membre fournit les informations de version du fichier objet ELF.
  • e_entry :ce membre fournit les informations d'adresse virtuelle du point d'entrée auquel le système doit transférer le contrôle afin que le processus puisse être lancé.
  • e_phoff :ce membre contient le décalage vers la table d'en-tête du programme. Ces informations sont stockées en termes d'octets. En l'absence de table d'en-tête de programme, l'information contenue par ce membre est nulle.
  • e_shoff :ce membre contient le décalage vers la table d'en-tête de section. Comme avec e_phoff, cette information est également stockée sous forme d'octets et en l'absence d'une table d'en-tête de section, l'information contenue par ce champ est nulle.
  • e_flags :ce membre contient des informations relatives à des drapeaux spécifiques au processus.
  • e_ehsize :ce membre contient des informations relatives à la taille de l'en-tête ELF en byes.
  • e_phentsize :ce membre contient des informations relatives à la taille d'une entrée dans la table d'en-tête du programme du fichier objet. Notez que toutes les entrées ont la même taille.
  • e_phnum :ce membre contient les informations relatives au nombre d'entrées dans la table d'en-tête du programme.
  • e_shentsize :ce membre contient les informations relatives à la taille d'une entrée dans la table d'en-tête de section. La taille est représentée sous forme de nombre d'octets.
  • e_shnum :ce membre donne les informations relatives au nombre d'entrées dans la table d'en-tête de section.

Notez que le produit de ephnum et ephentsize donne la taille totale de la table d'en-tête du programme en octets et de la même manière le produit de eshnum et eshentsize donne la taille totale de la table d'en-tête de section en octets.


Linux
  1. Bases des autorisations de fichiers Linux

  2. Comment rediriger la sortie vers un fichier et Stdout sous Linux

  3. Comment décompresser le format de fichier .xz sous Linux à l'aide des utilitaires tar et xz ?

  4. Exemples de commandes Linux Objcopy pour copier et traduire des fichiers objets

  5. glibc :fichier elf OS ABI invalide

Comment monter et démonter des systèmes de fichiers sous Linux

Commande Ls sous Linux (liste des fichiers et des répertoires)

Principes de base de Linux :comment masquer, verrouiller, chiffrer et sécuriser vos fichiers sous Linux

Fichier hôte Linux :comment le modifier et l'utiliser ?

Une introduction au hachage et aux sommes de contrôle sous Linux

Principes de base de la liaison Ethernet sous Linux