2012-01-19 20 views
6

Sto provando a compilare un file binario in un file oggetto MACH_O in modo che possa essere collegato a un dylib. Il dylib è scritto in c/C++.Compilare un file binario per collegare OSX

In Linux il comando viene utilizzato: ld -r -b binario -o foo.o foo.bin

Ho provato varie opzioni su OSX ma inutilmente:

ld -r foo.bin -o foo.o 
gives: 
ld: warning: -arch not specified 
ld: warning: ignoring file foo.bin, file was built for unsupported file format which is not the architecture being linked (x86_64) 

Viene creato un file .o vuoto

ld -arch x86_64 -r foo.bin -o foo.o 
ld: warning: ignoring file foo.bin, file was built for unsupported file format which is not the architecture being linked (x86_64) 

Nuovo e vuoto .o il file è stato creato. Controllo dei file con nm: nm foo.o nm: nessun nome elenco

Il file binario è in realtà, il firmware che verrà scaricato su un dispositivo esterno.

Ringraziamenti per guardare

+0

si dovrebbe solo fare qualcosa come 'ld -dylib -o libFoo.dylib fooSource * .o'. il problema sembra essere con foo.bin - se fai 'file foo.bin' cosa dice? –

+0

L'output del file foo.bin è: 'foo.bit: dati BIT Xilinx - da foo.ncd; HW_TIMEOUT = FALSE; Us - per 0xFFFFFFFF - costruito slx16ftg256 (011/03/15) - lunghezza dati 0x31373a35' – Satpal

+0

hmm , temo che non assomigli al LLVM clang ld fa il blob blob che incorpora quello che fa gnu ld.potresti provare a installare gcc da macports (http://www.macports.org/)? non sono sicuro che sarebbe d'aiuto, ma potrebbe valere la pena di provarci. –

risposta

7

Ecco la traduzione più vicina al comando del linker Linux per eseguire incorporamento binario con il linker OSX:

touch stub.c 
gcc -o stub.o -c stub.c 
ld -r -o foo.o -sectcreate binary foo_bin foo.bin stub.o 

foo.bin saranno memorizzati nel segmento binary, sezione foo_bin (entrambi i nomi sono arbitrario ma scelto per imitare GNU ld per ELF su Linux) dell'oggetto foo.o.

stub è necessario perché ld si rifiuta di creare solo un segmento/sezione personalizzato. Non è necessario se si link directly with a real code object.

Per ottenere i dati dalla sezione, utilizzare getsectbyname (struct è definita in mach-o/loader.h):

#include <mach-o/getsect.h> 
const struct section_64 *sect = getsectbyname("binary", "foo_bin"); 
char *buffer = calloc(1, sect->size+1); 
memcpy(buffer, sect->addr, sect->size); // whatever 

o getsectdata:

#include <mach-o/getsect.h> 
size_t size; 
char *data = getsectdata("binary", "foo_bin", &size); 
char *buffer = calloc(1, size+1); 
memcpy(buffer, data, size); // whatever 

(ho usato per memorizzare dati di testo, quindi la stringificazione tramite calloc azzeramento di dimensioni + 1 più copia blob)

Avviso: a partire dal 10.7, ASLR è diventato più potente e si comporta male con le funzioni getsect*, con conseguente segfault. set disable-aslr off in GDB prima dello run per riprodurre EXC_BAD_ACCESS (SIGSEGV) in condizioni di debug. Le persone hanno dovuto jump through inordinate hoops per trovare l'indirizzo reale e farlo funzionare di nuovo.

A simple workaround è quello di ottenere l'offset e la dimensione, aprire il file binario e leggere i dati direttamente dal disco. Ecco un esempio:

// main.c, build with gcc -o main main.c foo.o 
#include <stdlib.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <string.h> 
#include <stdio.h> 
#include <mach-o/getsect.h> 

int main() { 
    // finding the filename of the running binary is left as an exercise to the reader 
    char *filename = "main"; 

    const struct section_64 *sect = getsectbyname("binary", "foo_bin"); 
    if (sect == NULL) { 
     exit(1); 
    } 

    char *buffer = calloc(1, sect->size+1); 
    int fd = open(filename, O_RDONLY); 
    if (fd < 0) { 
     exit(1); 
    } 
    lseek(fd, sect->offset, SEEK_SET); 
    if (read(fd, buffer, sect->size) != sect->size) { 
     close(fd); 
     exit(1); 
    } 

    printf("%s", buffer); 
} 
+1

Sembra che ci siano versioni 'getection *' leggermente più recenti delle funzioni 'getsect *' che possono essere utilizzate e che non sono influenzate dai problemi ASLR. Leggermente più bello di dover leggere il binario crudo. –

+0

http://gareus.org/wiki/embedding_resources_in_executables rileva inoltre che il nome della sezione passato a '-sectcreate' non può essere più lungo di ** 16 ** caratteri ... – cfstras