summaryrefslogtreecommitdiff
path: root/tests/tst-ar-runner.sh
blob: ffc939a23e9de56df374b708023763349cdb0552 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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