My goal is to compile Rust programs to the smallest possible binary and extract the machine code. I've made a very simple program to test.
.cargo/config
[target.x86_64-pc-windows-gnu]
rustflags = ["-C", "link-args=-e _start -static -nostartfiles"]
Cargo.toml
[package]
name = "r"
version = "0.1.0"
edition = "2021"
[profile.release]
panic = "abort"
opt-level = "z"
lto = true
codegen-units = 1
main.rs
#![no_std]
#![no_main]
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}
#[no_mangle]
unsafe fn _start() -> isize {
42
}
I compile cargo build --target x86_64-pc-windows-gnu --release
, extract the .text
section objcopy -j .text -O binary target/x86_64-pc-windows-gnu/release/r.exe r.bin
, but when I display the machine code, I get more than I expected :
% objdump -D -b binary -mi386 -Mx86-64 -Mintel -z r.bin
r.bin: file format binary
Disassembly of section .data:
00000000 <.data>:
0: b8 2a 00 00 00 mov eax,0x2a
5: c3 ret
6: 66 90 xchg ax,ax
8: ff (bad)
9: ff (bad)
a: ff (bad)
b: ff (bad)
c: ff (bad)
d: ff (bad)
e: ff (bad)
f: ff 00 inc DWORD PTR [rax]
11: 00 00 add BYTE PTR [rax],al
13: 00 00 add BYTE PTR [rax],al
15: 00 00 add BYTE PTR [rax],al
17: 00 ff add bh,bh
19: ff (bad)
1a: ff (bad)
1b: ff (bad)
1c: ff (bad)
1d: ff (bad)
1e: ff (bad)
1f: ff 00 inc DWORD PTR [rax]
21: 00 00 add BYTE PTR [rax],al
23: 00 00 add BYTE PTR [rax],al
25: 00 00 add BYTE PTR [rax],al
27: 00 .byte 0x0
I expected it :
% objdump -D -b binary -mi386 -Mx86-64 -Mintel -z r.bin
r.bin: file format binary
Disassembly of section .data:
00000000 <.data>:
0: b8 2a 00 00 00 mov eax,0x2a
5: c3 ret
Two questions :
- What is the purpose of the machine code from address 0x6 to the end of the file ?
- How do I get rid of it ?