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

Reply via email to