2012-11-19 23 views
17

Tôi hiện đang làm việc trên một dự án trình biên dịch bằng cách sử dụng llvm. Tôi đã làm theo hướng dẫn khác nhau đến điểm mà tôi có một trình phân tích cú pháp để tạo ra một cây cú pháp và sau đó cây được chuyển đổi thành một mô đun llvm bằng cách sử dụng IRBuilder được cung cấp.Cách tạo mã máy với llvm

Mục tiêu của tôi là tạo một tệp thực thi và tôi bị nhầm lẫn là phải làm gì tiếp theo. Tất cả các hướng dẫn tôi đã tìm thấy chỉ cần tạo ra các module llvm và in ra lắp ráp bằng cách sử dụng Module.dump(). Ngoài ra, tài liệu duy nhất tôi có thể tìm thấy là dành cho nhà phát triển llvm và không phải là người dùng cuối của dự án.

Nếu tôi muốn tạo mã máy, các bước tiếp theo là gì? Dự án llvm-mc trông giống như nó có thể làm những gì tôi muốn, nhưng tôi không thể tìm thấy bất kỳ loại tài liệu nào trên đó.

Có lẽ tôi đang mong đợi sẽ làm điều gì đó mà nó không làm. Mong đợi của tôi là tôi có thể xây dựng một Module, sau đó sẽ có một API mà tôi có thể gọi với Module và một mục tiêu ba và một tập tin đối tượng sẽ được sản xuất. Tôi đã tìm thấy tài liệu và ví dụ về sản xuất một JIT, và tôi không quan tâm đến điều đó. Tôi đang tìm cách tạo ra các tệp nhị phân đã biên dịch.

Tôi đang làm việc trên OS X, nếu điều đó có bất kỳ tác động nào.

Trả lời

13

Sử dụng llc -filetype=obj để phát ra tệp đối tượng có thể liên kết từ IR của bạn. Bạn có thể xem mã số llc để xem các cuộc gọi API LLVM mà nó tạo ra để phát ra mã như vậy. Ít nhất đối với Mac OS X và Linux, các đối tượng được phát ra theo cách như vậy sẽ khá tốt (tức là đây không phải là tùy chọn "chất lượng alpha").

LLVM không chứa trình liên kết (tuy nhiên!), Tuy nhiên. Vì vậy, để thực sự liên kết tệp đối tượng này vào một số thư viện thực thi hoặc được chia sẻ, bạn sẽ cần sử dụng trình liên kết hệ thống. Lưu ý rằng ngay cả khi bạn có một tệp thực thi bao gồm một tệp đối tượng duy nhất, thì tệp sau phải được liên kết. Các nhà phát triển trong cộng đồng LLVM đang làm việc trên một liên kết thực sự cho LLVM, được gọi là lld. Bạn có thể truy cập its page hoặc tìm kiếm lưu trữ danh sách gửi thư để theo dõi tiến trình của nó.

14

Như bạn có thể đọc trên the llc guide, nó thực sự có ý định chỉ tạo hội đồng, và sau đó "Đầu ra ngôn ngữ lắp ráp có thể được truyền qua bộ ghép gốc và trình liên kết để tạo tệp thực thi nguyên gốc" - ví dụ: bộ kết hợp gnu (as) và trình liên kết (ld).

Vì vậy, câu trả lời chính ở đây là sử dụng các công cụ gốc để lắp ráp và liên kết.

Tuy nhiên, có hỗ trợ thực nghiệm để tạo ra các đối tượng có nguồn gốc trực tiếp từ một file IR, qua llc:

-filetype  - Choose a file type (not all types are supported by all targets): 
    =asm   - Emit an assembly ('.s') file 
    =obj   - Emit a native object ('.o') file [experimental] 

Hoặc bạn có thể sử dụng llvm-mc để lắp ráp nó từ .s file:

-filetype  - Choose an output file type: 
    =asm   - Emit an assembly ('.s') file 
    =null  - Don't emit anything (for timing purposes) 
    =obj   - Emit a native object ('.o') file 

Tuy nhiên, tôi không biết về những người liên kết.

Ngoài ra, tôi khuyên bạn nên kiểm tra tệp tools/bugpoint/ToolRunner.h, cho thấy trình bao bọc kết hợp llc và chuỗi công cụ C gốc của nền tảng để tạo mã máy. Từ nhận xét tiêu đề của nó:

Tệp này thể hiện sự trừu tượng xung quanh trình biên dịch C nền tảng, được sử dụng để biên dịch mã C và lắp ráp.

1

Để chạy chương trình ví dụ BrainF, biên dịch và chạy:

echo ,. > test.bf 
./BrainF test.bf -o test.bc 
llc -filetype=obj test.bc 
gcc test.o -o a.out 
./a.out 

sau đó gõ một chữ cái và nhấn Enter. Nó sẽ lặp lại bức thư đó cho bạn. (Đó là những gì ,..)

Ở trên đã được thử nghiệm với LLVM phiên bản 3.5.0.

4

Kiểm tra các chức năng này trong llvm-c/TargetMachine.h:

/** Emits an asm or object file for the given module to the filename. This 
    wraps several c++ only classes (among them a file stream). Returns any 
    error in ErrorMessage. Use LLVMDisposeMessage to dispose the message. */ 
LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M, 
    char *Filename, LLVMCodeGenFileType codegen, char **ErrorMessage); 

/** Compile the LLVM IR stored in \p M and store the result in \p OutMemBuf. */ 
LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T, LLVMModuleRef M, 
    LLVMCodeGenFileType codegen, char** ErrorMessage, LLVMMemoryBufferRef *OutMemBuf); 
Các vấn đề liên quan