cargo-binutils

repository·master·Indexed 20 days ago

https://github.com/rust-embedded/cargo-binutils

A proxy for LLVM tools like llvm-nm, llvm-objdump, and llvm-size included in the Rust toolchain. It provides Cargo subcommands (e.g., cargo size, cargo nm, cargo objdump) that simplify embedded development by automatically demangling Rust symbols and offering a 'build and inspect' mode to locate and analyze build artifacts using standard Cargo flags.

Tokens
4.5K
Snippets
29
Records
36
Agent score
66%

What's inside cargo-binutils

  1. Understand the difference between rust-* tools and cargo subcommands

    master

    The project provides two ways to interact with LLVM tools:

    1. Direct Proxies (rust-*): These are direct proxies for the LLVM tools in the llvm-tools component. They require you to pass the path to the artifact manually. Example: rust-size target/debug/my-app

    2. Cargo Subcommands (cargo *): These are 'sugar' for a two-step process: they first build the project using Cargo and then run the corresponding LLVM tool on the resulting artifact. This is known as "build and inspect" mode. Example: cargo size --example foo (which runs cargo build --example foo followed by rust-size on the output).

    Key Features of Cargo Subcommands:

    • Automatic Demangling: All Rust symbols in the output are automatically demangled.
    • Build and Inspect Mode: When used within a Cargo project, you can use flags like --bin, --example, --lib, --target, and --release to automatically locate and pass the artifact path to the tool.
  2. Install cargo-binutils and llvm-tools

    master

    To use cargo-binutils, you must install the crate itself and add the llvm-tools component via rustup to ensure the underlying LLVM tools are available in your toolchain.

    $ cargo install cargo-binutils
    
    $ rustup component add llvm-tools
  3. Use Cargo subcommands with build and inspect flags

    master

    When using cargo subcommands (e.g., cargo nm, cargo objdump, cargo size), you can use standard Cargo flags to specify which artifact to inspect. This avoids manually providing paths to the compiled files.

    Supported flags for build and inspect mode:

    • --bin NAME: Specify a specific binary.
    • --example NAME: Specify a specific example.
    • --lib: Specify a library.
    • --target TARGET: Specify a target triple.
    • --release: Build and inspect the release artifact.
  4. Tool build requirements

    master

    When using cargo-binutils, some tools require the project to be built before they can be run, while others can operate on files directly.

    Tools that require a prior cargo build:

    • nm
    • objcopy
    • objdump
    • readobj
    • size
    • strip

    Tools that do NOT require a prior build:

    • ar
    • as
    • cov
    • lld
    • profdata
  5. Use cargo-binutils as a proxy for LLVM tools

    master

    The cargo-binutils package provides Cargo subcommands that act as proxies for the llvm-* tools (like nm, objcopy, objdump, etc.) shipped with the Rust toolchain.

    When you run a command like cargo nm, the utility automatically handles finding the correct artifact produced by your Cargo project, setting up the appropriate execution context (like target triples), and passing your arguments through to the underlying LLVM tool.

    To pass arguments directly to the underlying tool, use the -- separator. For example, to see the help documentation for the proxied tool, run:

    cargo <tool> -- --help
  6. Mapping Rust architectures to LLVM architecture names

    master

    The cargo-binutils toolset performs internal mapping between Rust target architectures and the architecture names expected by LLVM tools (like objdump or size). This mapping accounts for differences in naming conventions, specifically regarding endianness and specific architecture variants (e.g., x86_64 in Rust mapping to x86-64 in LLVM).

    Key mapping logic includes:

    • Endianness handling: For architectures like aarch64, arm, mips, and sparc, the tool appends suffixes like _be (big-endian) or el/le (little-endian) based on the target configuration.
    • Thumb support: If a target name starts with thumb, it is mapped to thumbeb for big-endian or thumb for little-endian.
    • Specific name translations:
      • s390x $\rightarrow$ systemz
      • sparc64 $\rightarrow$ sparcv9
      • powerpc $\rightarrow$ ppc32
      • x86_64 $\rightarrow$ x86-64
  7. Pass arguments to the proxied LLVM tool

    master

    All arguments specified after the -- delimiter are passed directly to the underlying LLVM tool. This allows you to use any flags supported by the specific tool (e.g., objdump or nm) that are not explicitly handled by the cargo-binutils wrapper.

    Example for objdump:

    cargo objdump -- -h
    cargo <tool> -- <args>
  8. Use cargo-objdump to disassemble binaries

    master

    Use cargo objdump to disassemble a binary. For cargo-objdump, the architecture of the compilation target is automatically passed as -arch-name=$target to llvm-objdump.

    $ cargo objdump --release -- --disassemble --no-show-raw-insn target/thumbv7m-none-eabi/debug/app