diff options
| author | kx <kx@radix-linux.su> | 2026-10-09 18:00:15 +0300 |
|---|---|---|
| committer | kx <kx@radix-linux.su> | 2026-10-09 18:00:15 +0300 |
| commit | 065da3509019b15dd0e678072e6be629e5330bef (patch) | |
| tree | 69c934c9e786ac048b4fbe8f4c4c5571661521f4 /tests/tst-objcopy-runner.sh | |
| parent | d130fe27fa753be02ed76fd9b277aa3c3d928eb9 (diff) | |
| download | libmcpu-0.4.0.tar.xz | |
Version 0.4.00.4.0
Diffstat (limited to 'tests/tst-objcopy-runner.sh')
| -rwxr-xr-x | tests/tst-objcopy-runner.sh | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/tests/tst-objcopy-runner.sh b/tests/tst-objcopy-runner.sh new file mode 100755 index 0000000..96b501b --- /dev/null +++ b/tests/tst-objcopy-runner.sh @@ -0,0 +1,160 @@ +#!/bin/sh +set -eu + +: "${PACKAGE_VERSION:?}" + +: "${CPU_AS:?}" "${CPU_LD:?}" "${CPU_RUN:?}" "${CPU_READELF:?}" +: "${CPU_AR:?}" "${CPU_NM:?}" "${CPU_OBJCOPY:?}" + +TMP=${TMPDIR:-/tmp}/libmcpu-objcopy-$$ +mkdir -p "$TMP" +trap 'rm -rf "$TMP"' EXIT HUP INT TERM + +cat > "$TMP/main.s" <<'EOS' +.global _life +.text +_start_life: + LDI r64@0x00000, 42 + LDI r32@0x00030, 0 + EXIT r32@0x00030 +EOS + +cat > "$TMP/add-one.s" <<'EOS' +.global add_one +.text +add_one: + LDI r64@0x00008, 1 + IADD r64@0x00000, r64@0x00000, r64@0x00008 + RET +EOS + +"$CPU_AS" -o "$TMP/main.o" "$TMP/main.s" +"$CPU_AS" -o "$TMP/add-one.o" "$TMP/add-one.s" +"$CPU_LD" --stack-size=4096 --no-heap -o "$TMP/main" "$TMP/main.o" +"$CPU_AR" rcs "$TMP/libadd.a" "$TMP/add-one.o" + +# Plain MELF -> MELF copying is byte-for-byte when no edit is requested. +"$CPU_OBJCOPY" "$TMP/main" "$TMP/main.copy" +cmp "$TMP/main" "$TMP/main.copy" + +printf 'metadata-one\n' > "$TMP/note-one" +printf 'metadata-two\n' > "$TMP/note-two" + +# Add non-ALLOC metadata without touching the executable image. +"$CPU_OBJCOPY" --add-section=.note.test="$TMP/note-one" \ + "$TMP/main" "$TMP/main.note" +"$CPU_READELF" -S "$TMP/main.note" | grep -q '\.note\.test' +test "$("$CPU_RUN" --int-reg=r64@0x00000 "$TMP/main.note")" = 42 + +# Dump is read-only and may inspect runtime sections as well as metadata. +"$CPU_OBJCOPY" --dump-section=.note.test="$TMP/note.dump" \ + "$TMP/main.note" "$TMP/main.dump-copy" +cmp "$TMP/note-one" "$TMP/note.dump" +"$CPU_OBJCOPY" --dump-section=.text="$TMP/text.before" \ + "$TMP/main" "$TMP/main.text-copy" +"$CPU_OBJCOPY" --dump-section=.text="$TMP/text.after" \ + "$TMP/main.note" "$TMP/main.note-copy" +cmp "$TMP/text.before" "$TMP/text.after" + +# Update and rename apply only to safe non-ALLOC PROGBITS metadata. +"$CPU_OBJCOPY" --update-section=.note.test="$TMP/note-two" \ + "$TMP/main.note" "$TMP/main.updated" +"$CPU_OBJCOPY" --dump-section=.note.test="$TMP/updated.dump" \ + "$TMP/main.updated" "$TMP/main.updated-copy" +cmp "$TMP/note-two" "$TMP/updated.dump" + +"$CPU_OBJCOPY" --rename-section=.note.test=.note.renamed \ + "$TMP/main.updated" "$TMP/main.renamed" +"$CPU_READELF" -S "$TMP/main.renamed" | grep -q '\.note\.renamed' +if "$CPU_READELF" -S "$TMP/main.renamed" | grep -q '\.note\.test'; then + echo "old section name survived mcpu-objcopy rename" >&2 + exit 1 +fi + +# Safe metadata can be removed; runtime behavior stays unchanged. +"$CPU_OBJCOPY" -R .note.renamed "$TMP/main.renamed" "$TMP/main.removed" +if "$CPU_READELF" -S "$TMP/main.removed" | grep -q '\.note\.renamed'; then + echo "removed metadata section survived mcpu-objcopy" >&2 + exit 1 +fi +test "$("$CPU_RUN" --int-reg=r64@0x00000 "$TMP/main.removed")" = 42 + +# Runtime-visible and structural sections are protected. +if "$CPU_OBJCOPY" -R .text "$TMP/main" "$TMP/bad-remove" >/dev/null 2>&1; then + echo "mcpu-objcopy removed .text" >&2 + exit 1 +fi +if "$CPU_OBJCOPY" --update-section=.text="$TMP/note-one" \ + "$TMP/main" "$TMP/bad-update" >/dev/null 2>&1; then + echo "mcpu-objcopy updated .text" >&2 + exit 1 +fi +if "$CPU_OBJCOPY" --rename-section=.text=.foo \ + "$TMP/main" "$TMP/bad-rename" >/dev/null 2>&1; then + echo "mcpu-objcopy renamed .text" >&2 + exit 1 +fi +if "$CPU_OBJCOPY" --add-section=.text="$TMP/note-one" \ + "$TMP/main" "$TMP/bad-duplicate" >/dev/null 2>&1; then + echo "mcpu-objcopy added duplicate .text" >&2 + exit 1 +fi + +# --only-section is strict: an executable cannot lose its runtime image. +if "$CPU_OBJCOPY" -j .note.test "$TMP/main.note" "$TMP/bad-only" \ + >/dev/null 2>&1; then + echo "mcpu-objcopy created an incomplete ET_EXEC with -j" >&2 + exit 1 +fi + +# ET_REL link semantics are protected, but optional metadata may be filtered. +"$CPU_OBJCOPY" --add-section=.note.rel="$TMP/note-one" \ + "$TMP/main.o" "$TMP/main.note.o" +"$CPU_OBJCOPY" \ + -j .text -j .symtab -j .strtab -j .mcpu.target -j .shstrtab \ + "$TMP/main.note.o" "$TMP/main.filtered.o" +if "$CPU_READELF" -S "$TMP/main.filtered.o" | grep -q '\.note\.rel'; then + echo "--only-section failed to remove optional ET_REL metadata" >&2 + exit 1 +fi +"$CPU_LD" --stack-size=4096 --no-heap -o "$TMP/main.filtered" \ + "$TMP/main.filtered.o" +test "$("$CPU_RUN" --int-reg=r64@0x00000 "$TMP/main.filtered")" = 42 + +if "$CPU_OBJCOPY" -R .symtab "$TMP/main.o" "$TMP/bad-rel" \ + >/dev/null 2>&1; then + echo "mcpu-objcopy removed ET_REL .symtab" >&2 + exit 1 +fi + +# Archives are transformed member-by-member and retain their symbol index. +"$CPU_OBJCOPY" --add-section=.note.arc="$TMP/note-one" \ + "$TMP/libadd.a" "$TMP/libadd.note.a" +"$CPU_NM" -A "$TMP/libadd.note.a" | grep -q 'add_one' +mkdir "$TMP/extract" +( + cd "$TMP/extract" + "$CPU_AR" x ../libadd.note.a + "$CPU_READELF" -S add-one.o | grep -q '\.note\.arc' +) +"$CPU_OBJCOPY" -R .note.arc "$TMP/libadd.note.a" "$TMP/libadd.clean.a" +"$CPU_NM" -A "$TMP/libadd.clean.a" | grep -q 'add_one' +if "$CPU_OBJCOPY" --dump-section=.text="$TMP/archive.dump" \ + "$TMP/libadd.a" "$TMP/libadd.dump.a" >/dev/null 2>&1; then + echo "mcpu-objcopy accepted ambiguous archive --dump-section" >&2 + exit 1 +fi + +"$CPU_OBJCOPY" --help | grep -q -- '--add-section=NAME=FILE' +"$CPU_OBJCOPY" --version | grep -Fq "$PACKAGE_VERSION" + +if "$CPU_OBJCOPY" "$TMP/main" >/dev/null 2>&1; then + echo "mcpu-objcopy unexpectedly accepted a missing output file" >&2 + exit 1 +fi +if "$CPU_OBJCOPY" "$TMP/main" "$TMP/main" >/dev/null 2>&1; then + echo "mcpu-objcopy unexpectedly accepted in-place operation" >&2 + exit 1 +fi + +exit 0 |
