Files
MeowOS-For-R3P2/patch_v2/sdk/test_time32_abi.sh
T
AskaEth 7a32b0690e fix(m43): r1 评审 P2 — 语义断言入仓 + audiod 表述对齐产物
- test_time32_abi.sh 增加 16 字节 time64 布局断言:4263 后必须写 tv_sec 0x0/0x4
  (含 sra 符号扩展)+ tv_nsec 0x8;支持「内联」与「调用后转换」两种编译形态。
  自证:amsd 出货件 FAIL、修复后 amsd PASS、不加修复重编 sysui FAIL。
- build_audiod.sh / fw_content.conf:41 的 audiod 例外说明改为:「出货件是旧工具链
  静态 musl,4403→ENOSYS→4263+宽度转换本身健康;glibc-2.22 目标同样无 ABI 错位」,
  不再单称 glibc-dynamic。
2026-11-11 18:51:16 +08:00

124 lines
5.4 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# test_time32_abi.sh — 反汇编断言:mipsel 二进制必须走 o32 time32 取时(4263),
# 不得残留 time64 入口(4403)。这是宿主 fallback 单测无法覆盖的「真机取时路径」证据。
#
# 用法(任意目录):
# bash patch_v2/sdk/test_time32_abi.sh patch_v2/meow_watchdog/meow_watchdog
# bash patch_v2/sdk/test_time32_abi.sh patch_v2/meow_watchdog/meow_watchdog patch_v2/meow_launcherd/meow_launcherd
# 可用 OBJDUMP=<path> 指定 objdump(默认 llvm-objdump)。
#
# 期望:每个二进制同时满足三条——
# 1) 4263(SYS_clock_gettime time32)出现 ≥1 次;
# 2) 4403(SYS_clock_gettime64)出现 0 次;
# 3) 4263 之后必须把结果按 16 字节 time64 布局写回:tv_sec 写 0x0/0x4(含 sra ...0x1f
# 符号扩展)、tv_nsec 写 0x8。
# 第 3 条是必需的:zig 0.17 的「缺陷版」与 meow_time32 的「修复版」都呈 4263-only,
# 只看 1/2 区分不了。缺陷版把 4263 的 a1 直接指向调用方 8 字节缓冲、无宽度转换;修复版
# 才写 0x0/0x4/0x8。已知样本:amsd 出货件(缺陷)FAIL、修复后 amsd PASS、当前 zig 不加
# meow_time32.c 重编的 sysui FAIL。
set -u
OD="${OBJDUMP:-llvm-objdump}"
command -v "$OD" >/dev/null 2>&1 || { echo "缺少 objdump: $OD(可用 OBJDUMP=... 覆盖)" >&2; exit 2; }
[ "$#" -gt 0 ] || { echo "用法: $0 <mipsel-binary> [...]" >&2; exit 2; }
# 语义断言(两条路径,覆盖内联与非内联两种编译形态):
# A. 4263 指令所在窗口内出现同一基址寄存器的 0x0/0x4/0x8 存储 + sra 符号扩展(内联形态);
# B. 若 A 不成立,定位 4263 所在函数(最近的 jal 目标),检查其直接调用者在 jal 之后是否
# 做同样的 0x0/0x4/0x8 写回(meow_ui_time.c 那种「调用 time32 取时再转换」的形态)。
# 缺陷版两条都不成立:4263 的 a1 直达调用方 8 字节缓冲、无宽度转换。
sem_awk='
function hex2num(h, i, n, c) {
n = 0; h = tolower(h)
for (i = 1; i <= length(h); i++) {
c = index("0123456789abcdef", substr(h, i, 1)) - 1
if (c < 0) return -1
n = n * 16 + c
}
return n
}
function window_has_16b(from, to, j, l, frag, f, off, r, has_sra, seen, k, a) {
delete seen
has_sra = 0
for (j = from; j <= to && j <= NR; j++) {
l = line[j]
if (l ~ /sra[ \t]+\$[0-9a-z]+,[ \t]*\$[0-9a-z]+,[ \t]*0x1f/) has_sra = 1
if (l ~ /(^|[ \t])sw[ \t]+\$[0-9a-z]+,[ \t]*0x[048]\(\$[0-9a-z]+\)/) {
frag = l
if (match(frag, /0x[048]\(\$[0-9a-z]+\)/)) {
f = substr(frag, RSTART, RLENGTH)
off = substr(f, 3, 1)
r = f; sub(/.*\(\$/, "", r); sub(/\).*/, "", r)
seen[off SUBSEP r] = 1
}
}
}
if (!has_sra) return 0
for (k in seen) {
split(k, a, SUBSEP)
if (a[1] == "0" && (("4" SUBSEP a[2]) in seen) && (("8" SUBSEP a[2]) in seen)) return 1
}
return 0
}
{ line[NR] = $0 }
END {
ng = 0; nj = 0
for (i = 1; i <= NR; i++) {
if (!match(line[i], /^[ \t]*[0-9a-f]+:/)) continue
h = substr(line[i], RSTART, RLENGTH); sub(/:$/, "", h); gsub(/[ \t]/, "", h)
addr[i] = hex2num(h)
if (line[i] ~ /addiu[ \t]+\$[0-9a-z]+,[ \t]*\$zero,[ \t]*0x10a7/) { ng++; gt[ng] = i }
if (match(line[i], /jal[ \t]+0x[0-9a-f]+/)) {
s = substr(line[i], RSTART, RLENGTH); sub(/.*0x/, "", s)
nj++; jfrom[nj] = i; jto[nj] = hex2num(s)
}
}
for (g = 1; g <= ng; g++) {
i = gt[g]
if (window_has_16b(i + 1, i + 70)) exit 0
}
for (g = 1; g <= ng; g++) {
a = addr[gt[g]]
best = -1
for (j = 1; j <= nj; j++) {
t = jto[j]
if (t <= a && a - t <= 1024 && t > best) best = t
}
if (best < 0) continue
for (j = 1; j <= nj; j++) {
if (jto[j] != best) continue
if (window_has_16b(jfrom[j] + 1, jfrom[j] + 60)) exit 0
}
}
exit 1
}
'
fail=0
for bin in "$@"; do
[ -f "$bin" ] || { echo "FAIL 文件不存在: $bin"; fail=1; continue; }
dis="$("$OD" -d --triple=mipsel "$bin" 2>/dev/null)" || {
echo "FAIL objdump 失败: $bin"; fail=1; continue;
}
# 只匹配「把系统调用号装进 a0」的指令,不能裸 grep 0x1133:分支/跳转目标的
# 十六进制偏移(如 <.text+0x11338>)也含该子串,会把已修好的二进制误判为残留 4403。
n_time32=$(printf '%s\n' "$dis" | grep -cE 'addiu[[:space:]]+\$[0-9a-z]+,[[:space:]]*\$zero,[[:space:]]*0x10a7' || true)
n_time64=$(printf '%s\n' "$dis" | grep -cE 'addiu[[:space:]]+\$[0-9a-z]+,[[:space:]]*\$zero,[[:space:]]*0x1133' || true)
sem=FAIL
if printf '%s\n' "$dis" | awk "$sem_awk"; then sem=OK; fi
printf '%-52s 4263=%-2s 4403=%-2s 16B-layout=%s\n' \
"$bin" "$n_time32" "$n_time64" "$sem"
if [ "$n_time32" -lt 1 ]; then
echo "FAIL $bin: 未找到 4263(o32 time32)取时路径"; fail=1
fi
if [ "$n_time64" -ne 0 ]; then
echo "FAIL $bin: 发现 4403(time64)路径(应有 0 处)"; fail=1
fi
if [ "$sem" != "OK" ]; then
echo "FAIL $bin: 4263 后无 16 字节 time64 写回(0x0/0x4/0x8)——疑似直接写调用方 8 字节/无宽度转换"; fail=1
fi
done
[ "$fail" -eq 0 ] && echo "ALL PASS" || echo "SOME TESTS FAILED"
exit "$fail"