web-dev-qa-db-fra.com

Que contient un fichier objet?

Au cours des différentes étapes de la compilation en C ou C++, je sais qu'un fichier objet est généré (c'est-à-dire un fichier any_name.o). Que contient ce fichier .o? Je ne peux pas l'ouvrir car c'est un fichier binaire.

Quelqu'un pourrait-il m'aider? Le contenu du fichier objet dépend-il principalement du compilateur que nous utilisons sous Unix?

45
Vijay

Les fichiers objets peuvent contenir un tas de choses: Fondamentalement, c'est tout ou partie de la liste ci-dessous:

  • Noms des symboles
  • Code compilé
  • Des données constantes, par exemple. cordes
  • Importations - quels symboles les références de code compilées (corrigées par l'éditeur de liens)
  • Exportations - quels symboles le fichier objet met à la disposition des AUTRES fichiers objet.

L'éditeur de liens transforme un tas de fichiers objets en un exécutable, en faisant correspondre toutes les importations et les exportations, et en modifiant le code compilé afin que les fonctions correctes soient appelées.

47
Roddy

Il existe plusieurs formats standardisés (COFF, ELF sur Unix), en gros ce sont des variantes des mêmes formats que ceux utilisés pour les exécutables mais sans informations. Ces informations manquantes seront complétées lors de la liaison.

Les formats de fichiers objets contiennent essentiellement les mêmes informations:

  • code binaire résultant de la compilation (pour un processeur cible)
  • données statiques utilisées par cette partie du programme (comme les chaînes constantes, etc.). Vous pouvez faire une distinction plus fine entre BSS (données exportées) et Texte (données qui ne seront pas modifiées par le programme). Mais c'est surtout important pour le compilateur et l'éditeur de liens. Notez que comme le code binaire, les données dépendent également de la cible (big-endian, little-endian, 32bits, 64bits).
  • tableaux de symboles exportés par cette partie du programme (fonctions principalement des points d'entrée)
  • tableaux de symboles externes utilisés par cette partie du programme

Lorsque les objets seront liés entre eux, les parties du code qui se réfèrent aux symboles externes seront remplacées par des valeurs réelles (enfin, c'est encore trop simplifié, il y a une dernière partie qui sera effectuée au moment du chargement lors de l'exécution du programme, mais c'est la idée).

Le fichier objet peut également contenir plus d'informations sur les symboles strictement nécessaires à la résolution des importations et des exportations (utile pour le débogage). Ces informations peuvent être supprimées à l'aide de la commande strip.

8
kriss

Lisez d'abord la page wiki . Vous pouvez utiliser objdump pour examiner un tel fichier :)

5
Daniel Băluţă

Utilisez la commande file pour des choses comme celle-ci. C'est un ELFE fichier objet sur un système Linux moderne. Par exemple. si compilé pour x86 32 bits.

ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped

En revanche, un exécutable lié dynamiquement pourrait ressembler à:

ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped

Pour voir les en-têtes, y compris les noms de section, vous pouvez utiliser:

objdump -x any_name.o

Pour démonter:

objdump -d any_name.o
4
Matthew Flaschen

Tout d'abord, les fichiers binaires peuvent être ouverts! N'ayez pas peur, vous avez juste besoin des bons outils! Etant des données binaires, un éditeur de texte n'est bien sûr pas le bon outil; un bon outil pourrait être un éditeur hexadécimal, ou un éditeur avancé comme emacs, ou un outil qui, au lieu de simplement "produire" des octets dans leur représentation "hexadécimale" et de vous laisser seul avec votre interprétation des données, connaît ce format particulier et " interprète "correctement les données, à un certain niveau (par exemple, GIMP interprète un fichier PNG comme une image et l'affiche, un analyseur PNG" décompose "les données à l'intérieur des sections PNG en vous indiquant les drapeaux dans certains octets, ... etc).

Dans votre cas, la réponse générale est que le fichier objet contient votre code compilé (et vos données), ainsi que toutes les informations supplémentaires nécessaires à l'éditeur de liens, et éventuellement plus.

La façon dont ces informations sont "organisées" et, dans certains cas, en quoi consiste "éventuellement plus", cela dépend du format d'objet spécifique. Certains liens wikipedia énumérant certaines des possibilités sont this , this , this , this ...

Chacun d'eux peut avoir ses outils pour analyser le contenu; par exemple. readelf pour ELF, objdump pour plusieurs formats (essayez objdump -i) selon la façon dont il a été compilé.

3
ShinTakezou

Le fichier objet est la source compilée.

Cela signifie que c'est le code machine, qui dépend de la plate-forme cible (vous pouvez compiler pour Unix sur Windows si vous le voulez vraiment) et du compilateur utilisé. Différents compilateurs produiront un code machine différent à partir du même fichier source.

3
ChrisF

Le fichier contient des données binaires qui doivent être exécutées via un linker pour générer un exécutable. Il s'agit essentiellement d'un tas d'instructions de code machine avec des sections nommées (correspondant à vos fonctions). De l'article ' Object File ' de wikipedia:

En informatique, un fichier objet est une collection organisée de séquences distinctes et nommées de code machine [citation nécessaire]. Chaque séquence ou objet contient généralement des instructions pour que la machine hôte accomplisse une tâche, éventuellement accompagnée de données et de métadonnées connexes (par exemple, informations de relocalisation, informations de déroulement de pile, commentaires, symboles de programme, informations de débogage ou de profilage). Un éditeur de liens est généralement utilisé pour générer un exécutable ou une bibliothèque en combinant des parties de fichiers objets.

1
soulmerge

Dans l'environnement de compilation GNU, vous pouvez regarder avec objdump à la fois dans l'exécutable et dans le fichier objet.

Comme vous pouvez le voir, l'objet ne contient que le code des fonctions déclarées/référencées dans le fichier compilé (le fichier ne contient que la fonction principale avec un appel scanf et un appel printf).

$ objdump -t scanf_sample.o

scanf_sample.o:     file format pe-i386

SYMBOL TABLE:
[  0](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x00000000 scanf_sample.c
File
[  2](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _main
[  3](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .text
AUX scnlen 0x91 nreloc 9 nlnno 0
[  5](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .data
AUX scnlen 0x0 nreloc 0 nlnno 0
[  7](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .bss
AUX scnlen 0x0 nreloc 0 nlnno 0
[  9](sec  4)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .rdata
AUX scnlen 0x54 nreloc 0 nlnno 0
[ 11](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x00000000 ___main
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[ 13](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __alloca
[ 14](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _memset
[ 15](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _scanf
[ 16](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _printf

Si vous utilisez objdump sur un exécutable, vous pouvez voir beaucoup plus de fonctions (en plus de celles trouvées à l'intérieur de l'objet). Cela prouve que le fichier objet contient uniquement les fonctions définies dans le fichier source avec des références à d'autres fonctions. Ces références seront résolues lors de la phase de liaison.

En savoir plus sur liaison , compilation et objets .

1
INS