summaryrefslogtreecommitdiff
path: root/tests/tst-ar-runner.sh
diff options
context:
space:
mode:
authorkx <kx@radix-linux.su>2026-10-09 18:00:15 +0300
committerkx <kx@radix-linux.su>2026-10-09 18:00:15 +0300
commit065da3509019b15dd0e678072e6be629e5330bef (patch)
tree69c934c9e786ac048b4fbe8f4c4c5571661521f4 /tests/tst-ar-runner.sh
parentd130fe27fa753be02ed76fd9b277aa3c3d928eb9 (diff)
downloadlibmcpu-0.4.0.tar.xz
Version 0.4.00.4.0
Diffstat (limited to 'tests/tst-ar-runner.sh')
-rwxr-xr-xtests/tst-ar-runner.sh122
1 files changed, 122 insertions, 0 deletions
diff --git a/tests/tst-ar-runner.sh b/tests/tst-ar-runner.sh
new file mode 100755
index 0000000..ffc939a
--- /dev/null
+++ b/tests/tst-ar-runner.sh
@@ -0,0 +1,122 @@
+#!/bin/sh
+set -eu
+
+: "${PACKAGE_VERSION:?}"
+
+: "${CPU_AS:?}" "${CPU_AR:?}"
+
+TMP=${TMPDIR:-/tmp}/libmcpu-ar-$$
+mkdir -p "$TMP"
+trap 'rm -rf "$TMP"' EXIT HUP INT TERM
+
+cat > "$TMP/a.s" <<'EOS'
+.global foo
+.text
+foo:
+ RET
+EOS
+
+cat > "$TMP/very-long-member-name-for-mcpu.s" <<'EOS'
+.global bar
+.text
+bar:
+ RET
+EOS
+
+cat > "$TMP/c.s" <<'EOS'
+.global baz
+.text
+baz:
+ RET
+EOS
+
+"$CPU_AS" -o "$TMP/a.o" "$TMP/a.s"
+"$CPU_AS" -o "$TMP/very-long-member-name-for-mcpu.o" \
+ "$TMP/very-long-member-name-for-mcpu.s"
+"$CPU_AS" -o "$TMP/c.o" "$TMP/c.s"
+
+# rcs creates a deterministic UNIX archive, preserves command-line member
+# order, supports a long member name, and writes a real ar symbol index.
+"$CPU_AR" rcs "$TMP/libx.a" "$TMP/a.o" \
+ "$TMP/very-long-member-name-for-mcpu.o"
+"$CPU_AR" t "$TMP/libx.a" > "$TMP/list"
+cat > "$TMP/list.expected" <<'EOS'
+a.o
+very-long-member-name-for-mcpu.o
+EOS
+cmp "$TMP/list.expected" "$TMP/list"
+
+first_member=`dd if="$TMP/libx.a" bs=1 skip=8 count=1 2>/dev/null`
+[ "$first_member" = / ]
+
+# p returns the exact member bytes.
+"$CPU_AR" p "$TMP/libx.a" a.o > "$TMP/printed.o"
+cmp "$TMP/a.o" "$TMP/printed.o"
+
+# x restores exact member bytes, including BSD extended-name members.
+mkdir "$TMP/extract"
+(
+ cd "$TMP/extract"
+ "$CPU_AR" x ../libx.a
+)
+cmp "$TMP/a.o" "$TMP/extract/a.o"
+cmp "$TMP/very-long-member-name-for-mcpu.o" \
+ "$TMP/extract/very-long-member-name-for-mcpu.o"
+
+# Archive output is deterministic across independent creations.
+"$CPU_AR" rcs "$TMP/libx2.a" "$TMP/a.o" \
+ "$TMP/very-long-member-name-for-mcpu.o"
+cmp "$TMP/libx.a" "$TMP/libx2.a"
+
+# q always appends. Existing symbol-index state remains present.
+"$CPU_AR" q "$TMP/libx.a" "$TMP/c.o"
+"$CPU_AR" t "$TMP/libx.a" > "$TMP/list"
+cat > "$TMP/list.expected" <<'EOS'
+a.o
+very-long-member-name-for-mcpu.o
+c.o
+EOS
+cmp "$TMP/list.expected" "$TMP/list"
+first_member=`dd if="$TMP/libx.a" bs=1 skip=8 count=1 2>/dev/null`
+[ "$first_member" = / ]
+
+# r replaces a member in place rather than moving it to the end.
+cat > "$TMP/c.s" <<'EOS'
+.global qux
+.text
+qux:
+ RET
+EOS
+"$CPU_AS" -o "$TMP/c.o" "$TMP/c.s"
+"$CPU_AR" r "$TMP/libx.a" "$TMP/c.o"
+"$CPU_AR" t "$TMP/libx.a" > "$TMP/list"
+cmp "$TMP/list.expected" "$TMP/list"
+"$CPU_AR" p "$TMP/libx.a" c.o > "$TMP/printed-c.o"
+cmp "$TMP/c.o" "$TMP/printed-c.o"
+
+# d removes named members and s rebuilds the symbol index explicitly.
+"$CPU_AR" d "$TMP/libx.a" a.o
+"$CPU_AR" s "$TMP/libx.a"
+"$CPU_AR" t "$TMP/libx.a" > "$TMP/list"
+cat > "$TMP/list.expected" <<'EOS'
+very-long-member-name-for-mcpu.o
+c.o
+EOS
+cmp "$TMP/list.expected" "$TMP/list"
+first_member=`dd if="$TMP/libx.a" bs=1 skip=8 count=1 2>/dev/null`
+[ "$first_member" = / ]
+
+# A static MCPU archive may contain only valid current MELF ET_REL objects.
+printf 'not MELF\n' > "$TMP/bad.o"
+if "$CPU_AR" r "$TMP/bad.a" "$TMP/bad.o" >/dev/null 2>"$TMP/bad.err"; then
+ echo "mcpu-ar unexpectedly accepted a non-MELF member" >&2
+ exit 1
+fi
+grep -q 'not a MELF file' "$TMP/bad.err"
+test ! -e "$TMP/bad.a"
+
+"$CPU_AR" --version | grep -Fq "$PACKAGE_VERSION"
+"$CPU_AR" --help | grep -q 'rcs'
+"$CPU_AR" --help | grep -q 'symbol index'
+
+exit 0