2017-08-24 21 views
5

के साथ चलने पर तर्क प्रकार के मुख्य के बारे में त्रुटि देता है, मैं एलएलवीएम आईआर के बारे में कुछ सीखने की कोशिश कर रहा हूं, विशेष रूप से वास्तव में क्या rustc outputs। मुझे एक बहुत ही साधारण मामला चलाने में परेशानी का सामना करना पड़ रहा है।rustc द्वारा उत्पादित एलएलवीएम lli

मैं एक स्रोत फ़ाइल simple.rs में निम्नलिखित डाल:

fn main() { 
    let x = 7u32; 
    let y = x + 2; 
} 

और rustc --emit llvm-ir simple.rs चलाने फ़ाइल simple.ll प्राप्त करने के लिए, युक्त

; ModuleID = 'simple.cgu-0.rs' 
source_filename = "simple.cgu-0.rs" 
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 
target triple = "x86_64-unknown-linux-gnu" 

; Function Attrs: uwtable 
define internal void @_ZN6simple4main17h8ac50d7470339b75E() unnamed_addr #0 { 
start: 
    br label %bb1 

bb1:            ; preds = %start 
    ret void 
} 

define i64 @main(i64, i8**) unnamed_addr { 
top: 
    %2 = call i64 @_ZN3std2rt10lang_start17ha09816a4e25587eaE(void()* @_ZN6simple4main17h8ac50d7470339b75E, i64 %0, i8** %1) 
    ret i64 %2 
} 

declare i64 @_ZN3std2rt10lang_start17ha09816a4e25587eaE(void()*, i64, i8**) unnamed_addr 

attributes #0 = { uwtable } 

!llvm.module.flags = !{!0} 

!0 = !{i32 1, !"PIE Level", i32 2} 

मैं तो आदेश के साथ इस चलाने का प्रयास

lli-3.9 -load ~/.multirust/toolchains/nightly-x86_64-unknown-linux-gnu/lib/libstd-35ad9950c7e5074b.so simple.ll 

लेकिन मुझे त्रुटि संदेश मिलता है ई

LLVM ERROR: Invalid type for first argument of main() supplied 

मैं इस प्रकार इस का एक न्यूनतम प्रजनन करने में सक्षम हूँ: मैं एक फ़ाइल s2.ll कहा जाता है बनाने के लिए,

define i32 @main(i64, i8**) { 
    ret i32 42 
} 

युक्त और lli-3.9 s2.ll चल ही त्रुटि संदेश देता है। लेकिन अगर मैं

define i32 @main(i32, i8**) { 
    ret i32 42 
} 

(अर्थात मैं मुख्य में argc के प्रकार को बदल दिया है) तो lli-3.9 s2.ll रन के लिए s2.ll की सामग्री को बदलने के लिए, और echo $? पता चलता है कि यह वास्तव में वापस किया 42

मुझे नहीं लगता कि मुझे i64 में स्पष्ट रूप से पास करना होगा - मेरी तर्क सूची या सी तारों को स्मृति में कहीं भी रखा जाना चाहिए और सूचक और लंबाई main पर स्वचालित रूप से पास होनी चाहिए, है ना? इसलिए मुझे लगता है कि मैं lli का आह्वान करने के तरीके में कुछ गलत कर रहा हूं - लेकिन मुझे नहीं पता कि क्या।

उत्तर

5

जंग (, समारोह #[start] विशेषता के साथ चिह्नित डिफ़ॉल्ट मानक पुस्तकालय में समारोह lang_start द्वारा) ने अपने प्रवेश बिंदु के निशान प्रकार isize के argc पैरामीटर लेने के रूप में। This is a bug क्योंकि इसमें सी int का प्रकार होना चाहिए, इसलिए यह 64-बिट प्लेटफ़ॉर्म पर 32 बिट्स होना चाहिए, लेकिन isize 64 बिट्स है। हालांकि, जिस तरह से 64-बिट कॉलिंग सम्मेलन काम करते हैं, यह अभी भी सही तरीके से काम करता है। रिटर्न प्रकार के लिए भी यही समस्या मौजूद है।

A fix इसके लिए 2017-10-01 को किया गया है और जंग 1.22 में मौजूद होना चाहिए।

llimain के प्रकार की जांच करने के बारे में स्पष्ट रूप से अधिक सख्त है, यही कारण है कि यह त्रुटि देता है। लेकिन यदि आप इसके बजाय llc का उपयोग करते हैं, तो इसे सही तरीके से काम करना चाहिए।

सही main हस्ताक्षर पाने के लिए आपको मॉड्यूल के शीर्ष पर #![no_main] डालकर डिफ़ॉल्ट main रद्द कर सकते हैं, और उपलब्ध कराने के अपने खुद के main#[no_mangle] के साथ चिह्नित। लेकिन ध्यान दें कि यह मानक पुस्तकालय के प्रारंभिकरण को छोड़ देगा।

#![no_main] 

#[no_mangle] 
pub extern fn main(_argc: i32, _argv: *const *const u8) -> i32 { 
    0 
} 

यह भी देखें:

संबंधित मुद्दे