Skip to content

Commit 772f795

Browse files
committed
Use opt-level=z to shave off eight bytes
rustc/LLVM does constant propagation through the inline assembly and finds more compact instructions!
1 parent 00f5abb commit 772f795

File tree

2 files changed

+28
-24
lines changed

2 files changed

+28
-24
lines changed

README.md

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
# Using Rust to make a 145-byte static AMD64 Linux binary
1+
# Using Rust to make a 137-byte static AMD64 Linux binary
22

33
Requires nightly Rust because it uses the `sc` crate to make direct
44
system calls.
55

66
`elf.s` contains a custom ELF header, but no instructions.
7-
All of the machine code comes out of `rustc`. (Although all except one of the instructions that survive optimization *went in* as inline assembly.)
7+
All of the machine code comes out of `rustc`.
8+
(While most of the operations originate from inline assembly, LLVM replaces the instructions with more compact ones!)
89

910
```
1011
$ ./build.sh
@@ -14,9 +15,9 @@ You have rustc 1.46.0-nightly (346aec9b0 2020-07-11)
1415
Cloning into 'syscall.rs'...
1516
Compiling sc v0.2.3 (file:///home/tormol/p/rust/tiny-rust-executable/syscall.rs)
1617
17-
+ rustc tinyrust.rs -O -C relocation-model=static -L syscall.rs/target/release
18-
++ grep '.o$'
18+
+ rustc tinyrust.rs --crate-type lib -L syscall.rs/target/release -C relocation-model=static -O -C opt-level=z
1919
++ ar t libtinyrust.rlib
20+
++ grep '.o$'
2021
+ OBJECT=tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o
2122
+ ar x libtinyrust.rlib tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o
2223
+ objdump -dr tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o
@@ -27,23 +28,25 @@ tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o: file format elf64-x86-64
2728
Disassembly of section .text.main:
2829
2930
0000000000000000 <main>:
30-
0: bf 01 00 00 00 mov $0x1,%edi
31-
5: be 08 00 40 00 mov $0x400008,%esi
32-
a: ba 07 00 00 00 mov $0x7,%edx
33-
f: b8 01 00 00 00 mov $0x1,%eax
34-
14: 0f 05 syscall
35-
16: 31 ff xor %edi,%edi
36-
18: b8 3c 00 00 00 mov $0x3c,%eax
37-
1d: 0f 05 syscall
38-
1f: 0f 0b ud2
31+
0: 6a 07 pushq $0x7
32+
2: 5a pop %rdx
33+
3: 6a 01 pushq $0x1
34+
5: 58 pop %rax
35+
6: be 08 00 40 00 mov $0x400008,%esi
36+
b: 48 89 c7 mov %rax,%rdi
37+
e: 0f 05 syscall
38+
10: 6a 3c pushq $0x3c
39+
12: 58 pop %rax
40+
13: 31 ff xor %edi,%edi
41+
15: 0f 05 syscall
42+
17: 0f 0b ud2
3943
+ echo
4044
41-
4245
+ ld --gc-sections -e main -T script.ld -o payload tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o
4346
+ objcopy -j combined -O binary payload payload.bin
4447
++ nm --format=posix payload
45-
++ awk '{print $3}'
4648
++ grep '^main '
49+
++ awk '{print $3}'
4750
+ ENTRY=0000000000400070
4851
+ nasm -f bin -o tinyrust -D entry=0x0000000000400070 elf.s
4952
+ chmod +x tinyrust
@@ -53,14 +56,13 @@ Disassembly of section .text.main:
5356
00000020 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |8...............|
5457
00000030 00 00 00 00 38 00 38 00 01 00 00 00 07 00 00 00 |....8.8.........|
5558
00000040 00 00 00 00 00 00 00 00 00 00 40 00 00 00 00 00 |..........@.....|
56-
00000050 00 00 40 00 00 00 00 00 91 00 00 00 00 00 00 00 |..@.............|
57-
00000060 91 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................|
58-
00000070 bf 01 00 00 00 be 08 00 40 00 ba 07 00 00 00 b8 |........@.......|
59-
00000080 01 00 00 00 0f 05 31 ff b8 3c 00 00 00 0f 05 0f |......1..<......|
60-
00000090 0b |.|
61-
00000091
59+
00000050 00 00 40 00 00 00 00 00 89 00 00 00 00 00 00 00 |..@.............|
60+
00000060 89 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................|
61+
00000070 6a 07 5a 6a 01 58 be 08 00 40 00 48 89 c7 0f 05 |j.Zj.X...@.H....|
62+
00000080 6a 3c 58 31 ff 0f 05 0f 0b |j<X1.....|
63+
00000089
6264
+ wc -c tinyrust
63-
145 tinyrust
65+
137 tinyrust
6466
6567
$ ./tinyrust
6668
Hello!

build.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ fi
2020
set -x
2121

2222
rustc tinyrust.rs --crate-type lib \
23-
-O -C relocation-model=static \
24-
-L syscall.rs/target/release
23+
-L syscall.rs/target/release \
24+
-C relocation-model=static \
25+
-O \
26+
-C opt-level=z
2527

2628
# tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o
2729
OBJECT=$(ar t libtinyrust.rlib | grep '.o$')

0 commit comments

Comments
 (0)