| Issue |
185356
|
| Summary |
[MC][ARM] Clang silently accepts ARM Thumb2 `hvc` on CPUs lacking Virtualization Extension
|
| Labels |
clang
|
| Assignees |
|
| Reporter |
venkyqz
|
## Summary
`llvm-mc` silently assembles the ARM Thumb2 `hvc` mnemonic on CPUs that do not support the Virtualization Extension (e.g., Cortex-A9), despite the canonical `.w`-suffix form correctly rejecting it. The encoded bytes disassemble as `<unknown>` on the same CPU. This is a **parser feature-gate bypass** — the assembler and disassembler disagree on what the CPU can execute.
---
## Reproduction
**Godbolt Link**
+ https://godbolt.org/z/654a5M3M8
**Test File (`poc.s`):**
```asm
.syntax unified
.thumb
.text
hvc 3
```
**Commands:**
```bash
# hvc.w is CORRECTLY rejected for cortex-a9:
echo -e ".syntax unified\n.thumb\n.text\nhvc.w 3" | llvm-mc - \
--arch=arm --triple=armv7-linux-gnueabihf --mcpu=cortex-a9 --filetype=asm
# → error: instruction requires: virtualization-extensions
# hvc (alias, without .w) is SILENTLY ACCEPTED — BUG:
echo -e ".syntax unified\n.thumb\n.text\nhvc 3" | llvm-mc - \
--arch=arm --triple=armv7-linux-gnueabihf --mcpu=cortex-a9 --filetype=obj -o hvc.o
# → exit 0, emits bytes
# The encoded bytes are unrecognizable:
llvm-objdump -d --arch=arm --triple=armv7-linux-gnueabihf --mcpu=cortex-a9 hvc.o
# → 0: f7e0 8003 <unknown>
# Contrast — cortex-a15 (has Virtualization Extension) works correctly:
echo -e ".syntax unified\n.thumb\n.text\nhvc 3" | llvm-mc - \
--arch=arm --triple=armv7-linux-gnueabihf --mcpu=cortex-a15 --filetype=obj -o hvc_a15.o
llvm-objdump -d --arch=arm --triple=armv7-linux-gnueabihf --mcpu=cortex-a15 hvc_a15.o
# → 0: f7e0 8003 hvc.w #0x3
```
---
## Root Cause
In `ARMInstrThumb2.td`, the canonical `hvc.w` instruction has the correct feature guard:
```tablegen
def t2HVC : T2XI <...>,
Requires<[IsThumb2, HasVirtualization]>, ... { ... }
```
But the alias for the short form is **missing** the `Requires` predicate:
```tablegen
// BUG: no Requires<[IsThumb2, HasVirtualization]>
def : t2InstAlias<"hvc\t$imm16", (t2HVC imm0_65535:$imm16)>;
```
The AsmMatcher selects this alias regardless of CPU feature flags, then expands it to `t2HVC` and encodes HVC bytes.
---
## Impact
| Build Type | Behavior | Severity |
|------------|----------|----------|
| Debug | Silent acceptance (Exit 0) | Medium |
| Release | Silent acceptance (Exit 0) | Medium |
**Affected Variants:**
| Assembly Input | CPU | Exit | Disasm Result |
| -------------- | ---------- | ------------ | ------------- |
| `hvc 3` | cortex-a9 | 0 | `<unknown>` |
| `hvc.w 3` | cortex-a9 | 1 (rejected) | — |
| `hvc 3` | cortex-a15 | 0 | `hvc.w #0x3` |
**Impact:**
- Silently encodes a privileged instruction that the CPU cannot execute
- At runtime: CPU without VE support will trap or execute as undefined instruction
- Affected CPUs: Cortex-A5, A7, A8, A9, A15-without-VE
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs