Howdy Rustaceans,

Recent nightly releases provide an opt-in llvm-tools rustup component which you can install using the command: rustup component add llvm-tools . This component contains the following LLVM tools:

llvm-nm

llvm-objcopy

llvm-objdump

llvm-profdata

llvm-size

Most of these tools are LLVM alternatives to GNU binutils. The main advantage of these LLVM tools is that they support all the architectures that the Rust compiler supports. For example, llvm-objdump con disassemble object files containing machine code for architectures ranging from ARM Cortex-M (THUMB) all the way to WASM (*) and x86_64. OTOH, if you were to use the GNU tools you would have to install one set of binutils for each architecture you are working with (e.g. avr-binutils , arm-none-eabi-binutils , msp430-elf-binutils , etc.).

(*) size and nm work fine with WASM but objdump does not. It could be that disassembly support is lacking in LLVM 6, the version nightly rustc is currently using, and that upgrading LLVM would make objdump work; or it could be something completely different.

How to use these LLVM tools?

After installing the component the LLVM tools will be installed to the rustc sysroot but they will not be added to your PATH. To use the tools install the cargo-binutils crate; this crate provides subcommands that proxy the LLVM tools located in the rustc sysroot:

$ cargo install cargo-binutils $ cargo new --bin hello && cd $_ $ cargo build --release $ cargo size -v -- target/release/hello "/home/japaric/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/llvm-size" "target/release/hello" text data bss dec hex filename 300887 95276 4288 400451 61c43 target/release/hello $ cargo objdump -- -d target/release/hello target/release/hello: file format ELF64-x86-64 Disassembly of section .init: _init: 5af8: 48 83 ec 08 subq $8, %rsp 5afc: 48 8b 05 d5 14 26 00 movq 2495701(%rip), %rax 5b03: 48 85 c0 testq %rax, %rax 5b06: 74 02 je 2 <_init+0x12> 5b08: ff d0 callq *%rax 5b0a: 48 83 c4 08 addq $8, %rsp 5b0e: c3 retq Disassembly of section .plt: (..) $ # symbols (functions / statics) sorted by size $ cargo nm -- -print-size -size-sort target/release/hello | tail 000000000002db70 00000000000010d9 t je_arena_palloc 0000000000047920 000000000000184d T je_malloc_vsnprintf 0000000000010b80 0000000000001aa9 t elf_add 0000000000017c10 0000000000001b21 t backtrace_dwarf_add 00000000000313a0 0000000000001b6b t je_arena_boot 0000000000024910 0000000000001eac T mallocx 0000000000041020 0000000000001eed t je_stats_print 000000000001ba70 00000000000022c4 t read_line_info 0000000000015170 0000000000002341 T std::sys_common::backtrace::output::hd4b97ca56fb1f164 0000000000043710 0000000000002617 t stats_arena_print

Check the project README for more details.

Stability

The Rust project provides no guarantee about the availability of these LLVM tools or the stability of their CLI. On some platforms the llvm-tools component may be empty, i.e. installing the component will install nothing.

For these reasons you should not rely on these tools to build code (e.g. in build scripts). Given that these tools are mainly for inspection and profiling the risk of that is very low.

NOTE The rustup component might be renamed to llvm-tools-preview to better reflect the lack of stability guarantees.

Improving the UI

In the first release of cargo-binutils the Cargo subcommands simply proxy the LLVM tools. In future releases, we’d like to provide a user interface that feels more integrated with Cargo (e.g. cargo size --examples should build all the examples and list their sizes) so we have opened several issues requesting input on how such UI should look. If you have thoughts or suggestions on the topic please comment over there!

This change is part of the embedded WG effort towards improving / unifying embedded Rust tooling. See rust-lang-nursery/embedded-wg#50 and rust-lang-nursery/embedded-wg#51.