Skip to content

Commit 9cb120c

Browse files
committed
ci: assert that an optional interface is referenced weakly
The defect fixed in 0.3.5 shipped, and nothing in this repository saw it. A strong reference to `kal_random_fill` in the dispatcher made an optional interface mandatory, and it was found one repository downstream, by a bare-metal program in openkal-llvm-runtime linking over openkal-opensbi: ld.lld: error: undefined symbol: kal_random_fill Reproducing that here would need a bare-metal toolchain and a backend that declines the interface. The symbol class needs neither and states the invariant more directly than a link would. ⭐ The check carries its own control. Asserting only that `kal_random_fill` is weak would pass just as well if the symbol had vanished or the object had not been built, so a required interface beside it must still be an undefined strong reference — that is what makes a backend failing to provide one a link error rather than a silently missing call. Measured on the object from a bare-metal build, both ways: with the weak declaration w kal_random_fill U kal_time_sleep → ok with it removed U kal_random_fill U kal_time_sleep → red
1 parent cdf550a commit 9cb120c

1 file changed

Lines changed: 39 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,45 @@ jobs:
8888
[ -n '${{ matrix.target }}' ] && extra='--target ${{ matrix.target }}'
8989
mcpp build $extra
9090
91+
# ⭐ AN OPTIONAL INTERFACE IS REFERENCED WEAKLY, WHICH IS A PROPERTY OF
92+
# THE OBJECT AND NOT OF ANY ONE LINK.
93+
#
94+
# `openkal.random` is optional, and clause 6.1 expresses an
95+
# implementation that does not provide it as the absence of a link-time
96+
# definition. This dispatcher is linked into every program, so a strong
97+
# reference to `kal_random_fill` makes an optional interface mandatory:
98+
# every program over a backend without it fails to link, whether or not
99+
# it wanted a random byte.
100+
#
101+
# ⚠️ THAT DEFECT SHIPPED, AND NOTHING HERE SAW IT. It was found one
102+
# repository downstream, by a bare-metal program in openkal-llvm-runtime
103+
# linking over openkal-opensbi:
104+
#
105+
# ld.lld: error: undefined symbol: kal_random_fill
106+
#
107+
# Reproducing it here would need a bare-metal toolchain and a backend
108+
# that declines the interface. The symbol class needs neither, and states
109+
# the invariant more directly than a link would: `w` for the optional
110+
# one, `U` for a required one beside it.
111+
- name: An optional interface is referenced weakly
112+
if: runner.os == 'Linux'
113+
run: |
114+
obj="$(find target -name okm_syscall.o | head -1)"
115+
test -n "$obj" || { echo "::error::okm_syscall.o was not built"; exit 1; }
116+
nm="$(command -v llvm-nm || command -v nm)"
117+
"$nm" "$obj" > syms.txt
118+
119+
# The control: a required interface must still be a strong reference,
120+
# so that a backend failing to provide one is still a link error.
121+
grep -qE '^ *U kal_time_sleep$' syms.txt \
122+
|| { echo "::error::kal_time_sleep is not an undefined strong reference — the check below proves nothing"
123+
grep kal_time syms.txt; exit 1; }
124+
125+
grep -qE '^ *w kal_random_fill$' syms.txt \
126+
|| { echo "::error::kal_random_fill is not a weak reference; an optional interface has been made mandatory"
127+
grep kal_random syms.txt; exit 1; }
128+
echo " ok kal_random_fill is weak, kal_time_sleep is strong"
129+
91130
# A program above this package names one package. It does not name
92131
# openkal, it does not name an implementation, and it says nothing about
93132
# the platform.

0 commit comments

Comments
 (0)