fix(asm): reject the operand-starved riscv64 spellings instead of panicking
Assisted-by: GLM 5.3
This commit is contained in:
1 parent
d03de62c07
commit
acd30088af
3 files changed
+17
-2
No files matched your search
@@ -232,6 +232,11 @@ func FuzzAssembleRISCV64(f *testing.F) {
|
|||||||
f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tCSRRW $0x1000, X5, X6\n\tRET\n")
|
f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tCSRRW $0x1000, X5, X6\n\tRET\n")
|
||||||
f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tSLLI $64, X5, X6\n\tRET\n")
|
f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tSLLI $64, X5, X6\n\tRET\n")
|
||||||
f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tVLE8V (X10), V32\n\tRET\n")
|
f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tVLE8V (X10), V32\n\tRET\n")
|
||||||
|
// Operand-starved spellings that used to panic the layout and encode
|
||||||
|
// passes; each must come back as a diagnostic.
|
||||||
|
f.Add("TEXT ·f(SB), $0\n\tJALR\n\tRET\n")
|
||||||
|
f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tROR $3\n\tRET\n")
|
||||||
|
f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tVLE8V (X10)\n\tRET\n")
|
||||||
f.Add("#define A A\nA\n")
|
f.Add("#define A A\nA\n")
|
||||||
|
|
||||||
f.Fuzz(func(t *testing.T, src string) {
|
f.Fuzz(func(t *testing.T, src string) {
|
||||||
|
|||||||
@@ -570,6 +570,11 @@ func riscvRevShiftSize(mnem string, ops []*ast.Operand) int {
|
|||||||
if mnem != "ROR" && mnem != "RORI" {
|
if mnem != "ROR" && mnem != "RORI" {
|
||||||
return 4 // SLLIW has no compressed form
|
return 4 // SLLIW has no compressed form
|
||||||
}
|
}
|
||||||
|
if len(ops) < 2 {
|
||||||
|
// A malformed one-operand form: encoding rejects it with a
|
||||||
|
// diagnostic, and the layout pass only needs a word count.
|
||||||
|
return 4
|
||||||
|
}
|
||||||
imm := int(immFromOperand(ops[0]))
|
imm := int(immFromOperand(ops[0]))
|
||||||
rs1 := regFromOperand(ops[1])
|
rs1 := regFromOperand(ops[1])
|
||||||
rd := rs1
|
rd := rs1
|
||||||
@@ -4830,6 +4835,9 @@ func encodeRISCVVecLS(mnem string, ops []*ast.Operand) ([]byte, bool, error) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, true, fmt.Errorf("unsupported vector load/store %q", mnem)
|
return nil, true, fmt.Errorf("unsupported vector load/store %q", mnem)
|
||||||
}
|
}
|
||||||
|
if len(ops) < 2 {
|
||||||
|
return nil, true, fmt.Errorf("%s expects at least 2 operands, got %d", mnem, len(ops))
|
||||||
|
}
|
||||||
op := uint32(0x27)
|
op := uint32(0x27)
|
||||||
if v.load {
|
if v.load {
|
||||||
op = 0x07
|
op = 0x07
|
||||||
|
|||||||
+4
-2
@@ -96,8 +96,10 @@ func riscvIsLeaf(t *ast.Text) bool {
|
|||||||
case "JALR":
|
case "JALR":
|
||||||
// JALR rd, offset(rs1) links when the destination register (the
|
// JALR rd, offset(rs1) links when the destination register (the
|
||||||
// first operand) is X1; JALR rs1, rd links when the second
|
// first operand) is X1; JALR rs1, rd links when the second
|
||||||
// register is X1; JALR offset(rs1) always links to X1.
|
// register is X1; JALR offset(rs1) always links to X1. A bare
|
||||||
if len(in.Operands) == 1 {
|
// operand-less spelling is malformed and encoding rejects it;
|
||||||
|
// conservatively count it as a link so the frame stays honest.
|
||||||
|
if len(in.Operands) <= 1 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if isMemOperand(in.Operands[1]) {
|
if isMemOperand(in.Operands[1]) {
|
||||||
|
|||||||
Reference in new issue
Block a user