fix(arm64): reject bare BTI with a diagnostic and accept the full family

Assisted-by: GLM 5.3 Flash
This commit is contained in:
2026-09-20 19:15:05 +02:00
parent 6556b85abf
commit 241e7256f6
2 changed files with 37 additions and 1 deletions
+7 -1
View File
@@ -2856,8 +2856,14 @@ func encodeARM64Sys(mnem string, ops []*ast.Operand) ([]byte, error) {
} }
return a64wordLE(0xd503201f | uint32(v)<<5), nil return a64wordLE(0xd503201f | uint32(v)<<5), nil
case "BTI": case "BTI":
// The toolchain requires the landing-pad kind: bare BTI is
// rejected ("missing operand"), and only the uppercase C/J/JC
// spellings assemble (0xd503245f/49f/4df).
if len(ops) != 1 {
return nil, fmt.Errorf("%s expects C, J, or JC", mnem)
}
op := operandRegName(ops[0]) op := operandRegName(ops[0])
base, ok := map[string]uint32{"C": 0xd503245f}[op] base, ok := map[string]uint32{"C": 0xd503245f, "J": 0xd503249f, "JC": 0xd50324df}[op]
if !ok { if !ok {
return nil, fmt.Errorf("%s: unknown kind %q", mnem, op) return nil, fmt.Errorf("%s: unknown kind %q", mnem, op)
} }
+30
View File
@@ -675,6 +675,36 @@ func TestArm64AcquireRelease(t *testing.T) {
} }
} }
// TestArm64BTI pins the landing-pad family against the toolchain words:
// only the uppercase C/J/JC spellings assemble, and bare BTI is a
// diagnostic, never a panic.
func TestArm64BTI(t *testing.T) {
got := arm64Words(t, "\tBTI C\n\tBTI J\n\tBTI JC\n")
want := []uint32{
0xd503245f, // BTI C
0xd503249f, // BTI J
0xd50324df, // BTI JC
0xd65f03c0, // RET
}
if len(got) != len(want) {
t.Fatalf("got %d words, want %d", len(got), len(want))
}
for i := range want {
if got[i] != want[i] {
t.Errorf("word %d = %#x, want %#x", i, got[i], want[i])
}
}
for _, src := range []string{"\tBTI\n", "\tBTI c\n", "\tBTI B\n"} {
f, errs := parser.Parse("test_arm64.s", "#include \"textflag.h\"\n\nTEXT ·f(SB), NOSPLIT, $0-0\n"+src+"\tRET\n")
if len(errs) > 0 {
continue
}
if _, err := AssembleFileARM64(f); err == nil {
t.Errorf("BTI spelling %q should be rejected, as go tool asm rejects it", src)
}
}
}
// TestArm64System pins BRK, SVC, the barriers, cache maintenance and the // TestArm64System pins BRK, SVC, the barriers, cache maintenance and the
// system register accesses. // system register accesses.
func TestArm64System(t *testing.T) { func TestArm64System(t *testing.T) {