2010-04-13 3 views
40

Sto cercando di incorporare blob binari in un file exe. Sto usando mingw gcc.Incorporamento di blob binari utilizzando gcc mingw

Faccio il file oggetto come questo:

ld -r -b binary -o binary.o input.txt 

Ho poi guardo objdump uscita per ottenere i simboli:

objdump -x binary.o 

e dà simboli chiamati:

_binary_input_txt_start 
_binary_input_txt_end 
_binary_input_txt_size 

I quindi provate ad accedervi nel mio programma C:

#include <stdlib.h> 
#include <stdio.h> 

extern char _binary_input_txt_start[]; 

int main (int argc, char *argv[]) 
{ 
    char *p; 
    p = _binary_input_txt_start; 

    return 0; 
} 

Poi ho compilare in questo modo:

gcc -o test.exe test.c binary.o 

ma ottengo sempre:

undefined reference to _binary_input_txt_start 

Qualcuno sa che cosa sto facendo male?

+7

A proposito, non ero a conoscenza di questo metodo di estrazione di dati arbitrari in un eseguibile: bello. –

+0

Cosa offre questo metodo che non è offerto dai file '.rc'? – rubenvb

+0

@rubenvb Accesso facilitato a contntent. Non ha bisogno di chiamate a qualsiasi API di risorse: s – user877329

risposta

27

Nel programma C rimuovere la sottolineatura:

#include <stdlib.h> 
#include <stdio.h> 

extern char binary_input_txt_start[]; 

int main (int argc, char *argv[]) 
{ 
    char *p; 
    p = binary_input_txt_start; 

    return 0; 
} 

compilatori C spesso (? Sempre) sembrano anteporre una sottolineatura per extern nomi. Non sono del tutto sicuro perché questo è - presumo che ci sia qualcosa di vero this wikipedia article's affermazione che

era pratica comune per i compilatori C anteporre un leader sottolineatura a tutti gli identificatori di programma portata esterni per evitare scontri con il contributo di lingua di runtime supporto

Ma mi colpisce il fatto che, se sono stati sottolineatura anteporre a tutte le persone esterne, allora si sta in realtà non partizionare lo spazio dei nomi molto. Ad ogni modo, questa è una domanda per un altro giorno, e il fatto è che i caratteri di sottolineatura vengono aggiunti.

+0

Wow ... grazie mille. Questo mi stava facendo impazzire. Sapevo che doveva essere qualcosa di semplice. Ho appena eseguito il debug e ho notato che stava cambiando in __binary_input_txt_start – myforwik

+0

@myforwik: nel caso siate interessati, ho postato una domanda che chiede perché C lo fa: http://stackoverflow.com/questions/2627511/why -do-c-compilers-ante-underscores-to-external-names –

+0

@ Michael: L'affermazione dell'articolo è vera. I runtime sono stati scritti in assembler, che era libero di usare nomi privi di underscore e poteva quindi essere sicuro di non scontrarsi con nessun simbolo definito nel codice C, e viceversa il codice C non aveva modo di accedere ai simboli dal codice runtime asm . –

4

L'ho testato su Linux (Ubuntu 10.10).

  1. file di Resouce:
    input.txt

  2. gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 [genera eseguibile ELF, per Linux]
    Genera simbolo _binary__input_txt_start.
    Accetta il simbolo _binary__input_txt_start (con sottolineatura).

  3. i586-mingw32msvc-gcc (GCC) 4.2.1-sjlj (mingw32-2) [genera eseguibile PE, per Windows]
    Genera simbolo _binary__input_txt_start.
    Accetta il simbolo binary__input_txt_start (senza sottolineatura).

+0

Utilizzando tdm-gcc 4.8.1, devo fare riferimento alle variabili usando il trattino basso. – hauzer

3

Da ld man page:

--leading-sottolineatura

--no-leader sottolineano

Per la maggior parte degli obiettivi di default simbolo-prefix è un carattere di sottolineatura ed è definito nella descrizione dell'obiettivo. Con questa opzione è possibile disabilitare/abilitare il prefisso del simbolo di sottolineatura predefinito.

così

ld -r -b binary -o binary.o input.txt --leading-underscore 

dovrebbe essere una soluzione.

0

Apparentemente questa funzione non è presente nel ld di OSX, quindi devi farlo totally differently con un flag gcc personalizzato che hanno aggiunto, e non puoi fare riferimento ai dati direttamente, ma devi fare qualche inizializzazione del runtime per ottenere l'indirizzo .

Quindi potrebbe essere più portatile creare un file di origine assembler che include il file binario in fase di compilazione, a la this answer.