2010-08-09 37 views
8

Tôi quan tâm đến việc tạo ngôn ngữ và xây dựng trình biên dịch, và đã làm việc thông qua ví dụ ở đây: http://gnuu.org/2009/09/18/writing-your-own-toy-compiler/. Tác giả đã sử dụng LLVM 2.6 và sau khi thực hiện một vài thay đổi cho LLVM 2.7, tôi đã nhận được tất cả mã tạo mã để biên dịch. Khi cung cấp mã kiểm tra, mã kiểm tra,Tạo mã LLVM gây ra lỗi seg?

int do_math(int a) { 
    int x = a * 5 + 3 
} 

do_math(10) 

chương trình hoạt động chính xác cho đến khi nó cố gắng chạy mã, tại thời điểm nó phân tách. Tôi đang trong quá trình xây dựng LLDB trên hệ thống của tôi, nhưng trong khi chờ đợi, bất cứ ai nhìn thấy một lỗi seg rõ ràng trong ASV LLVM này?

; ModuleID = 'main' 

define internal void @main() { 
entry: 
    %0 = call i64 @do_math(i64 10)     ; <i64> [#uses=0] 
    ret void 
} 

define internal i64 @do_math(i64) { 
entry: 
    %a = alloca i64         ; <i64*> [#uses=1] 
    %x = alloca i64         ; <i64*> [#uses=1] 
    %1 = add i64 5, 3        ; <i64> [#uses=1] 
    %2 = load i64* %a        ; <i64> [#uses=1] 
    %3 = mul i64 %2, %1        ; <i64> [#uses=1] 
    store i64 %3, i64* %x 
    ret void 
} 

Kết quả chỉ là:

Segmentation fault 

vòm của tôi là OS X x86_64.

Cảm ơn.

Trả lời

15

Tôi gặp vấn đề tương tự. Tôi lột bỏ trình biên dịch của Loren và mọi thứ đều hoạt động tốt ngoại trừ việc thi hành.

lỗi Segmentation được gây ra bởi thực tế là:

ExecutionEngine * ee = EngineBuilder (mô-đun) .Create();

trả về NULL. Để xem lỗi thực tế, bạn cần nhận chuỗi lỗi:

std :: string error; ExecutionEngine * ee = EngineBuilder (mô-đun) .setErrorStr (& lỗi) .create();

Trong trường hợp của bạn có lẽ bạn nên xem:

"Không tìm thấy mục tiêu cho ba này (không có mục tiêu đã được đăng ký)

Để khắc phục điều đó bạn cần phải gọi

InitializeNativeTarget();

Nhưng nếu bạn nhận được:

JIT chưa được liên kết.

Bạn nên bao gồm:

llvm/ExecutionEngine/MCJIT.h

đó sẽ liên kết động cơ JIT.

0

LLVM ASM bạn đã đăng không phải là bản dịch chính xác của mã C bạn đã trình bày. Bạn đang phân bổ %a làm biến ngăn xếp và sau đó tải dữ liệu chưa được khởi tạo từ nó và sử dụng nó. Những gì bạn muốn để làm là đặt tên đối số của bạn %a và sử dụng giá trị đó. Hãy thử sử dụng mã này để thay thế:

define internal i64 @do_math(i64 %a) { 
entry: 
    %x = alloca i64         ; <i64*> [#uses=1] 
    %1 = add i64 5, 3        ; <i64> [#uses=1] 
    %2 = mul i64 %a, %1        ; <i64> [#uses=1] 
    store i64 %2, i64* %x 
    ret void 
} 

Ngoài ra, nguyên mẫu main() của bạn có thể không khớp với thư viện thời gian chạy C của bạn. Và, ngoài ra, bạn nhận ra rằng bạn không trả lại kết quả từ do_math(), phải không?

+0

Mã không chính xác 'Mã C', đó là ngôn ngữ giống như C, được xây dựng trong hướng dẫn tôi liên kết đến. Tôi hiểu rằng hàm 'do_math' không trả về int như nó nói. ASM được tạo ra từ một mã AST và một số mã tạo mã, vì vậy tôi sẽ xem liệu tôi có thể tìm hiểu tại sao nó đang cố gắng sử dụng dữ liệu chưa được khởi tạo hay không. –

Các vấn đề liên quan