#assembly #cargo #cargo-subcommand #plugin

bin+lib cargo-show-asm

一个显示 Rust 源代码生成汇编的 Cargo 子命令

64 个版本

0.2.38 2024年7月2日
0.2.35 2024年5月6日
0.2.30 2024年2月11日
0.2.25 2023年12月31日
0.1.12 2022年7月27日

#65Cargo 插件

Download history 720/week @ 2024-05-03 480/week @ 2024-05-10 370/week @ 2024-05-17 327/week @ 2024-05-24 721/week @ 2024-05-31 537/week @ 2024-06-07 724/week @ 2024-06-14 825/week @ 2024-06-21 911/week @ 2024-06-28 347/week @ 2024-07-05 207/week @ 2024-07-12 236/week @ 2024-07-19 313/week @ 2024-07-26 530/week @ 2024-08-02 1085/week @ 2024-08-09 540/week @ 2024-08-16

2,515 每月下载量

MIT/Apache

140KB
3K SLoC

cargo-show-asm

A cargo subcommand that displays the Assembly, LLVM-IR, MIR and WASM generated for Rust source code.

安装

$ cargo install cargo-show-asm

特性

  • 平台支持

    • OS: Linux 和 macOS。Windows 支持有限
    • Rust: nightly 和 stable。
    • 架构: x86, x86_64, aarch64, 等。
    • 交叉编译支持。
  • 显示

    • Intel 或 AT& T 语法中的汇编。
    • 与汇编对应的 Rust 源代码。
    • llvm-ir。
    • rustc MIR
    • Wasm 代码
    • llvm-mca 分析

cargo asm

显示 rustc 为任何函数生成的代码

用法: cargo asm [-p=SPEC] [ARTIFACT] [-M=ARG]... [TARGET-CPU] [--rust] [-c=COUNT] [--simplify] [--include-constants] [--this-workspace | --all-crates | --all-sources] OUTPUT-FORMAT [--everything | FUNCTION [INDEX]]

用法

  1. 专注于生成单个汇编的目标
 % cargo asm -p isin --lib   # here we are targeting lib in isin crate


  1. 缩小函数范围
 % cargo asm -p isin --lib from_ # here "from_" is part of the function you are interested intel


  1. 获取完整结果
 % cargo asm -p isin --lib isin::base36::from_alphanum

选择分析工件

  • --lib — 显示库代码的结果
  • --test=TEST — 显示集成测试的结果
  • --bench=BENCH — 显示基准测试结果
  • --example=EXAMPLE — 显示示例结果
  • --bin=BIN — 显示二进制文件结果

Cargo 选项

  • --manifest-path=PATH — Cargo.toml 的路径,默认为当前文件夹

  • --target-dir=DIR — 使用自定义的目标目录生成工件,如果不存在则创建

    使用环境变量 CARGO_TARGET_DIR

  • --dry — 生成构建计划而不是实际构建

  • --frozen — 需要 Cargo.lock 和缓存是最新的

  • --locked — 需要 Cargo.lock 是最新的

  • --offline — 不访问网络运行

  • --no-default-features — 不激活 default 功能

  • --all-features — 激活所有可用功能

  • --features=FEATURE — 要激活的功能,可以多次使用

  • --release — 以发布模式编译(默认)

  • --dev — 以开发模式编译

  • --profile=PROFILE — 为此特定配置文件构建,您也可以在这里使用 devrelease

    使用环境变量 CARGO_SHOW_ASM_PROFILE

  • --target=TRIPLE — 为目标三元组构建

  • -C=FLAG — 传递给 rustc 的代码生成标志,请参阅 'rustc -C help' 以获取详细信息

  • -Z=FLAG — 不稳定(仅限夜间)的 Cargo 标志,请参阅 'cargo -Z help' 以获取详细信息

后处理选项

  • --rust — 打印交错 Rust 代码

  • -c, --context=COUNT — 包含其他被调用的函数,递归地,直到 COUNT 层级

    [默认:0]

  • --color — 启用颜色高亮显示

  • --no-color — 禁用颜色高亮显示

  • --full-name — 包含完整的去命名名称,而不是仅包含前缀

  • --short-name — 包含不带哈希后缀的去命名名称(默认)

  • --keep-mangled — 不去命名符号名称

  • -K, --keep-labels — 保留所有原始标签

  • -B, --keep-blanks — 移除冗余标签,但保留其位置上的空格

  • -R, --reduce-labels — 完全移除冗余标签

  • -v, --verbose — 输出更详细,可以多次指定

  • --simplify — 尝试移除一些非汇编指令信息

  • --include-constants — 包含包含字符串字面量和其他常量的部分

  • -b, --keep-blank — 保留空白行

  • --this-workspace — 仅显示当前工作区的 rust 源代码

  • --all-crates — 显示当前工作区和 rust 注册表中的 rust 源代码

  • --all-sources — 显示所有 rust 源代码,包括 stdlib 和编译器

选择输出类型

  • --asm — 显示汇编代码
  • --disasm — 反汇编二进制文件或对象文件
  • --llvm — 显示 llvm-ir
  • --llvm-input — 显示在任何 LLVM 遍历之前的 llvm-ir
  • --mir — 显示 MIR
  • --wasm — 显示 WASM,需要已安装 wasm32-unknown-unknown 目标
  • --mca — 显示 llvm-mca 分析
  • --intel — 使用 Intel 风格的汇编
  • --att — 使用 AT&T 风格的汇编

