immunant / c2rust

Migrate C code to Rust
https://c2rust.com/
Other
3.81k stars 220 forks source link

Linux Kernel Module blog-post example broken due to `_Generic` #982

Open SheldonHH opened 1 year ago

SheldonHH commented 1 year ago

by following the guide from https://immunant.com/blog/2020/06/kernel_modules/ from @Immunant

Using hypervisor 2.1: https://github.com/Bareflank/hypervisor/tree/v2.1/bfdriver/src/platform/linux

C2Rust with errors

 c2rust transpile ./compile_commands.json --emit-no-std --emit-modules -o bareflank-rs "$@" >output.txt 2>error.txt

complete error.txt

....
789 warnings generated.
....

warning: Missing child 94376710043688 of node AstNode { tag: TagIfStmt, children: [Some(94376710043688), Some(94376710044128), Some(94376710044280)], loc: SrcSpan { fileid: 303, begin_line: 208, begin_column: 9, end_line: 208, end_column: 9 }, type_id: None, rvalue: LValue, macro_expansions: [], macro_expansion_text: None, extras: [] }
Exported Clang AST was invalid. Check warnings above for unimplemented features.
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/page-flags.h:208:9
 [-Wclang-ast]
warning: Missing type 94376706267776 for node: AstNode { tag: TagVarDecl, children: [Some(94376718175144)], loc: SrcSpan { fileid: 54, begin_line: 320, begin_column: 2, end_line: 320, end_column: 2 }, type_id: Some(94376706267776), rvalue: LValue, macro_expansions: [], macro_expansion_text: None, extras: [Text("__flags"), Bool(false), Bool(false), Bool(false), Bool(true), Array([])] }
Exported Clang AST was invalid. Check warnings above for unimplemented features.
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/kernfs.h:320:2
 [-Wclang-ast]
warning: Missing child 94376725014288 of node AstNode { tag: TagParenExpr, children: [Some(94376725014288)], loc: SrcSpan { fileid: 111, begin_line: 386, begin_column: 9, end_line: 386, end_column: 9 }, type_id: Some(94376712495840), rvalue: LValue, macro_expansions: [], macro_expansion_text: None, extras: [] }
Exported Clang AST was invalid. Check warnings above for unimplemented features.
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/memcontrol.h:386:9
 [-Wclang-ast]
warning: Missing child 94376723681448 of node AstNode { tag: TagParenExpr, children: [Some(94376723681448)], loc: SrcSpan { fileid: 53, begin_line: 784, begin_column: 9, end_line: 784, end_column: 9 }, type_id: Some(94376695008912), rvalue: RValue, macro_expansions: [], macro_expansion_text: None, extras: [] }
Exported Clang AST was invalid. Check warnings above for unimplemented features.
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/cgroup-defs.h:784:9
 [-Wclang-ast]
warning: Missing child 94376703345864 of node AstNode { tag: TagIfStmt, children: [Some(94376703345864), Some(94376703346344), Some(94376703346592)], loc: SrcSpan { fileid: 233, begin_line: 382, begin_column: 6, end_line: 382, end_column: 6 }, type_id: None, rvalue: LValue, macro_expansions: [], macro_expansion_text: None, extras: [] }
Exported Clang AST was invalid. Check warnings above for unimplemented features.
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/arch/x86/include/asm/nospec-branch.h:382:6
 [-Wclang-ast]
thread 'main' panicked at 'Could not find CTypeId(47553) in TypedAstContext', /root/.cargo/registry/src/github.com-1ecc6299db9ec823/c2rust-transpile-0.18.0/src/c_ast/mod.rs:260:30
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

total 57 headers files in the warning message

 grep -- "-->" error.txt | awk -F ':' '{print $1}' | sort -u | wc -l

result:

--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/arch/x86/include/asm/atomic64_64.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/arch/x86/include/asm/atomic.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/arch/x86/include/asm/nospec-branch.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/arch/x86/include/asm/pkru.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/arch/x86/include/asm/qspinlock.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/asm-generic/rwonce.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/atomic/atomic-arch-fallback.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/backing-dev-defs.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/bio.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/bottom_half.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/bvec.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/cgroup-defs.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/cgroup.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/dcache.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/device.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/fs.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/highmem.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/hrtimer.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/huge_mm.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/idr.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/kernfs.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/key.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/kobject.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/ktime.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/list_bl.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/list.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/llist.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/math64.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/memcontrol.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/mm.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/mmzone.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/mount.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/page-flags.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/pagemap.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/page_ref.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/percpu_counter.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/percpu-refcount.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/pgtable.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/plist.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/radix-tree.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/rbtree_latch.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/rculist_bl.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/rcupdate.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/rcu_sync.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/rcuwait.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/sched.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/sched/signal.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/seqlock.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/srcu.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/swap.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/thread_info.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/timerqueue.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/uaccess.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/wait.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/workqueue.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/writeback.h
--> /usr/src/linux-hwe-5.19-headers-5.19.0-46/include/linux/xarray.h
fw-immunant commented 1 year ago

The relevant warning from your log appears to be:

warning: c2rust: Encountered unsupported generic selection expression

Which is caused by the definition of the page_folio macro in the kernel, which uses _Generic. This is tracked by issue #760.

SheldonHH commented 1 year ago

Thank you. I am curious as to how the conversion of the Linux Kernel Module to C2Rust was successful back in 2020. https://immunant.com/blog/2020/06/kernel_modules/

What versions of C2Rust, Clang, GCC, and the Linux kernel were used in this process? the article is a bit vague about the specific versions of tools.

I'd like to replicate the same successful transpilation, and use C2Rust to translate more simple Linux Kernel Modules to improve on C2Rust.

brechtvandesijpe commented 4 months ago

Thank you. I am curious as to how the conversion of the Linux Kernel Module to C2Rust was successful back in 2020. https://immunant.com/blog/2020/06/kernel_modules/

What versions of C2Rust, Clang, GCC, and the Linux kernel were used in this process? the article is a bit vague about the specific versions of tools.

I'd like to replicate the same successful transpilation, and use C2Rust to translate more simple Linux Kernel Modules to improve on C2Rust.

I am currently having the same issue, following the same tutorial. I wonder what these steps were:

"After making some fixes and additions to C2Rust and fix the subsequent compilation errors, we compiled the resulting Rust code with:"

It seems that in the tutorial the author was able to fix these. Did you find any solution to the problem?

thedataking commented 4 months ago

Hi @brechtvandesijpe, the issue is missing support for _Generic types as mentioned here https://github.com/immunant/c2rust/issues/982#issuecomment-1630869003

@ahomescu do you remember how/whether we worked around this issue?

ahomescu commented 3 months ago

I don't remember anything about _Generic. Keep in mind this was 4 years ago, so it's very likely that the kernel code has also changed significantly. I didn't document the exact versions of Linux or clang that we used, but the blog post mentions 5.0.

ahomescu commented 3 months ago

The relevant warning from your log appears to be:

warning: c2rust: Encountered unsupported generic selection expression

Which is caused by the definition of the page_folio macro in the kernel, which uses _Generic. This is tracked by issue #760.

It looks like page_folio was introduced in Linux 5.16, so any kernel before that should be good (unless there are other uses of _Generic).