7

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 ?
Xobtah
  • 464
  • 7
  • 20
  • 2
    This "code" doesn't look like code. Wild guess: what if the .data section has some minimum length and that is simply padding? (Though I can't think of anything that would make 40 a meaningful length.) – Caesar Jul 27 '23 at 22:52
  • Have you tried seeing whether other compilers are able to produce smaller binaries? Like `gcc` or `clang`? – jthulhu Jul 28 '23 at 06:28
  • After several days of testing, I can't find where the data section could be set a minimal length. I have tried MSVC and GNU and none of them seem to be able to make the expected bin (I am on an Apple M1 btw) – Xobtah Jul 31 '23 at 09:27

0 Answers0