From a5e0e09f183c0fbb859db65680366b397ca6868c Mon Sep 17 00:00:00 2001 From: Melvin Kicchi Date: Tue, 6 Oct 2015 14:30:24 +0200 Subject: [PATCH 01/21] Upgrade to rustc 1.5.0-nightly (32a8567ea 2015-10-05) (built 2015-10-06) --- build.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build.sh b/build.sh index 34fbd6d..9ef0e6a 100755 --- a/build.sh +++ b/build.sh @@ -2,11 +2,11 @@ set -e -for d in rustc git cargo ar ld objcopy nasm; do +for d in rustc git cargo ar ld objcopy nasm hexdump; do which $d >/dev/null || (echo "Can't find $d, needed to build"; exit 1) done -printf "Tested on rustc 1.1.0-dev (435622028 2015-05-04)\nYou have " +printf "Tested on rustc 1.5.0-nightly (32a8567ea 2015-10-05)\nYou have " rustc --version echo @@ -22,17 +22,17 @@ rustc tinyrust.rs \ -O -C no-stack-check -C relocation-model=static \ -L syscall.rs/target/release -ar x libtinyrust.rlib tinyrust.o +ar x libtinyrust.rlib tinyrust.0.o -objdump -dr tinyrust.o +objdump -dr tinyrust.0.o echo -ld --gc-sections -e main -T script.ld -o payload tinyrust.o +ld --gc-sections -e main -T script.ld -o payload tinyrust.0.o objcopy -j combined -O binary payload payload.bin ENTRY=$(nm -f posix payload | grep '^main ' | awk '{print $3}') nasm -f bin -o tinyrust -D entry=0x$ENTRY elf.s chmod +x tinyrust -hd tinyrust +hexdump -C tinyrust wc -c tinyrust From b00973d2721315c436ae4a7f61bfcc8b2674f27a Mon Sep 17 00:00:00 2001 From: Melvin Kicchi Date: Tue, 6 Oct 2015 14:41:25 +0200 Subject: [PATCH 02/21] Update tinyrust.rs --- tinyrust.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tinyrust.rs b/tinyrust.rs index 375c988..f1b722f 100644 --- a/tinyrust.rs +++ b/tinyrust.rs @@ -1,5 +1,5 @@ #![crate_type="rlib"] -#![feature(core)] +#![feature(raw, core_intrinsics)] #[macro_use] extern crate syscall; From 8c711fca3d3214dd80f62fb8814d18fd0eb47242 Mon Sep 17 00:00:00 2001 From: Hiroki Noda Date: Mon, 30 Jan 2017 11:18:54 +0900 Subject: [PATCH 03/21] Upgrade to rustc 1.16.0-nightly (df8debf6d 2017-01-25) --- .gitignore | 2 +- build.sh | 6 +++--- tinyrust.rs | 11 ++++------- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 34d432e..124cb9e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,5 @@ /payload.bin /tinyrust /tinyrust.ll -/tinyrust.o +/tinyrust.0.o /libtinyrust.rlib diff --git a/build.sh b/build.sh index 9ef0e6a..44ef87e 100755 --- a/build.sh +++ b/build.sh @@ -6,12 +6,12 @@ for d in rustc git cargo ar ld objcopy nasm hexdump; do which $d >/dev/null || (echo "Can't find $d, needed to build"; exit 1) done -printf "Tested on rustc 1.5.0-nightly (32a8567ea 2015-10-05)\nYou have " +printf "Tested on rustc 1.16.0-nightly (df8debf6d 2017-01-25)" rustc --version echo if [ ! -d syscall.rs ]; then - git clone https://github.com/kmcallister/syscall.rs + git clone https://github.com/japaric/syscall.rs (cd syscall.rs && cargo build --release) echo fi @@ -19,7 +19,7 @@ fi set -x rustc tinyrust.rs \ - -O -C no-stack-check -C relocation-model=static \ + -O -C relocation-model=static \ -L syscall.rs/target/release ar x libtinyrust.rlib tinyrust.0.o diff --git a/tinyrust.rs b/tinyrust.rs index f1b722f..fa7e539 100644 --- a/tinyrust.rs +++ b/tinyrust.rs @@ -1,9 +1,9 @@ #![crate_type="rlib"] -#![feature(raw, core_intrinsics)] +#![feature(core_intrinsics)] -#[macro_use] extern crate syscall; +#[macro_use] extern crate sc; -use std::{mem, raw, intrinsics}; +use std::{mem, slice, intrinsics}; fn exit(n: usize) -> ! { unsafe { @@ -23,10 +23,7 @@ pub fn main() { // Make a Rust value representing the string constant we stashed // in the ELF file header. let message: &'static [u8] = unsafe { - mem::transmute(raw::Slice { - data: 0x00400008 as *const u8, - len: 7, - }) + mem::transmute(slice::from_raw_parts(0x00400008 as *const u8, 7)) }; write(1, message); From 718e4511687062937437dda69dff22df3c099c3a Mon Sep 17 00:00:00 2001 From: Hiroki Noda Date: Mon, 30 Jan 2017 11:21:55 +0900 Subject: [PATCH 04/21] Overlapped 8bytes elf header and program header --- elf.s | 4 +--- script.ld | 4 ++-- tinyrust.rs | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/elf.s b/elf.s index 9bd38d2..da7cd06 100644 --- a/elf.s +++ b/elf.s @@ -20,13 +20,11 @@ ehdr: dd 0 ; e_flags dw ehdrsize ; e_ehsize dw phdrsize ; e_phentsize - dw 1 ; e_phnum - dw 0, 0, 0 ; e_sh* ehdrsize equ $ - ehdr phdr: - dd 1 ; p_type = loadable program segment + dd 1 ; p_type = loadable program segment & (e_phnum + e_sh*) dd 7 ; p_flags = rwx dq 0 ; p_offset dq $$, $$ ; p_vaddr, p_paddr diff --git a/script.ld b/script.ld index 3eb759d..35db21b 100644 --- a/script.ld +++ b/script.ld @@ -1,7 +1,7 @@ SECTIONS { - . = 0x400078; + . = 0x400070; - combined . : AT(0x400078) ALIGN(1) SUBALIGN(1) { + combined . : AT(0x400070) ALIGN(1) SUBALIGN(1) { *(.text*) *(.data*) *(.rodata*) diff --git a/tinyrust.rs b/tinyrust.rs index fa7e539..84e15b4 100644 --- a/tinyrust.rs +++ b/tinyrust.rs @@ -23,7 +23,7 @@ pub fn main() { // Make a Rust value representing the string constant we stashed // in the ELF file header. let message: &'static [u8] = unsafe { - mem::transmute(slice::from_raw_parts(0x00400008 as *const u8, 7)) + mem::transmute(slice::from_raw_parts(0x00400000 as *const u8, 7)) }; write(1, message); From 35bd9cb8bd8655b62ea392fd0289b983c82b9109 Mon Sep 17 00:00:00 2001 From: Hiroki Noda Date: Mon, 30 Jan 2017 02:31:02 +0000 Subject: [PATCH 05/21] Works on FreeBSD --- build.sh | 2 +- elf.s | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index 44ef87e..ad275b2 100755 --- a/build.sh +++ b/build.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/elf.s b/elf.s index da7cd06..1b47942 100644 --- a/elf.s +++ b/elf.s @@ -6,7 +6,7 @@ ehdr: db 0x7f, "ELF" ; magic - db 2, 1, 1, 0 ; 64-bits, little endian, version 1 + db 2, 1, 1, 9 ; 64-bits, little endian, version 9(FreeBSD, linux loader ignores this) ; This padding is a perfect place to put a string constant! db "Hello!", 0x0A, 0 From 5247304ee902a122da8a7506733f0fb67e6790b6 Mon Sep 17 00:00:00 2001 From: Hiroki Noda Date: Mon, 30 Jan 2017 11:38:08 +0900 Subject: [PATCH 06/21] Add missing stuff --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index ad275b2..af075bf 100755 --- a/build.sh +++ b/build.sh @@ -6,7 +6,7 @@ for d in rustc git cargo ar ld objcopy nasm hexdump; do which $d >/dev/null || (echo "Can't find $d, needed to build"; exit 1) done -printf "Tested on rustc 1.16.0-nightly (df8debf6d 2017-01-25)" +printf "Tested on rustc 1.16.0-nightly (df8debf6d 2017-01-25)\n You have " rustc --version echo From bb1dc9deb2fb9ca2c542fb5b62d8296638d695f9 Mon Sep 17 00:00:00 2001 From: Hiroki Noda Date: Mon, 30 Jan 2017 12:12:06 +0900 Subject: [PATCH 07/21] Fix --- tinyrust.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tinyrust.rs b/tinyrust.rs index 84e15b4..fa7e539 100644 --- a/tinyrust.rs +++ b/tinyrust.rs @@ -23,7 +23,7 @@ pub fn main() { // Make a Rust value representing the string constant we stashed // in the ELF file header. let message: &'static [u8] = unsafe { - mem::transmute(slice::from_raw_parts(0x00400000 as *const u8, 7)) + mem::transmute(slice::from_raw_parts(0x00400008 as *const u8, 7)) }; write(1, message); From af2d17246ffedc8864b1a0f71eceb7ac434a9ff8 Mon Sep 17 00:00:00 2001 From: Hiroki Noda Date: Mon, 30 Jan 2017 03:12:41 +0000 Subject: [PATCH 08/21] Fix for FreeBSD --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index af075bf..6e2b202 100755 --- a/build.sh +++ b/build.sh @@ -30,7 +30,7 @@ echo ld --gc-sections -e main -T script.ld -o payload tinyrust.0.o objcopy -j combined -O binary payload payload.bin -ENTRY=$(nm -f posix payload | grep '^main ' | awk '{print $3}') +ENTRY=$(nm --format=posix payload | grep '^main ' | awk '{print $3}') nasm -f bin -o tinyrust -D entry=0x$ENTRY elf.s chmod +x tinyrust From acc45d752e97d546aab129da7b763b5c59757b66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B8rn=20Birch=20Moltu?= Date: Fri, 7 Sep 2018 19:35:57 +0200 Subject: [PATCH 09/21] Upgrade to Rust 1.30-nightly The object file in the rlib has been renamed again, and the name now includes now gibberish. The assembly now has an extra instruction due to https://github.com/rust-lang/rust/pull/45920 which increases the executable size with two bytes. (There doesn't appear to be a way to disable the unreachable() trap.) --- .gitignore | 2 +- build.sh | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 124cb9e..4969f39 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,5 @@ /payload.bin /tinyrust /tinyrust.ll -/tinyrust.0.o +/*.o /libtinyrust.rlib diff --git a/build.sh b/build.sh index 6e2b202..24b3f64 100755 --- a/build.sh +++ b/build.sh @@ -6,7 +6,7 @@ for d in rustc git cargo ar ld objcopy nasm hexdump; do which $d >/dev/null || (echo "Can't find $d, needed to build"; exit 1) done -printf "Tested on rustc 1.16.0-nightly (df8debf6d 2017-01-25)\n You have " +printf "Tested on rustc 1.30.0-nightly (f8d34596f 2018-08-30)\n You have " rustc --version echo @@ -22,12 +22,14 @@ rustc tinyrust.rs \ -O -C relocation-model=static \ -L syscall.rs/target/release -ar x libtinyrust.rlib tinyrust.0.o +# tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o +OBJECT=$(ar t libtinyrust.rlib | grep '.o$') +ar x libtinyrust.rlib "$OBJECT" -objdump -dr tinyrust.0.o +objdump -dr "$OBJECT" echo -ld --gc-sections -e main -T script.ld -o payload tinyrust.0.o +ld --gc-sections -e main -T script.ld -o payload "$OBJECT" objcopy -j combined -O binary payload payload.bin ENTRY=$(nm --format=posix payload | grep '^main ' | awk '{print $3}') From 4e90ceda5238cf47fb2d020700e9a32fc54dfe22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B8rn=20Birch=20Moltu?= Date: Fri, 7 Sep 2018 19:47:22 +0200 Subject: [PATCH 10/21] Update readme --- README.md | 77 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index fa44929..ac8d8b5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ -# Using Rust to make a 151-byte static AMD64 Linux binary +# Using Rust to make a 145-byte static AMD64 Linux binary + +Requires nightly Rust because it uses the `sc` crate to make direct +system calls. `elf.s` contains a custom ELF header, but no instructions. All of the machine code comes out of `rustc`. (Although all of the instructions that survive @@ -6,55 +9,59 @@ optimization *went in* as inline assembly.) ``` $ ./build.sh -Tested on rustc 1.0.0-dev (44a287e6e 2015-01-08 17:03:40 -0800) -You have rustc 1.0.0-dev (44a287e6e 2015-01-08 17:03:40 -0800) +Tested on rustc 1.30.0-nightly (f8d34596f 2018-08-30) +You have rustc 1.30.0-nightly (f8d34596f 2018-08-30) Cloning into 'syscall.rs'... - Compiling syscall v0.1.0 (file:///home/keegan/tiny-rust-demo/syscall.rs) + Compiling sc v0.2.2 (file:///home/keegan/tiny-rust-demo/syscall.rs) -+ rustc tinyrust.rs -O -C no-stack-check -C relocation-model=static -L syscall.rs/target -+ ar x libtinyrust.rlib tinyrust.o -+ objdump -dr tinyrust.o ++ rustc tinyrust.rs -O -C relocation-model=static -L syscall.rs/target/release +++ grep '.o$' +++ ar t libtinyrust.rlib ++ OBJECT=tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o ++ ar x libtinyrust.rlib tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o ++ objdump -dr tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o -tinyrust.o: file format elf64-x86-64 +tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o: file format elf64-x86-64 Disassembly of section .text.main: 0000000000000000
: - 0: b8 01 00 00 00 mov $0x1,%eax - 5: bf 01 00 00 00 mov $0x1,%edi - a: be 08 00 40 00 mov $0x400008,%esi - f: ba 07 00 00 00 mov $0x7,%edx - 14: 0f 05 syscall - 16: b8 3c 00 00 00 mov $0x3c,%eax - 1b: 31 ff xor %edi,%edi - 1d: 0f 05 syscall + 0: bf 01 00 00 00 mov $0x1,%edi + 5: be 08 00 40 00 mov $0x400008,%esi + a: ba 07 00 00 00 mov $0x7,%edx + f: b8 01 00 00 00 mov $0x1,%eax + 14: 0f 05 syscall + 16: 31 ff xor %edi,%edi + 18: b8 3c 00 00 00 mov $0x3c,%eax + 1d: 0f 05 syscall + 1f: 0f 0b ud2 + echo -+ ld --gc-sections -e main -T script.ld -o payload tinyrust.o + ++ ld --gc-sections -e main -T script.ld -o payload tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o + objcopy -j combined -O binary payload payload.bin -++ nm -f posix payload -++ grep '^main ' +++ nm --format=posix payload ++ awk '{print $3}' -+ ENTRY=0000000000400078 -+ set -x -+ nasm -f bin -o tinyrust -D entry=0x0000000000400078 elf.s +++ grep '^main ' ++ ENTRY=0000000000400070 ++ nasm -f bin -o tinyrust -D entry=0x0000000000400070 elf.s + chmod +x tinyrust -+ hd tinyrust -00000000 7f 45 4c 46 02 01 01 00 48 65 6c 6c 6f 21 0a 00 |.ELF....Hello!..| -00000010 02 00 3e 00 01 00 00 00 78 00 40 00 00 00 00 00 |..>.....x.@.....| -00000020 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |@...............| -00000030 00 00 00 00 40 00 38 00 01 00 00 00 00 00 00 00 |....@.8.........| -00000040 01 00 00 00 07 00 00 00 00 00 00 00 00 00 00 00 |................| -00000050 00 00 40 00 00 00 00 00 00 00 40 00 00 00 00 00 |..@.......@.....| -00000060 97 00 00 00 00 00 00 00 97 00 00 00 00 00 00 00 |................| -00000070 00 10 00 00 00 00 00 00 b8 01 00 00 00 bf 01 00 |................| -00000080 00 00 be 08 00 40 00 ba 07 00 00 00 0f 05 b8 3c |.....@.........<| -00000090 00 00 00 31 ff 0f 05 |...1...| -00000097 ++ hexdump -C tinyrust +00000000 7f 45 4c 46 02 01 01 09 48 65 6c 6c 6f 21 0a 00 |.ELF....Hello!..| +00000010 02 00 3e 00 01 00 00 00 70 00 40 00 00 00 00 00 |..>.....p.@.....| +00000020 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |8...............| +00000030 00 00 00 00 38 00 38 00 01 00 00 00 07 00 00 00 |....8.8.........| +00000040 00 00 00 00 00 00 00 00 00 00 40 00 00 00 00 00 |..........@.....| +00000050 00 00 40 00 00 00 00 00 91 00 00 00 00 00 00 00 |..@.............| +00000060 91 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................| +00000070 bf 01 00 00 00 be 08 00 40 00 ba 07 00 00 00 b8 |........@.......| +00000080 01 00 00 00 0f 05 31 ff b8 3c 00 00 00 0f 05 0f |......1..<......| +00000090 0b |.| +00000091 + wc -c tinyrust -151 tinyrust +145 tinyrust $ ./tinyrust Hello! From 0c8d3412961c14490539a378fa0bb9cfbd1eabb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B8rn=20Birch=20Moltu?= Date: Fri, 7 Sep 2018 19:48:22 +0200 Subject: [PATCH 11/21] Use the stable hint::unreachable_unchecked() Still requires nightly because sc uses inline_asm Also remove identity transmute left over from 8c711fca. --- tinyrust.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tinyrust.rs b/tinyrust.rs index fa7e539..d36f1f2 100644 --- a/tinyrust.rs +++ b/tinyrust.rs @@ -1,14 +1,14 @@ #![crate_type="rlib"] -#![feature(core_intrinsics)] +#![no_std] #[macro_use] extern crate sc; -use std::{mem, slice, intrinsics}; +use core::{hint,slice}; fn exit(n: usize) -> ! { unsafe { syscall!(EXIT, n); - intrinsics::unreachable() + hint::unreachable_unchecked() } } @@ -22,9 +22,7 @@ fn write(fd: usize, buf: &[u8]) { pub fn main() { // Make a Rust value representing the string constant we stashed // in the ELF file header. - let message: &'static [u8] = unsafe { - mem::transmute(slice::from_raw_parts(0x00400008 as *const u8, 7)) - }; + let message = unsafe{ slice::from_raw_parts(0x00400008 as *const u8, 7) }; write(1, message); exit(0); From 19c66960fa2e3504e69a8487e075f7eb04caad21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B8rn=20Birch=20Moltu?= Date: Fri, 17 Jul 2020 13:59:36 +0200 Subject: [PATCH 12/21] Update README in more places to reflect ud2 instruction inserted by Rust --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ac8d8b5..01bb56f 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,8 @@ Requires nightly Rust because it uses the `sc` crate to make direct system calls. -`elf.s` contains a custom ELF header, but no instructions. All of the machine -code comes out of `rustc`. (Although all of the instructions that survive -optimization *went in* as inline assembly.) +`elf.s` contains a custom ELF header, but no instructions. +All of the machine code comes out of `rustc`. (Although all except one of the instructions that survive optimization *went in* as inline assembly.) ``` $ ./build.sh From 39b80584522ca8dc2cb2b15972d145c7a9e6a91a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B8rn=20Birch=20Moltu?= Date: Fri, 17 Jul 2020 14:02:35 +0200 Subject: [PATCH 13/21] Update for Rust 1.46 nightly Switch sc repo to one with updated feature flags. --- README.md | 6 +++--- build.sh | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 01bb56f..c3817c0 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,11 @@ All of the machine code comes out of `rustc`. (Although all except one of the in ``` $ ./build.sh -Tested on rustc 1.30.0-nightly (f8d34596f 2018-08-30) -You have rustc 1.30.0-nightly (f8d34596f 2018-08-30) +Tested on rustc 1.46.0-nightly (346aec9b0 2020-07-11) +You have rustc 1.46.0-nightly (346aec9b0 2020-07-11) Cloning into 'syscall.rs'... - Compiling sc v0.2.2 (file:///home/keegan/tiny-rust-demo/syscall.rs) + Compiling sc v0.2.3 (file:///home/tormol/p/rust/tiny-rust-executable/syscall.rs) + rustc tinyrust.rs -O -C relocation-model=static -L syscall.rs/target/release ++ grep '.o$' diff --git a/build.sh b/build.sh index 24b3f64..a8fff4c 100755 --- a/build.sh +++ b/build.sh @@ -6,12 +6,13 @@ for d in rustc git cargo ar ld objcopy nasm hexdump; do which $d >/dev/null || (echo "Can't find $d, needed to build"; exit 1) done -printf "Tested on rustc 1.30.0-nightly (f8d34596f 2018-08-30)\n You have " +printf "Tested on rustc 1.46.0-nightly (346aec9b0 2020-07-11)\nYou have " rustc --version echo if [ ! -d syscall.rs ]; then - git clone https://github.com/japaric/syscall.rs + git clone --depth=1 https://github.com/AgustinCB/syscall.rs + # a fork of https://github.com/japaric/syscall.rs with updated asm feature flag (cd syscall.rs && cargo build --release) echo fi From 00f5abb0fb83e9cae67ca7ebf0adc3871185ef51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B8rn=20Birch=20Moltu?= Date: Fri, 17 Jul 2020 21:20:24 +0200 Subject: [PATCH 14/21] Specify compilation target type from build.sh instead of source code --- build.sh | 2 +- tinyrust.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/build.sh b/build.sh index a8fff4c..a4172d9 100755 --- a/build.sh +++ b/build.sh @@ -19,7 +19,7 @@ fi set -x -rustc tinyrust.rs \ +rustc tinyrust.rs --crate-type lib \ -O -C relocation-model=static \ -L syscall.rs/target/release diff --git a/tinyrust.rs b/tinyrust.rs index d36f1f2..acdfe14 100644 --- a/tinyrust.rs +++ b/tinyrust.rs @@ -1,4 +1,3 @@ -#![crate_type="rlib"] #![no_std] #[macro_use] extern crate sc; From 772f7958a0095479ab927af30ca76503302fb4d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B8rn=20Birch=20Moltu?= Date: Tue, 21 Jul 2020 18:24:30 +0200 Subject: [PATCH 15/21] Use opt-level=z to shave off eight bytes rustc/LLVM does constant propagation through the inline assembly and finds more compact instructions! --- README.md | 46 ++++++++++++++++++++++++---------------------- build.sh | 6 ++++-- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index c3817c0..5de0bd6 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,11 @@ -# Using Rust to make a 145-byte static AMD64 Linux binary +# Using Rust to make a 137-byte static AMD64 Linux binary Requires nightly Rust because it uses the `sc` crate to make direct system calls. `elf.s` contains a custom ELF header, but no instructions. -All of the machine code comes out of `rustc`. (Although all except one of the instructions that survive optimization *went in* as inline assembly.) +All of the machine code comes out of `rustc`. +(While most of the operations originate from inline assembly, LLVM replaces the instructions with more compact ones!) ``` $ ./build.sh @@ -14,9 +15,9 @@ You have rustc 1.46.0-nightly (346aec9b0 2020-07-11) Cloning into 'syscall.rs'... Compiling sc v0.2.3 (file:///home/tormol/p/rust/tiny-rust-executable/syscall.rs) -+ rustc tinyrust.rs -O -C relocation-model=static -L syscall.rs/target/release -++ grep '.o$' ++ rustc tinyrust.rs --crate-type lib -L syscall.rs/target/release -C relocation-model=static -O -C opt-level=z ++ ar t libtinyrust.rlib +++ grep '.o$' + OBJECT=tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o + ar x libtinyrust.rlib tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o + 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 Disassembly of section .text.main: 0000000000000000
: - 0: bf 01 00 00 00 mov $0x1,%edi - 5: be 08 00 40 00 mov $0x400008,%esi - a: ba 07 00 00 00 mov $0x7,%edx - f: b8 01 00 00 00 mov $0x1,%eax - 14: 0f 05 syscall - 16: 31 ff xor %edi,%edi - 18: b8 3c 00 00 00 mov $0x3c,%eax - 1d: 0f 05 syscall - 1f: 0f 0b ud2 + 0: 6a 07 pushq $0x7 + 2: 5a pop %rdx + 3: 6a 01 pushq $0x1 + 5: 58 pop %rax + 6: be 08 00 40 00 mov $0x400008,%esi + b: 48 89 c7 mov %rax,%rdi + e: 0f 05 syscall + 10: 6a 3c pushq $0x3c + 12: 58 pop %rax + 13: 31 ff xor %edi,%edi + 15: 0f 05 syscall + 17: 0f 0b ud2 + echo - + ld --gc-sections -e main -T script.ld -o payload tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o + objcopy -j combined -O binary payload payload.bin ++ nm --format=posix payload -++ awk '{print $3}' ++ grep '^main ' +++ awk '{print $3}' + ENTRY=0000000000400070 + nasm -f bin -o tinyrust -D entry=0x0000000000400070 elf.s + chmod +x tinyrust @@ -53,14 +56,13 @@ Disassembly of section .text.main: 00000020 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |8...............| 00000030 00 00 00 00 38 00 38 00 01 00 00 00 07 00 00 00 |....8.8.........| 00000040 00 00 00 00 00 00 00 00 00 00 40 00 00 00 00 00 |..........@.....| -00000050 00 00 40 00 00 00 00 00 91 00 00 00 00 00 00 00 |..@.............| -00000060 91 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................| -00000070 bf 01 00 00 00 be 08 00 40 00 ba 07 00 00 00 b8 |........@.......| -00000080 01 00 00 00 0f 05 31 ff b8 3c 00 00 00 0f 05 0f |......1..<......| -00000090 0b |.| -00000091 +00000050 00 00 40 00 00 00 00 00 89 00 00 00 00 00 00 00 |..@.............| +00000060 89 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................| +00000070 6a 07 5a 6a 01 58 be 08 00 40 00 48 89 c7 0f 05 |j.Zj.X...@.H....| +00000080 6a 3c 58 31 ff 0f 05 0f 0b |j Date: Wed, 22 Jul 2020 14:35:19 +0200 Subject: [PATCH 16/21] Add CI --- .cirrus.yml | 15 +++++++++++++++ README.md | 2 ++ 2 files changed, 17 insertions(+) create mode 100644 .cirrus.yml diff --git a/.cirrus.yml b/.cirrus.yml new file mode 100644 index 0000000..72e5c43 --- /dev/null +++ b/.cirrus.yml @@ -0,0 +1,15 @@ +task: + name: Linux amd64 nightly + container: + image: rustlang/rust:nightly + cpu: 1 + memory: 1 + setup_script: + - apt-get update + - apt-get install -yqq nasm bsdmainutils + build_script: + - ./build.sh + test_script: + - ./tinyrust + - test "$(./tinyrust)" == 'Hello!' + - test "$(wc -c < tinyrust)" -eq 137 diff --git a/README.md b/README.md index 5de0bd6..407a66e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Using Rust to make a 137-byte static AMD64 Linux binary +[![Build Status](https://api.cirrus-ci.com/github/tormol/tiny-rust-executable.svg)](https://cirrus-ci.com/github/tormol/tiny-rust-executable) + Requires nightly Rust because it uses the `sc` crate to make direct system calls. From 20e01029c2e276bf3592dcfcbcb7e8b59bd5c45a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B8rn=20Birch=20Moltu?= Date: Tue, 21 Jul 2020 19:54:08 +0200 Subject: [PATCH 17/21] Use cargo to compile instead of calling rustc directly --- .cargo/config | 3 +++ .cirrus.yml | 5 +++++ .gitignore | 15 ++++++++++++--- Cargo.lock | 13 +++++++++++++ Cargo.toml | 31 +++++++++++++++++++++++++++++++ README.md | 13 ++++++++----- build.sh | 19 ++++--------------- 7 files changed, 76 insertions(+), 23 deletions(-) create mode 100644 .cargo/config create mode 100644 Cargo.lock create mode 100644 Cargo.toml diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 0000000..1254531 --- /dev/null +++ b/.cargo/config @@ -0,0 +1,3 @@ +[build] +rustflags = ["-C", "relocation-model=static"] +incremental = false diff --git a/.cirrus.yml b/.cirrus.yml index 72e5c43..7551b38 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -4,6 +4,9 @@ task: image: rustlang/rust:nightly cpu: 1 memory: 1 + cargo_cache: + folder: $HOME/.cargo/registry + fingerprint_script: cat Cargo.lock 2> /dev/null || true setup_script: - apt-get update - apt-get install -yqq nasm bsdmainutils @@ -13,3 +16,5 @@ task: - ./tinyrust - test "$(./tinyrust)" == 'Hello!' - test "$(wc -c < tinyrust)" -eq 137 + before_cache_script: + - rm -rf $HOME/.cargo/registry/index diff --git a/.gitignore b/.gitignore index 4969f39..3eaa7d4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,16 @@ +# cargo +/target + +# pre-cargo /syscall.rs +/libtinyrust.rlib + +# rlib extraction and other intermediate artefacts +/*.o +/*.rmeta /payload /payload.bin -/tinyrust /tinyrust.ll -/*.o -/libtinyrust.rlib + +# final executable +/tinyrust diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..c781dbe --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,13 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "sc" +version = "0.2.3" +source = "git+https://github.com/AgustinCB/syscall.rs/#44546775beac0e16872d4aaf26e300ee907df837" + +[[package]] +name = "tiny-rust-executable" +version = "0.5.0" +dependencies = [ + "sc", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..b9279b8 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "tiny-rust-executable" +version = "0.5.0" +authors = [ + "Keegan McAllister ", + "Melvin Kicchi ", + "Hiroki Noda ", + "Torbjørn Birch Moltu " +] +license = "Apache-2.0 OR MIT" +edition = "2015" + +[lib] +name = "tinyrust" +path = "tinyrust.rs" + +[profile.dev] +opt-level = "z" +overflow-checks = false +lto = false +panic = "abort" + +[profile.release] +opt-level = "z" +overflow-checks = false +lto = false # enabling LTO breaks objdump and requires other flags to ld +panic = "abort" + +[dependencies] +# fork of https://github.com/japaric/syscall.rs (sc 0.2.2) with updated feature flags +sc = {git = "https://github.com/AgustinCB/syscall.rs/"} diff --git a/README.md b/README.md index 407a66e..d13ebf6 100644 --- a/README.md +++ b/README.md @@ -9,15 +9,18 @@ system calls. All of the machine code comes out of `rustc`. (While most of the operations originate from inline assembly, LLVM replaces the instructions with more compact ones!) -``` +```sh $ ./build.sh Tested on rustc 1.46.0-nightly (346aec9b0 2020-07-11) You have rustc 1.46.0-nightly (346aec9b0 2020-07-11) -Cloning into 'syscall.rs'... - Compiling sc v0.2.3 (file:///home/tormol/p/rust/tiny-rust-executable/syscall.rs) - -+ rustc tinyrust.rs --crate-type lib -L syscall.rs/target/release -C relocation-model=static -O -C opt-level=z ++ cargo build --release --verbose + Updating git repository `https://github.com/AgustinCB/syscall.rs/` + Compiling sc v0.2.3 (https://github.com/AgustinCB/syscall.rs/#44546775) + Running `rustc --crate-name sc /home/tormol/.cargo/git/checkouts/syscall.rs-a441cc4b410d529b/4454677/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts --crate-type lib --emit=dep-info,metadata,link -C opt-level=z -C panic=abort -Clinker-plugin-lto -C metadata=35c3430f33082929 -C extra-filename=-35c3430f33082929 --out-dir /home/tormol/p/rust/tiny-rust-executable/target/release/deps -L dependency=/home/tormol/p/rust/tiny-rust-executable/target/release/deps --cap-lints allow -C relocation-model=static` + Compiling tiny-rust-executable v0.5.0 (/home/tormol/p/rust/tiny-rust-executable) + Running `rustc --crate-name tinyrust tinyrust.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type lib --emit=dep-info,metadata,link -C opt-level=z -C panic=abort -Clinker-plugin-lto -C metadata=61b6ba1ff0efe210 -C extra-filename=-61b6ba1ff0efe210 --out-dir /home/tormol/p/rust/tiny-rust-executable/target/release/deps -L dependency=/home/tormol/p/rust/tiny-rust-executable/target/release/deps --extern sc=/home/tormol/p/rust/tiny-rust-executable/target/release/deps/libsc-35c3430f33082929.rmeta -C relocation-model=static` + Finished release [optimized] target(s) in 0.45s ++ ar t libtinyrust.rlib ++ grep '.o$' + OBJECT=tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o diff --git a/build.sh b/build.sh index c46d798..b5b3bd5 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ set -e -for d in rustc git cargo ar ld objcopy nasm hexdump; do +for d in rustc cargo ar ld objcopy nasm hexdump; do which $d >/dev/null || (echo "Can't find $d, needed to build"; exit 1) done @@ -10,24 +10,13 @@ printf "Tested on rustc 1.46.0-nightly (346aec9b0 2020-07-11)\nYou have " rustc --version echo -if [ ! -d syscall.rs ]; then - git clone --depth=1 https://github.com/AgustinCB/syscall.rs - # a fork of https://github.com/japaric/syscall.rs with updated asm feature flag - (cd syscall.rs && cargo build --release) - echo -fi - set -x -rustc tinyrust.rs --crate-type lib \ - -L syscall.rs/target/release \ - -C relocation-model=static \ - -O \ - -C opt-level=z +cargo build --release --verbose # tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o -OBJECT=$(ar t libtinyrust.rlib | grep '.o$') -ar x libtinyrust.rlib "$OBJECT" +OBJECT=$(ar t target/release/libtinyrust.rlib | grep '.o$') +ar x target/release/libtinyrust.rlib "$OBJECT" objdump -dr "$OBJECT" echo From 261831be2543f454a00f3137da772196146df389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B8rn=20Birch=20Moltu?= Date: Wed, 22 Jul 2020 22:20:06 +0200 Subject: [PATCH 18/21] Move license info to README --- COPYRIGHT | 7 ------- LICENSE-MIT | 2 -- README.md | 13 +++++++++++++ 3 files changed, 13 insertions(+), 9 deletions(-) delete mode 100644 COPYRIGHT diff --git a/COPYRIGHT b/COPYRIGHT deleted file mode 100644 index 54471e8..0000000 --- a/COPYRIGHT +++ /dev/null @@ -1,7 +0,0 @@ -This project is copyright 2015, Keegan McAllister - -Licensed under the Apache License, Version 2.0 or the MIT license , at your option. All files in the project -carrying such notice may not be copied, modified, or distributed except -according to those terms. diff --git a/LICENSE-MIT b/LICENSE-MIT index 82b3119..31aa793 100644 --- a/LICENSE-MIT +++ b/LICENSE-MIT @@ -1,5 +1,3 @@ -Copyright (c) 2014 The syscall.rs Project Developers - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the diff --git a/README.md b/README.md index d13ebf6..41d53b2 100644 --- a/README.md +++ b/README.md @@ -72,3 +72,16 @@ Disassembly of section .text.main: $ ./tinyrust Hello! ``` + +## License + +Licensed under either of + +* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) +* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. From 0671c4c24c40f00da898f5fb3638ecd46791f6c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B8rn=20Birch=20Moltu?= Date: Sat, 1 Aug 2020 11:41:06 +0200 Subject: [PATCH 19/21] Switch to now updated crates.io version of sc The changes in the fork I was using have now been merged and released. --- Cargo.lock | 5 +++-- Cargo.toml | 5 ++--- README.md | 7 ++++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c781dbe..b979eec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,11 +3,12 @@ [[package]] name = "sc" version = "0.2.3" -source = "git+https://github.com/AgustinCB/syscall.rs/#44546775beac0e16872d4aaf26e300ee907df837" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "176365c8253e381ad147774b6d9730a1b3fe2d7db498af521ed7d968674a55b3" [[package]] name = "tiny-rust-executable" -version = "0.5.0" +version = "0.5.1" dependencies = [ "sc", ] diff --git a/Cargo.toml b/Cargo.toml index b9279b8..522e30a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tiny-rust-executable" -version = "0.5.0" +version = "0.5.1" authors = [ "Keegan McAllister ", "Melvin Kicchi ", @@ -27,5 +27,4 @@ lto = false # enabling LTO breaks objdump and requires other flags to ld panic = "abort" [dependencies] -# fork of https://github.com/japaric/syscall.rs (sc 0.2.2) with updated feature flags -sc = {git = "https://github.com/AgustinCB/syscall.rs/"} +sc = "0.2.3" diff --git a/README.md b/README.md index 41d53b2..1278676 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,10 @@ Tested on rustc 1.46.0-nightly (346aec9b0 2020-07-11) You have rustc 1.46.0-nightly (346aec9b0 2020-07-11) + cargo build --release --verbose - Updating git repository `https://github.com/AgustinCB/syscall.rs/` - Compiling sc v0.2.3 (https://github.com/AgustinCB/syscall.rs/#44546775) - Running `rustc --crate-name sc /home/tormol/.cargo/git/checkouts/syscall.rs-a441cc4b410d529b/4454677/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts --crate-type lib --emit=dep-info,metadata,link -C opt-level=z -C panic=abort -Clinker-plugin-lto -C metadata=35c3430f33082929 -C extra-filename=-35c3430f33082929 --out-dir /home/tormol/p/rust/tiny-rust-executable/target/release/deps -L dependency=/home/tormol/p/rust/tiny-rust-executable/target/release/deps --cap-lints allow -C relocation-model=static` + Downloaded sc v0.2.3 + Downloaded 1 crate (37.2 KB) in 0.71s + Compiling sc v0.2.3 + Running `rustc --crate-name sc /home/tormol/.cargo/registry/src/github.com-1ecc6299db9ec823/sc-0.2.3/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts --crate-type lib --emit=dep-info,metadata,link -C opt-level=z -C panic=abort -Cembed-bitcode=no -C metadata=8fa96b43c9d094b0 -C extra-filename=-8fa96b43c9d094b0 --out-dir /home/tormol/p/rust/tiny-rust-demo/target/release/deps -L dependency=/home/tormol/p/rust/tiny-rust-demo/target/release/deps --cap-lints allow -C relocation-model=static` Compiling tiny-rust-executable v0.5.0 (/home/tormol/p/rust/tiny-rust-executable) Running `rustc --crate-name tinyrust tinyrust.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type lib --emit=dep-info,metadata,link -C opt-level=z -C panic=abort -Clinker-plugin-lto -C metadata=61b6ba1ff0efe210 -C extra-filename=-61b6ba1ff0efe210 --out-dir /home/tormol/p/rust/tiny-rust-executable/target/release/deps -L dependency=/home/tormol/p/rust/tiny-rust-executable/target/release/deps --extern sc=/home/tormol/p/rust/tiny-rust-executable/target/release/deps/libsc-35c3430f33082929.rmeta -C relocation-model=static` Finished release [optimized] target(s) in 0.45s From 0f498f173efb68108109f1ae80e869af2349c201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B8rn=20Birch=20Moltu?= Date: Sat, 1 Aug 2020 12:34:12 +0200 Subject: [PATCH 20/21] Expand README --- README.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1278676..5c5abba 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,17 @@ [![Build Status](https://api.cirrus-ci.com/github/tormol/tiny-rust-executable.svg)](https://cirrus-ci.com/github/tormol/tiny-rust-executable) -Requires nightly Rust because it uses the `sc` crate to make direct -system calls. - `elf.s` contains a custom ELF header, but no instructions. All of the machine code comes out of `rustc`. (While most of the operations originate from inline assembly, LLVM replaces the instructions with more compact ones!) +This project is built by running the `./build.sh` script instead of `cargo build`: Making the binary this small requires post-processing steps which cargo doesn't support. +Requires nightly Rust because it uses inline assembly (through the `sc` crate) to make direct system calls. + +[Blog post about this demo](http://mainisusuallyafunction.blogspot.com/2015/01/151-byte-static-linux-binary-in-rust.html), by Keegan McAllister who originally created it. + +## Example + ```sh $ ./build.sh Tested on rustc 1.46.0-nightly (346aec9b0 2020-07-11) @@ -86,3 +90,7 @@ at your option. ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +## See Also + +* [A 99-byte x86 (32-bit) Go executable](https://github.com/xaionaro-go/tinyhelloworld) From d5db564b4610aa98505c8abdb950b219fb141b3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B8rn=20Birch=20Moltu?= Date: Thu, 20 Mar 2025 22:08:05 +0100 Subject: [PATCH 21/21] Make it work on stable * Update sc to 2.3.7 which uses asm!() instead of the removed llvm_asm!(). * Rename .cargo/config to avoid warning. * Update version in build.sh and output in README. --- .cargo/{config => config.toml} | 0 Cargo.lock | 6 ++-- README.md | 62 ++++++++++++++++++---------------- build.sh | 2 +- 4 files changed, 37 insertions(+), 33 deletions(-) rename .cargo/{config => config.toml} (100%) diff --git a/.cargo/config b/.cargo/config.toml similarity index 100% rename from .cargo/config rename to .cargo/config.toml diff --git a/Cargo.lock b/Cargo.lock index b979eec..1edc739 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,10 +1,12 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 4 + [[package]] name = "sc" -version = "0.2.3" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176365c8253e381ad147774b6d9730a1b3fe2d7db498af521ed7d968674a55b3" +checksum = "010e18bd3bfd1d45a7e666b236c78720df0d9a7698ebaa9c1c559961eb60a38b" [[package]] name = "tiny-rust-executable" diff --git a/README.md b/README.md index 5c5abba..b77c8ea 100644 --- a/README.md +++ b/README.md @@ -15,50 +15,52 @@ Requires nightly Rust because it uses inline assembly (through the `sc` crate) t ```sh $ ./build.sh -Tested on rustc 1.46.0-nightly (346aec9b0 2020-07-11) -You have rustc 1.46.0-nightly (346aec9b0 2020-07-11) +Tested on rustc 1.85.0 (4d91de4e4 2025-02-17) +You have rustc 1.85.0 (4d91de4e4 2025-02-17) + cargo build --release --verbose - Downloaded sc v0.2.3 - Downloaded 1 crate (37.2 KB) in 0.71s - Compiling sc v0.2.3 - Running `rustc --crate-name sc /home/tormol/.cargo/registry/src/github.com-1ecc6299db9ec823/sc-0.2.3/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts --crate-type lib --emit=dep-info,metadata,link -C opt-level=z -C panic=abort -Cembed-bitcode=no -C metadata=8fa96b43c9d094b0 -C extra-filename=-8fa96b43c9d094b0 --out-dir /home/tormol/p/rust/tiny-rust-demo/target/release/deps -L dependency=/home/tormol/p/rust/tiny-rust-demo/target/release/deps --cap-lints allow -C relocation-model=static` - Compiling tiny-rust-executable v0.5.0 (/home/tormol/p/rust/tiny-rust-executable) - Running `rustc --crate-name tinyrust tinyrust.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type lib --emit=dep-info,metadata,link -C opt-level=z -C panic=abort -Clinker-plugin-lto -C metadata=61b6ba1ff0efe210 -C extra-filename=-61b6ba1ff0efe210 --out-dir /home/tormol/p/rust/tiny-rust-executable/target/release/deps -L dependency=/home/tormol/p/rust/tiny-rust-executable/target/release/deps --extern sc=/home/tormol/p/rust/tiny-rust-executable/target/release/deps/libsc-35c3430f33082929.rmeta -C relocation-model=static` - Finished release [optimized] target(s) in 0.45s -++ ar t libtinyrust.rlib + Updating crates.io index + Locking 1 package to latest compatible version + Downloaded sc v0.2.7 + Downloaded 1 crate (39.6KiB) in 0.88s + Compiling sc v0.2.7 + Running `/home/tbm/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc --crate-name sc --edition=2015 /home/tbm/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sc-0.2.7/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=137 --crate-type lib --emit=dep-info,metadata,link -C opt-level=z -C panic=abort -C embed-bitcode=no --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values())' -C metadata=de0ba5d176876c9c -C extra-filename=-e50ec66b37f4e2cb --out-dir /home/tbm/p/rust/tiny-rust-demo/target/release/deps -C strip=debuginfo -L dependency=/home/tbm/p/rust/tiny-rust-demo/target/release/deps --cap-lints allow -C relocation-model=static` + Compiling tiny-rust-executable v0.5.1 (/home/tbm/p/rust/tiny-rust-demo) + Running `/home/tbm/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc --crate-name tinyrust --edition=2015 tinyrust.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=137 --crate-type lib --emit=dep-info,metadata,link -C opt-level=z -C panic=abort -C embed-bitcode=no --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values())' -C metadata=76aa331090f20463 -C extra-filename=-f769982e789cd78c --out-dir /home/tbm/p/rust/tiny-rust-demo/target/release/deps -C strip=debuginfo -L dependency=/home/tbm/p/rust/tiny-rust-demo/target/release/deps --extern sc=/home/tbm/p/rust/tiny-rust-demo/target/release/deps/libsc-e50ec66b37f4e2cb.rmeta -C relocation-model=static` + Finished `release` profile [optimized] target(s) in 0.06s +++ ar t target/release/libtinyrust.rlib ++ grep '.o$' -+ OBJECT=tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o -+ ar x libtinyrust.rlib tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o -+ objdump -dr tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o ++ OBJECT=tinyrust-f769982e789cd78c.tinyrust.35d04aaf99cb8b97-cgu.0.rcgu.o ++ ar x target/release/libtinyrust.rlib tinyrust-f769982e789cd78c.tinyrust.35d04aaf99cb8b97-cgu.0.rcgu.o ++ objdump -dr tinyrust-f769982e789cd78c.tinyrust.35d04aaf99cb8b97-cgu.0.rcgu.o -tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o: file format elf64-x86-64 +tinyrust-f769982e789cd78c.tinyrust.35d04aaf99cb8b97-cgu.0.rcgu.o: file format elf64-x86-64 Disassembly of section .text.main: 0000000000000000
: - 0: 6a 07 pushq $0x7 - 2: 5a pop %rdx - 3: 6a 01 pushq $0x1 - 5: 58 pop %rax - 6: be 08 00 40 00 mov $0x400008,%esi - b: 48 89 c7 mov %rax,%rdi - e: 0f 05 syscall - 10: 6a 3c pushq $0x3c - 12: 58 pop %rax - 13: 31 ff xor %edi,%edi - 15: 0f 05 syscall - 17: 0f 0b ud2 + 0: 6a 01 push $0x1 + 2: 58 pop %rax + 3: 6a 07 push $0x7 + 5: 5a pop %rdx + 6: be 08 00 40 00 mov $0x400008,%esi + b: 48 89 c7 mov %rax,%rdi + e: 0f 05 syscall + 10: 6a 3c push $0x3c + 12: 58 pop %rax + 13: 31 ff xor %edi,%edi + 15: 0f 05 syscall + 17: 0f 0b ud2 + echo -+ ld --gc-sections -e main -T script.ld -o payload tinyrust.tinyrust.3a1fbbbh-cgu.0.rcgu.o ++ ld --gc-sections -e main -T script.ld -o payload tinyrust-f769982e789cd78c.tinyrust.35d04aaf99cb8b97-cgu.0.rcgu.o + objcopy -j combined -O binary payload payload.bin ++ nm --format=posix payload ++ grep '^main ' ++ awk '{print $3}' -+ ENTRY=0000000000400070 -+ nasm -f bin -o tinyrust -D entry=0x0000000000400070 elf.s ++ ENTRY=400070 ++ nasm -f bin -o tinyrust -D entry=0x400070 elf.s + chmod +x tinyrust + hexdump -C tinyrust 00000000 7f 45 4c 46 02 01 01 09 48 65 6c 6c 6f 21 0a 00 |.ELF....Hello!..| @@ -68,7 +70,7 @@ Disassembly of section .text.main: 00000040 00 00 00 00 00 00 00 00 00 00 40 00 00 00 00 00 |..........@.....| 00000050 00 00 40 00 00 00 00 00 89 00 00 00 00 00 00 00 |..@.............| 00000060 89 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 |................| -00000070 6a 07 5a 6a 01 58 be 08 00 40 00 48 89 c7 0f 05 |j.Zj.X...@.H....| +00000070 6a 01 58 6a 07 5a be 08 00 40 00 48 89 c7 0f 05 |j.Xj.Z...@.H....| 00000080 6a 3c 58 31 ff 0f 05 0f 0b |j/dev/null || (echo "Can't find $d, needed to build"; exit 1) done -printf "Tested on rustc 1.46.0-nightly (346aec9b0 2020-07-11)\nYou have " +printf "Tested on rustc 1.85.0 (4d91de4e4 2025-02-17)\nYou have " rustc --version echo