Aquí está la traducción más cercana al comando de enlace de Linux para realizar la incrustación binario con el enlazador 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
se almacenarán en el segmento binary
, sección foo_bin
(ambos nombres son arbitrario pero elegido para imitar GNU ld para ELF en Linux) del objeto foo.o
.
stub
es necesario porque ld
se niega a crear solo un segmento/sección personalizado. No lo necesita si link directly with a real code object.
para obtener datos de vuelta de la sección, utilice getsectbyname (struct se define en 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
(I utilizado para almacenar datos de texto, de ahí el stringification vía calloc
puesta a cero del tamaño + 1 más copia de blob)
Warning: Desde 10.7, ASLR se volvió más fuerte y se equivoca con las funciones getsect*
, lo que da como resultado segfaults. set disable-aslr off
en GDB antes de run
para reproducir EXC_BAD_ACCESS (SIGSEGV) en condiciones de depuración. La gente tenía que llamar al jump through inordinate hoops para encontrar la dirección real y hacer que esto funcione de nuevo.
A simple workaround es obtener el desplazamiento y el tamaño, abrir el binario y leer los datos directamente desde el disco. Este es un ejemplo de trabajo:
// 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);
}
solo deberías hacer algo como 'ld -dylib -o libFoo.dylib fooSource * .o'. el problema parece ser con foo.bin - si haces 'file foo.bin' ¿qué dice? –
La salida del archivo foo.bin es: 'foo.bit: Xilinx datos BIT - de foo.ncd; HW_TIMEOUT = FALSE; nosotros - para 0xFFFFFFFF - construido slx16ftg256 (011/03/15) - longitud de datos 0x31373a35' – Satpal
hmm Me temo que no parece que LLVM clang ld haga la inserción de blobs binarios que hace el gnu ld.es posible que desee intentar instalar gcc desde macports (http://www.macports.org/)? no estoy seguro si eso ayudaría, pero podría valer la pena intentarlo. –