2010-06-15 11 views
42

Durante le varie fasi di compilazione in C o C++, so che viene generato un file oggetto (ad esempio, un file any_name.o). Cosa contiene questo file .o? Non riesco ad aprirlo dato che si tratta di un file binario.Che cosa contiene un file oggetto?

Qualcuno potrebbe aiutarmi? I contenuti del file oggetto dipendono principalmente dal compilatore che usiamo su Unix?

+1

Ci sono un sacco di strumenti * nix per guardare all'interno di un file oggetto: inizia con nm, http://unixhelp.ed.ac.uk/CGI/man-cgi?nm –

risposta

45

file oggetto possono contenere un sacco di roba: In pratica è una parte o tutta la lista qui sotto:

  • nomi dei simboli
  • codice compilato
  • dati costanti, ad es.stringhe
  • Importazioni - quali simboli il codice compilato fa riferimento (viene corretto dal linker)
  • Esportazioni - quali simboli il file oggetto rende disponibili per altri file oggetto.

Il linker trasforma un gruppo di file oggetto in un file eseguibile, facendo corrispondere tutte le importazioni e le esportazioni e modificando il codice compilato in modo che vengano richiamate le funzioni corrette.

3

Utilizzare il comando file per cose come questa. È un file oggetto ELF su un moderno sistema Linux. Per esempio. se compilato per x86 a 32 bit.

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

Al contrario, un eseguibile collegato dinamicamente potrebbe essere simile:

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

Per vedere le intestazioni, tra cui nomi di sezione, è possibile utilizzare:

objdump -x any_name.o 

di smontare:

objdump -d any_name.o 
3

L'oggetto il file è la fonte compilata.

Ciò significa che è un codice macchina, che dipende dalla piattaforma di destinazione (è possibile compilare per Unix su Windows se lo si desidera realmente) e il compilatore utilizzato. Diversi compilatori produrranno un codice macchina diverso dallo stesso file sorgente.

5

Leggere innanzitutto lo wiki page. È possibile utilizzare objdump ad esaminare tale file :)

1

Il file contiene dati binari che deve essere eseguito attraverso un linker per generare un file eseguibile. È essenzialmente una serie di istruzioni di codice macchina con sezioni denominate (corrispondenti alle tue funzioni). Da Wikipedia di 'Object File' articolo:

In informatica, un file oggetto è una raccolta organizzata di separati, sequenze denominate di codice macchina [citazione necessaria]. Ogni sequenza, o oggetto, tipicamente contiene istruzioni per computer host per realizzare qualche operazione, eventualmente accompagnata da dati correlati metadati (es trasferimento informazione, pila svolgimento informazioni, commenti, programma simboli, debugging o profilatura informazioni). Un linker è in genere utilizzato per generare un file eseguibile o libreria combinando parti di file oggetto .

7

Esistono diversi formati standardizzati (COFF, ELF su Unix), in pratica sono varianti degli stessi formati di quelli utilizzati per i file eseguibili ma mancano alcune informazioni. Queste informazioni mancanti saranno completate durante il collegamento.

Oggetti formati di file fondamentalmente contiene le stesse informazioni:

  • codice binario risultante della compilazione (per un processore di destinazione)
  • dati statici utilizzati da quella parte del programma (come stringhe costanti, ecc). È possibile fare una distinzione più precisa tra BSS (dati esportati) e Testo (dati che non saranno modificati dal programma). Ma questo è per lo più importante per il compilatore e il linker. Nota che come il codice binario, i dati dipendono anche dal target (big-endian, little-endian, 32bit, 64bit).
  • tabelle di simboli esportati da questa parte del programma (per lo più funzioni punti di ingresso)
  • tabelle di simboli esterni utilizzati da questa parte del programma

Quando gli oggetti saranno collegati insieme le parti del codice quello che si riferisce ai simboli esterni sarà sostituito da valori effettivi (beh, che è ancora semplificato, c'è un'ultima parte che verrà eseguita al momento del caricamento quando si esegue il programma, ma questa è l'idea).

Il file oggetto può contenere anche ulteriori informazioni sui simboli strettamente necessarie per la risoluzione delle importazioni e dell'esportazione (utile per il debug). Questa informazione può essere rimossa usando il comando strip.

1

Nell'ambiente di compilazione GNU è possibile cercare con objdump sia nell'eseguibile che nel file oggetto.

Come si può vedere l'oggetto contiene solo il codice delle funzioni dichiarate/referenziate all'interno del file compilato (il file contiene solo la funzione principale con una chiamata scanf e una chiamata 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 

Se si utilizza objdump su un file eseguibile è possibile vedere molto più funzioni (oltre a quelli che si trovano all'interno dell'oggetto). Ciò dimostra che il file oggetto contiene solo le funzioni definite nel file sorgente con riferimenti ad altre funzioni. Questi riferimenti verranno risolti nella fase di collegamento.

Ulteriori informazioni su linking, compilation e objects.

+0

Ho usato MinGW sotto Windows per esempio sopra: funziona allo stesso modo sotto * nix – INS

3

In primo luogo, i file binari possono essere aperti! Non aver paura di questo, hai bisogno solo degli strumenti giusti! Essendo dati binari, un editor di testo non è lo strumento giusto, naturalmente; uno strumento giusto potrebbe essere un editor esadecimale, o un editor avanzato come emacs, o uno strumento che invece di "esportare" semplicemente i byte nella loro rappresentazione "esadecimale" e che ti lascia solo con la tua interpretazione dei dati, conosce quel particolare formato e " interpreta "correttamente i dati, ad un certo livello (esGIMP interpreta un file PNG come immagine e lo mostra, un analizzatore PNG "decomporrà" i dati all'interno delle sezioni PNG mostrando che indicano i flag in determinati byte, ... ecc.).

Nel tuo caso, la risposta generale è che il file oggetto contiene il codice (e i dati) compilato, più tutte le informazioni aggiuntive necessarie dal linker e, infine, più.

Come queste informazioni sono "organizzate" e in alcuni casi in ciò che "alla fine più" consiste, dipende dal formato oggetto specifico. Alcuni link wikipedia sfogliare alcune delle possibilità sono this, this, this, this ...

Ognuno di questi può avere i suoi strumenti per analizzare il contenuto; per esempio. readelf per ELF, objdump per diversi formati (prova objdump -i) a seconda di come è stato compilato.

Problemi correlati