summaryrefslogtreecommitdiff
path: root/tests/tst-static-option-runner.sh
diff options
context:
space:
mode:
Diffstat (limited to 'tests/tst-static-option-runner.sh')
-rwxr-xr-xtests/tst-static-option-runner.sh124
1 files changed, 124 insertions, 0 deletions
diff --git a/tests/tst-static-option-runner.sh b/tests/tst-static-option-runner.sh
new file mode 100755
index 0000000..1515a7f
--- /dev/null
+++ b/tests/tst-static-option-runner.sh
@@ -0,0 +1,124 @@
+#!/bin/sh
+set -eu
+
+: "${CPU_AS:?}" "${CPU_LD:?}" "${CPU_RUN:?}" "${CPU_READELF:?}" "${CPU_AR:?}"
+
+TMP=${TMPDIR:-/tmp}/libmcpu-static-option-$$
+mkdir -p "$TMP/both" "$TMP/soonly" "$TMP/aonly"
+trap 'rm -rf "$TMP"' EXIT HUP INT TERM
+
+cat > "$TMP/main.s" <<'EOS'
+.global _life
+.extern pick
+.text
+_start_life:
+ LDI r64@0x00000, 40
+ CALL pick
+ MOV r64@0x00018, r64@0x00000
+ LDI r32@0x00030, 0
+ EXIT r32@0x00030
+EOS
+
+cat > "$TMP/wrapper.s" <<'EOS'
+.global wrapper
+.extern pick
+.text
+wrapper:
+ CALL pick
+ RET
+EOS
+
+cat > "$TMP/pick-static.s" <<'EOS'
+.global pick
+.text
+pick:
+ LDI r64@0x00008, 2
+ IADD r64@0x00000, r64@0x00000, r64@0x00008
+ RET
+EOS
+
+cat > "$TMP/pick-shared.s" <<'EOS'
+.global pick
+.text
+pick:
+ LDI r64@0x00008, 3
+ IADD r64@0x00000, r64@0x00000, r64@0x00008
+ RET
+EOS
+
+"$CPU_AS" -o "$TMP/main.o" "$TMP/main.s"
+"$CPU_AS" -o "$TMP/wrapper.o" "$TMP/wrapper.s"
+"$CPU_AS" -o "$TMP/pick-static.o" "$TMP/pick-static.s"
+"$CPU_AS" -o "$TMP/pick-shared.o" "$TMP/pick-shared.s"
+
+"$CPU_AR" rcs "$TMP/both/libpick.a" "$TMP/pick-static.o"
+cp "$TMP/both/libpick.a" "$TMP/aonly/libpick.a"
+"$CPU_LD" --shared --soname=libpick.so.1 \
+ -o "$TMP/both/libpick.so.1.0.0" "$TMP/pick-shared.o"
+ln -s libpick.so.1.0.0 "$TMP/both/libpick.so.1"
+ln -s libpick.so.1 "$TMP/both/libpick.so"
+cp "$TMP/both/libpick.so.1.0.0" "$TMP/soonly/libpick.so.1.0.0"
+ln -s libpick.so.1.0.0 "$TMP/soonly/libpick.so.1"
+ln -s libpick.so.1 "$TMP/soonly/libpick.so"
+
+# Normal ABI-v3 lookup prefers .so in a directory containing both providers.
+"$CPU_LD" --dynamic --stack-size=4096 --no-heap \
+ -L"$TMP/both" -lpick -o "$TMP/dynamic-shared" "$TMP/main.o"
+"$CPU_READELF" -d "$TMP/dynamic-shared" > "$TMP/dynamic-shared.dynamic"
+grep -q 'NEEDED.*\[libpick.so.1\]' "$TMP/dynamic-shared.dynamic"
+[ "`"$CPU_RUN" --library-path="$TMP/both" \
+ --int-reg=r64@0x00018 "$TMP/dynamic-shared"`" = 43 ]
+
+# --static changes only -l resolution. The output is still ABI-v3 ET_EXEC,
+# but libpick.a is selected and no DT_NEEDED is emitted.
+"$CPU_LD" --dynamic --static --stack-size=4096 --no-heap \
+ -L"$TMP/both" -lpick -o "$TMP/dynamic-static" "$TMP/main.o"
+"$CPU_READELF" -h "$TMP/dynamic-static" > "$TMP/dynamic-static.header"
+"$CPU_READELF" -d "$TMP/dynamic-static" > "$TMP/dynamic-static.dynamic"
+grep -q 'ABI Version:.*3' "$TMP/dynamic-static.header"
+[ "`grep -c 'NEEDED' "$TMP/dynamic-static.dynamic" || true`" -eq 0 ]
+[ "`"$CPU_RUN" --int-reg=r64@0x00018 "$TMP/dynamic-static"`" = 42 ]
+
+# --shared --static remains ABI-v3 ET_DYN with its own SONAME; the selected
+# archive member is incorporated into the image and adds no NEEDED entry.
+"$CPU_LD" --shared --static --soname=libwrapper.so.1 \
+ -L"$TMP/both" -lpick -o "$TMP/libwrapper.so" "$TMP/wrapper.o"
+"$CPU_READELF" -d "$TMP/libwrapper.so" > "$TMP/libwrapper.dynamic"
+grep -q 'SONAME.*\[libwrapper.so.1\]' "$TMP/libwrapper.dynamic"
+[ "`grep -c 'NEEDED' "$TMP/libwrapper.dynamic" || true`" -eq 0 ]
+
+# -r already accepts static archives only; --static is therefore a harmless
+# explicit statement of the same library-selection policy.
+"$CPU_LD" -r --static -L"$TMP/both" -lpick \
+ -o "$TMP/partial.o" "$TMP/wrapper.o"
+"$CPU_READELF" -s "$TMP/partial.o" > "$TMP/partial.sym"
+grep -q '[[:space:]]pick$' "$TMP/partial.sym"
+
+# ABI-v1 is already fully static; accepting --static must preserve that path.
+"$CPU_LD" --static --stack-size=4096 --no-heap \
+ -L"$TMP/both" -lpick -o "$TMP/abi1-static" "$TMP/main.o"
+[ "`"$CPU_RUN" --int-reg=r64@0x00018 "$TMP/abi1-static"`" = 42 ]
+
+# Forced-static lookup skips a .so-only earlier directory and continues until
+# it finds libpick.a in a later directory.
+"$CPU_LD" --dynamic --static --stack-size=4096 --no-heap \
+ -L"$TMP/soonly" -L"$TMP/aonly" -lpick \
+ -o "$TMP/later-archive" "$TMP/main.o"
+[ "`"$CPU_RUN" --int-reg=r64@0x00018 "$TMP/later-archive"`" = 42 ]
+"$CPU_READELF" -d "$TMP/later-archive" > "$TMP/later-archive.dynamic"
+[ "`grep -c 'NEEDED' "$TMP/later-archive.dynamic" || true`" -eq 0 ]
+
+# With only a shared provider available, --static must fail and must not fall
+# back to libpick.so.
+if "$CPU_LD" --dynamic --static --stack-size=4096 --no-heap \
+ -L"$TMP/soonly" -lpick -o "$TMP/missing-static" "$TMP/main.o" \
+ >/dev/null 2>"$TMP/missing-static.err"; then
+ echo "--static unexpectedly selected a shared library" >&2
+ exit 1
+fi
+grep -q 'libpick.a' "$TMP/missing-static.err"
+
+"$CPU_LD" --help 2>&1 | grep -q -- '--static'
+"$CPU_LD" --help 2>&1 | grep -q 'force every -l<name> lookup to use lib<name>.a'
+
+exit 0