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);
}
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? –
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
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. –