## 簡述 > 這份筆記是 [C2Rust for Linux Kernel](/IR2_2mL7QTe_riQJzbPl-g) 的一部份。 這份筆記延伸了 [C2Rust on SeKVM:BootAux.c](/Q9tIBLzEQlyTstvpJWMKhw) 的實驗結果,進一步找出核心的哪些標頭無法被 C2Rust 轉譯。 此實驗走訪每個 `hypsec.h` 中引用的標頭,尋找第一個 C2Rust 無法轉譯的程式碼區塊。實驗結果發現 GNU C 語法以及部分內嵌組合語言是 C2Rust 無法轉譯的程式碼,而此段程式碼存在於 `<linux/kernel.h>` 中,大量的核心程式碼都會直接或間接引用這個標頭檔,因此要自動轉譯 Linux 核心至 Rust 語言是困難的,更別說可能還有其他無法轉譯的程式碼。 ## 搜尋第一個無法轉換的程式碼區塊 1. `<asm/kvm_asm.h>` 2. `<linux/mm.h>` 3. `<linux/gfp.h>` 4. `<linux/mmzone.h>` 5. `<linux/spinlock.h>` 6. `<linux/bottom_half.h>` 在 `<linux/bottom_half.h>` 中的以下程式碼會導致轉譯失敗: ```c=17 static inline void local_bh_disable(void) { __local_bh_disable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET); } ``` 以下是 C2Rust 的輸出,雖然它表示這是一個 `warning`,但是我在輸出中搜尋不到 `error`,所以根據內容: > Cannot translate GNU address of label expression 我推測這就是一個 `error`。錯誤的原因是 Linux 核心使用了 GNU C 的特有語法,這是 C2Rust 目前沒有辦法轉譯的。 ```c ./include/linux/bottom_half_toy.h:19:24: warning: c2rust: Cannot translate GNU address of label expression 19 | __local_bh_disable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET); | ^~~~~~~~~ ./include/linux/kernel.h:58:64: note: expanded from macro '_THIS_IP_' 58 | #define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; }) | ^~ ``` ## 其他無法轉換的程式碼區塊 我嘗試直接轉換 `BootAux.c`,並從輸出中搜尋 `Cannot` 或 `translate`,發現以下無法轉換的區塊: ```c ./include/linux/bottom_half.h:19:24: warning: c2rust: Cannot translate GNU address of label expression 19 | __local_bh_disable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET); | ^~~~~~~~~ ./include/linux/kernel.h:58:64: note: expanded from macro '_THIS_IP_' 58 | #define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; }) | ^~ ./include/linux/bottom_half.h:32:23: warning: c2rust: Cannot translate GNU address of label expression 32 | __local_bh_enable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET); | ^~~~~~~~~ ./include/linux/kernel.h:58:64: note: expanded from macro '_THIS_IP_' 58 | #define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; }) | ^~ ``` 另外轉換了 `Helper.c`,發現部分的內嵌組合語言無法轉換: ```c=226 asm volatile ( "ldrb w26, [%1, %2]\n\t" "dsb ld\n\t" "mov %0, x26\n\t" :"=r"(ret) :"r"(base), "r"(REG_FR) :"x26", "cc" ); ``` 我測試過只有 `nop` 是可以轉譯的,只留下以上六行的其中 2-4 行也可以轉譯,因為我對組合語言不熟悉,所以沒辦法進一步找出問題,但至少我們得知部分組合語言是 C2Rust 無法轉換的。 ## 會產生警告的程式碼區塊 轉譯 `BootAux.c` 遇到的警告如下所示。 ### Unsupported Generic Selection Expression `<linux/compiler_types.h>`: ```c=278 #define __unqual_scalar_typeof(x) typeof( \ _Generic((x), \ char: (char)0, \ __scalar_type_to_expr_cases(char), \ __scalar_type_to_expr_cases(short), \ __scalar_type_to_expr_cases(int), \ __scalar_type_to_expr_cases(long), \ __scalar_type_to_expr_cases(long long), \ default: (x))) ``` 這段程式碼會讓 C2Rust 產生以下警告,但不確定 C2Rust 會如何處理: ``` warning: c2rust: Encountered unsupported generic selection expression ``` ### Exported Clang AST Was Invalid 這是出現頻率最多的警告,然而這些訊息並沒有指出警告來源。 ``` warning: Missing child 198234981051632 of node AstNode { tag: TagBinaryOperator, children: [Some(198234981051632), Some(198234981051824)], loc: SrcSpan { fileid: 203, begin_line: 247, begin_column: 24, end_line: 247, end_column: 24 }, type_id: Some(198234974708704), rvalue: RValue, macro_expansions: [], macro_expansion_text: None, extras: [Text("||"), Null, Null] } Exported Clang AST was invalid. Check warnings above for unimplemented features. --> /home/natsucamellia/Workspace/linux-sekvm-rust/include/linux/math64.h:247:24 [-Wclang-ast] ``` --- 另外也嘗試轉譯了 `lib/llist.c`,除了以上的警告外,還有以下警告: ### Did Not Recognize Inline ASM Constraint ``` warning: Did not recognize inline asm constraint: Kr It is likely that this will cause compilation errors or incorrect semantics in the translated program; please manually correct. warning: Did not recognize inline asm constraint: Lr It is likely that this will cause compilation errors or incorrect semantics in the translated program; please manually correct. ``` 得知 `Kr` 與 `Lr` 也是 C2Rust 無法轉換的組合語言語法,雖然 C2Rust 會回傳 `EXIT_SUCCESS`,但是不保證程式的正確性。