从工件中选择要显示的项目

  • --everything — 输出整个文件
  • FUNCTION — 输出具有给定名称的函数,通过名称过滤函数
  • INDEX — 在存在多个同名函数时选择特定函数

可用选项

  • -p, --package=SPEC — 要使用的包,默认为当前包

    对于工作区项目是必需的,也可以指向一个依赖项

  • --file=PATH — 反汇编此文件而不是调用 cargo,需要编译时带有 disasm 功能的 cargo-show-asm

    您可以指定可执行文件、rlib 或对象文件

  • -M, --mca-arg=ARG — 将参数传递给 llvm-mca 以进行 mca 目标

  • --native — 为正在运行编译器的 CPU 优化

  • --target-cpu=CPU — 为特定 CPU 优化代码,请参阅 'rustc --print target-cpus'

  • -h, --help — 打印帮助信息

  • -V, --version — 打印版本信息

您可以通过运行不带参数的 cargo asm 来开始 - 它将建议如何缩小搜索范围 - 对于工作区包,您需要指定要与之一起工作的包,对于定义了多个目标(lib、二进制文件、示例)的包,您需要指定要使用的确切目标。在一个工作区中,cargo asm 只列出工作区成员作为建议,但工作区树中的任何包都是可用的。

一旦 cargo asm 专注于单个目标,它将运行 rustc 产生汇编文件,并尝试列出可用的公共函数列表

$ cargo asm --lib
Try one of those
"<&T as core::fmt::Display>::fmt" [17, 12, 12, 12, 12, 19, 19, 12]
"<&mut W as core::fmt::Write>::write_char" [20]
"<&mut W as core::fmt::Write>::write_fmt" [38]
"<&mut W as core::fmt::Write>::write_str" [90]
"<F as nom::internal::Parser<I,O,E>>::parse" [263]
# ...

引号中的名称是去混淆的 rust 名称,方括号中的数字表示汇编文件中的行数。具有相同名称的函数可以存在于多个实例中。

指定确切的函数名称或其唯一标识部分的名称将打印其汇编代码

$ cargo asm --lib "cargo_show_asm::opts::focus::{{closure}}"

要选择不同选项,您可以指定索引

$ cargo asm --lib "cargo_show_asm::opts::focus::{{closure}}" 2

或者使用包含十六进制的完整名称

$ cargo asm --lib --full-name
# ...
$ cargo asm --lib "once_cell::imp::OnceCell<T>::initialize::h9c5c7d5bd745000b"

cargo-show-asm 内置了搜索功能。只需传递部分名称而不是完整名称,只会列出匹配的函数

$ cargo asm --lib Debug

我的函数不在那里!

rustc 只会在知道函数类型的情况下生成代码,包括泛型参数,以及是否导出(如果是库的情况)和是否内联(如果是二进制、示例、测试等)。如果你的函数接受泛型参数,尝试围绕它创建一个单态包装器,并使其 pub#[inline(never)]

是否包含相关函数?

假设你有一个名为 foo 的函数调用了其他函数 - bar。使用 --context N 或其简短变体 -c N,你可以要求 cargo-show-asm 包含 bar 的主体到输入中。这会递归地进行,直到 N 步。参见 https://github.com/pacak/cargo-show-asm/issues/247

关于 cargo-asm 呢?

cargo-asm 已不再维护:https://github.com/gnzlbg/cargo-asm/issues/244。这个crate是一个重新实现,解决了一些其不足之处,包括

  • cargo-asm 每次都会用1个代码生成单元重新编译所有内容,这很慢,也不一定是你的发布配置文件中的内容。cargo-show-asm 避免了这一点。

  • 由于 cargo-asm 处理demangling,输出看起来像asm,但实际上并不是asm。它包含很多额外的逗号,这使得重用它更加繁琐。

  • cargo-asm 总是使用颜色,除非你传递一个标志,而 cargo-show-asm 如果输出不是发送到终端会更改其默认行为。

  • cargo-show-asm 还支持 MIR(注意,人类可读的 MIR 的格式不是稳定的)。

Shell completion

cargo-asm 随附由 bpaf 生成的shell completion,使用以下任一行并将其放置到你的shell的正确位置。

$ cargo-asm --bpaf-complete-style-bash
$ cargo-asm --bpaf-complete-style-zsh
$ cargo-asm --bpaf-complete-style-fish
$ cargo-asm --bpaf-complete-style-elvish

你需要将其作为 cargo-asm 命令而不是 cargo asm 使用,以利用它。

彩色行解析输出

你可以使用 cargo-show-asm 的两个功能之一来获得更漂亮的命令行界面

cargo install cargo-show-asm -F bright-color
cargo install cargo-show-asm -F dull-color

许可证

此项目可根据您的选择在以下许可证下使用

贡献

除非你明确声明,否则你提交给此项目的任何贡献,根据 Apache-2.0 许可证的定义,都应按上述方式双许可,不附加任何额外条款或条件。

依赖关系

~5–19MB
~322K SLoC