#!/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 lookup to use lib.a' exit 0