2012-01-19 33 views
6

Tôi đang cố gắng biên dịch tệp nhị phân thành tệp đối tượng MACH_O để nó có thể được liên kết nó thành một dylib. Dylib được viết bằng c/C++.Biên dịch một tệp nhị phân để liên kết OSX

Trên Linux lệnh sau đây được sử dụng: ld -r -b nhị phân -o foo.o foo.bin

Tôi đã cố gắng lựa chọn khác nhau trên OSX nhưng không có kết quả:

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) 

Tệp rỗng .o được tạo

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) 

Tệp .o một lần nữa và trống. Kiểm tra các tệp bằng nm cho: nm foo.o nm: không có danh sách tên

Tệp nhị phân thực sự là phần mềm sẽ được tải xuống thiết bị bên ngoài.

Cám ơn tìm

+0

bạn chỉ cần thực hiện một việc như 'ld -dylib -o libFoo.dylib fooSource * .o'. vấn đề có vẻ là với foo.bin - nếu bạn làm 'tập tin foo.bin' nó nói gì? –

+0

Đầu ra của tệp foo.bin là: 'foo.bit: Dữ liệu BIT Xilinx - từ foo.ncd; HW_TIMEOUT = FALSE; Hệ với chúng tôi - cho 0xFFFFFFFF - được xây dựng slx16ftg256 (011/03/15) - chiều dài dữ liệu 0x31373a35' – Satpal

+0

hmm , Tôi sợ nó không giống như LLVM clang ld hiện blob nhị phân nhúng rằng ld gnu không.bạn có thể thử cài đặt gcc từ macports (http://www.macports.org/)? không chắc chắn nếu điều đó sẽ giúp ích, nhưng có thể đáng để thử. –

Trả lời

7

Dưới đây là bản dịch gần nhất với lệnh linker Linux để thực hiện nhúng nhị phân với các mối liên kết 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 sẽ được lưu trữ trong phân khúc binary, phần foo_bin (cả hai tên là tùy ý nhưng được chọn để bắt chước GNU ld cho ELF trên Linux) của đối tượng foo.o.

stub là cần thiết vì ld từ chối chỉ tạo phân đoạn/mục tùy chỉnh. Bạn không cần nó nếu bạn link directly with a real code object.

Để có được dữ liệu trở lại từ phần, sử dụng getsectbyname (struct được định nghĩa trong 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 

hoặc 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 

(tôi đã sử dụng nó để lưu trữ dữ liệu văn bản, vì thế mà stringification via calloc zeroing of size + 1 plus blob copy)

Cảnh báo: Kể từ 10.7, ASLR trở nên mạnh hơn và gây rối với các chức năng getsect*, dẫn đến các segfaults. set disable-aslr off trong GDB trước run ning để tái tạo EXC_BAD_ACCESS (SIGSEGV) trong điều kiện gỡ lỗi. Mọi người đã phải jump through inordinate hoops để tìm địa chỉ thực và làm cho địa chỉ này hoạt động trở lại.

A simple workaround là lấy độ lệch và kích thước, mở tệp nhị phân và đọc dữ liệu trực tiếp từ đĩa. Dưới đây là ví dụ hoạt động:

// 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

Có vẻ như có phiên bản 'getection *' hơi mới hơn của các hàm 'getect *' có thể được sử dụng và không bị ảnh hưởng bởi các vấn đề ASLR. Hơi đẹp hơn phải đọc nhị phân thô. –

+0

http://gareus.org/wiki/embedding_resources_in_executables cũng lưu ý rằng tên phần được chuyển đến '-sectcreate' không thể dài hơn ** 16 ** ký tự ... – cfstras