## 簡述
> 這份筆記是 [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`,但是不保證程式的正確性。