#!/bin/sh # vim: set ts=4: set -eu RUSTC="$1" TMPDIR="$(pwd)/.tmp-${0##*/}-$RANDOM" failed=0 _rustc() { printf '\n$ rustc %s\n' "$*" "$RUSTC" "$@" } die() { printf '\033[1;31mERROR:\033[0m %s\n' "$1" >&2 # bold red exit 1 } fail() { printf '\033[1;31mFAIL:\033[0m %s\n' "$1" >&2 # bold red failed=$(( failed + 1 )) } assert_dynamic() { readelf -l "$1" | grep -Fqw INTERP \ && readelf -d "$1" | grep -Fqw NEEDED || { fail "$1 is not a dynamic executable!" readelf -ld "$1" } } assert_ok() { "$1" || fail "$1 exited with status $?" } assert_panic() { local status=0 "$1" || status=$? && [ "$status" = 101 ] \ || fail "$1 exited with status $status, but expected 101" } assert_pie() { readelf -d "$1" | grep -Fw FLAGS_1 | grep -Fqw PIE || { fail "$1 is not a PIE executable!" readelf -d "$1" } } assert_static() { test -f "$1" \ && ! readelf -l "$1" | grep -Fqw INTERP \ && ! readelf -d "$1" | grep -Fqw NEEDED || { fail "$1 is not a static executable!" readelf -ld "$1" } } #-------------------- M a i n -------------------- test -d "$TMPDIR" && die "$TMPDIR already exists!" mkdir -p "$TMPDIR" trap "rm -R '$TMPDIR'" EXIT cd "$TMPDIR" cat >> hello_world.rs <<-EOF fn main() { println!("Hello, world!"); } EOF _rustc hello_world.rs assert_ok ./hello_world assert_dynamic hello_world assert_pie hello_world rm -f hello_world _rustc -C target-feature=-crt-static hello_world.rs assert_ok ./hello_world assert_dynamic hello_world assert_pie hello_world rm -f hello_world _rustc -C target-feature=+crt-static hello_world.rs assert_ok ./hello_world assert_static hello_world assert_pie hello_world rm -f hello_world cat >> panic.rs <<-EOF fn main() { panic!("This should panic"); } EOF _rustc -C target-feature=-crt-static panic.rs assert_panic ./panic _rustc -C target-feature=+crt-static panic.rs assert_panic ./panic [ "$failed" -eq 0 ] || die "$failed assertion(s) has failed"