pacak / cargo-show-asm

cargo subcommand showing the assembly, LLVM-IR and MIR generated for Rust code
Apache License 2.0
712 stars 35 forks source link

Fix no_mangle function search in LLVM-IR output mode #313

Closed zheland closed 1 month ago

zheland commented 1 month ago

In LLVM-IR output mode cargo asm don't parse non-mangled function definitions properly and return function names like Function Attrs: mustprogress nofree noinline norecurse nosync nounwind nonlazybind willreturn memory(none) uwtable instead. In ASM output mode everything is okay.

Checked with example about on linux x86_64 and with cargo test.

[!WARNING] The changes have not been tested on a large number of samples and in theory may break something. Since the conditions for detecting functions have been relaxed, it now you can theoretically over-detect functions. Please check on more "real" examples if possible.

Changes

Example

For the following code:

#[inline(never)]
pub fn func1() -> u32 {
    1
}

#[inline(never)]
pub fn func2() -> u32 {
    2
}

#[no_mangle]
#[inline(never)]
pub extern "C" fn func3() -> u32 {
    3
}

#[no_mangle]
#[inline(never)]
pub extern "Rust" fn func4() -> u32 {
    4
}

Current output (without this PR)

$ cargo asm --lib
Try one of those by name or a sequence number
0 "func3" [7]
1 "func4" [7]
2 "test_lib1::func1" [8]
3 "test_lib1::func2" [7]

$ cargo asm --lib --llvm
Try one of those by name or a sequence number
0 "Function Attrs: mustprogress nofree noinline norecurse nosync nounwind nonlazybind willreturn memory(none) uwtable" [1, 1]
2 "test_lib1::func1" [1]
3 "test_lib1::func2" [1]

$ cargo asm --lib --llvm func3
Can't find any items matching "func3"

$ cargo asm --lib --llvm func4
Can't find any items matching "func4"

$ cargo asm --lib --llvm 0
; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind nonlazybind willreturn memory(none) uwtable
define noundef i32 @func3() unnamed_addr #0 {
start:
  ret i32 3
}

$ cargo asm --lib --llvm --everything | grep -A 5 -E "func2|func3|func4"
; test_lib1::func2
; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind nonlazybind willreturn memory(none) uwtable
define noundef i32 @test_lib1::func2() unnamed_addr #0 {
start:
  ret i32 2
}

; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind nonlazybind willreturn memory(none) uwtable
define noundef i32 @func3() unnamed_addr #0 {
start:
  ret i32 3
}

; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind nonlazybind willreturn memory(none) uwtable
define noundef i32 @func4() unnamed_addr #0 {
start:
  ret i32 4
}

attributes #0 = { mustprogress nofree noinline norecurse nosync nounwind nonlazybind willreturn memory(none) uwtable "probe-stack"="inline-asm" "target-cpu"="x86-64" }

Expected (with this PR)

$ cargo asm --lib
Try one of those by name or a sequence number
0 "func3" [7]
1 "func4" [7]
2 "test_lib1::func1" [8]
3 "test_lib1::func2" [7]

$ cargo asm --lib --llvm
Try one of those by name or a sequence number
0 "func3" [1]
1 "func4" [1]
2 "test_lib1::func1" [1]
3 "test_lib1::func2" [1]

$ cargo asm --lib --llvm func3
define noundef i32 @func3() unnamed_addr #0 {
start:
  ret i32 3
}

$ cargo asm --lib --llvm func4
define noundef i32 @func4() unnamed_addr #0 {
start:
  ret i32 4
}
pacak commented 1 month ago

Please check on more "real" examples if possible.

To be honest I'm not using LLVM output often enough and no_mangle - at all, at least in projects I'm usually working on. Let's merge this in as is since it improves the behavior and I'll deal with any remaining issues if somebody reports them or I encounter them myself.

Thank you for your great contributions. Please let me know if you have more planned - I can wait with the release for some time.

zheland commented 1 month ago

Thank you, nothing more planned yet :-)