Skip to content

Conversation

@yonghong-song
Copy link
Contributor

Jonathan Cottrill reported a crash in [1] with the following command line:

 $ echo 'r0 = atomic_fetch_add((u64*)(r2 + 0), r1)' | llvm-mc --arch bpf --filetype null 

Note that in the above command, the insn specification requires that r0 and r1 must be the same register. Otherwise, the crash will happen.

Let us add a case Match_InvalidTiedOperand to handle such invalid insns. With this patch, the error message looks like below:

 <stdin>:1:39: error: operand is not the same as the dst register r0 = atomic_fetch_add((u64*)(r2 + 0), r1) ^ 

The error message is much better than the crash. Some other insns are also covered by this patch.

 $ echo 'w0 = xchg32_32(r2 + 0, w1)' | llvm-mc --arch bpf --filetype null <stdin>:1:24: error: operand is not the same as the dst register w0 = xchg32_32(r2 + 0, w1) ^ 

[1] #145180

Jonathan Cottrill reported a crash in [1] with the following command line: $ echo 'r0 = atomic_fetch_add((u64*)(r2 + 0), r1)' | llvm-mc --arch bpf --filetype null Note that in the above command, the insn specification requires that r0 and r1 must be the same register. Otherwise, the crash will happen. Let us add a case Match_InvalidTiedOperand to handle such invalid insns. With this patch, the error message looks like below: <stdin>:1:39: error: operand is not the same as the dst register r0 = atomic_fetch_add((u64*)(r2 + 0), r1) ^ The error message is much better than the crash. Some other insns are also covered by this patch. $ echo 'w0 = xchg32_32(r2 + 0, w1)' | llvm-mc --arch bpf --filetype null <stdin>:1:24: error: operand is not the same as the dst register w0 = xchg32_32(r2 + 0, w1) ^ [1] llvm#145180
@yonghong-song yonghong-song requested a review from eddyz87 July 2, 2025 21:01
@llvmbot llvmbot added the llvm:mc Machine (object) code label Jul 2, 2025
@yonghong-song yonghong-song requested a review from 4ast July 2, 2025 21:01
@llvmbot
Copy link
Member

llvmbot commented Jul 2, 2025

@llvm/pr-subscribers-mc

Author: None (yonghong-song)

Changes

Jonathan Cottrill reported a crash in [1] with the following command line:

 $ echo 'r0 = atomic_fetch_add((u64*)(r2 + 0), r1)' | llvm-mc --arch bpf --filetype null 

Note that in the above command, the insn specification requires that r0 and r1 must be the same register. Otherwise, the crash will happen.

Let us add a case Match_InvalidTiedOperand to handle such invalid insns. With this patch, the error message looks like below:

 &lt;stdin&gt;:1:39: error: operand is not the same as the dst register r0 = atomic_fetch_add((u64*)(r2 + 0), r1) ^ 

The error message is much better than the crash. Some other insns are also covered by this patch.

 $ echo 'w0 = xchg32_32(r2 + 0, w1)' | llvm-mc --arch bpf --filetype null &lt;stdin&gt;:1:24: error: operand is not the same as the dst register w0 = xchg32_32(r2 + 0, w1) ^ 

[1] #145180


Full diff: https://github.com/llvm/llvm-project/pull/146778.diff

2 Files Affected:

  • (modified) llvm/lib/Target/BPF/AsmParser/BPFAsmParser.cpp (+3)
  • (added) llvm/test/MC/BPF/bad-tied.s (+12)
diff --git a/llvm/lib/Target/BPF/AsmParser/BPFAsmParser.cpp b/llvm/lib/Target/BPF/AsmParser/BPFAsmParser.cpp index 88c92da8e95b4..a347794a9a30c 100644 --- a/llvm/lib/Target/BPF/AsmParser/BPFAsmParser.cpp +++ b/llvm/lib/Target/BPF/AsmParser/BPFAsmParser.cpp @@ -348,6 +348,9 @@ bool BPFAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidSImm16: return Error(Operands[ErrorInfo]->getStartLoc(), "operand is not a 16-bit signed integer"); + case Match_InvalidTiedOperand: + return Error(Operands[ErrorInfo]->getStartLoc(), + "operand is not the same as the dst register"); } llvm_unreachable("Unknown match type detected!"); diff --git a/llvm/test/MC/BPF/bad-tied.s b/llvm/test/MC/BPF/bad-tied.s new file mode 100644 index 0000000000000..9cd47896c3dd2 --- /dev/null +++ b/llvm/test/MC/BPF/bad-tied.s @@ -0,0 +1,12 @@ +# RUN: not llvm-mc -mcpu=v4 -triple bpfel < %s 2>&1 \ +# RUN: | grep 'error: operand is not the same as the dst register' \ +# RUN: | count 9 + r0 = bswap16 r1 + r0 = bswap32 r1 + r0 = bswap64 r1 + r0 = atomic_fetch_add((u64*)(r2 + 0), r1) + r0 = atomic_fetch_and((u64*)(r2 + 0), r1) + r0 = atomic_fetch_or((u64*)(r2 + 0), r1) + r0 = atomic_fetch_xor((u64*)(r2 + 0), r1) + w0 = xchg32_32(r2 + 0, w1) + r0 = xchg_64(r2 + 0, r1) 
Copy link
Contributor

@eddyz87 eddyz87 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also Match_NearMisses not covered in the switch statement, but it can't be generated by BPFAsmParser, as it has to be enabled in td file via flag bit ReportMultipleNearMisses.

So, with this change all possible Match_* errors are covered.

@yonghong-song yonghong-song merged commit 13fddea into llvm:main Jul 3, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

llvm:mc Machine (object) code

3 participants