RISC-V miscompilation: Clang misaligns kprobe test arrays or omits labels, causing Linux kernel KUnit failures (GNU as works)
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
## **Summary (Miscompilation)**
This is a miscompilation issue:
> *The compiler successfully produces an executable Linux kernel Image, but the kernel does not run correctly.*
When compiling the Linux RISC-V kernel with Clang, the kernel boots but crashes during KUnit kprobes selftests due to corrupted data in `test_kprobes_addresses[]` and `test_kprobes_functions[]`. The same kernel built with GCC does not exhibit the issue.
I suspect this is caused by Clang misaligning `.rodata` arrays or failing to emit local labels that are referenced later as symbols.
## **Environment**
* **Clang version used:**
[https://github.com/llvm/llvm-project/releases/download/llvmorg-21.1.5/LLVM-21.1.5-Linux-X64.tar.xz](https://github.com/llvm/llvm-project/releases/download/llvmorg-21.1.5/LLVM-21.1.5-Linux-X64.tar.xz)
* **Linux kernel version:**
[https://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git/snapshot/linux-riscv-for-linus-6.18-rc6.tar.gz](https://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git/snapshot/linux-riscv-for-linus-6.18-rc6.tar.gz)
* **Target:** `riscv64`
## **Observed Behavior**
The kernel builds successfully with Clang, producing a valid `Image`.
However, when booted under QEMU, it fails during initialization of the RISC-V KUnit kprobes tests:
Log:
[https://github.com/j1akai/temp/blob/main/20251113/report0.log](https://github.com/j1akai/temp/blob/main/20251113/report0.log)
The root cause appears to be that the linker-visible arrays:
* `test_kprobes_addresses[]`
* `test_kprobes_functions[]`
defined in:
```
arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S
```
are corrupted when assembled with Clang, but correct when assembled with `riscv64-linux-gnu-as`.
This eventually leads to:
```
num_kprobe is overestimated
kcalloc() attempts to allocate an excessively large block
allocation fails -> KUnit fails
```
## **Analysis**
Details:
[https://github.com/j1akai/temp/blob/main/20251113/readme.md](https://github.com/j1akai/temp/blob/main/20251113/readme.md)
Summary of findings:
### **1. Clang does not emit local labels unless explicitly marked `.globl`**
`test_kprobes_add_addr1:` and similar labels inside functions do not appear as symbols unless manually marked `.globl`.
GNU as *does* emit these labels, so `RISCV_PTR label` produces valid addresses.
With Clang, many entries in `test_kprobes_addresses[]` become:
* `0x0000000000000000`
* uninitialized memory
* garbage values
This corrupts the array.
---
### **2. Clang aligns and places `.rodata` differently**
Even with identical assembly:
```asm
.section .rodata
RISCV_PTR test_kprobes_add_addr1
RISCV_PTR test_kprobes_add_addr2
...
```
GNU as guarantees:
* 8-byte alignment for pointer arrays
* placement in `.rodata`
Clang sometimes:
* does not align the array at 8 bytes unless `.align 3` is added
* places it in `.data` if attributes are missing
* produces a larger-than-expected section that confuses the kernel logic
This causes:
```
test_kprobes_addresses[] appears larger than it actually is
while (test_kprobes_addresses[num_kprobe]) runs past the end
leading to invalid memory accesses
```
## **Linux community discussion**
I reported this issue to the Linux RISC-V community; the maintainers recommended seeking the LLVM community's opinion on this behavior so they can decide whether to accept a workaround in the kernel. See the Linux discussion:
* [https://lists.infradead.org/pipermail/linux-riscv/2025-November/080819.html](https://lists.infradead.org/pipermail/linux-riscv/2025-November/080819.html)
* [https://lists.infradead.org/pipermail/linux-riscv/2025-November/080950.html](https://lists.infradead.org/pipermail/linux-riscv/2025-November/080950.html)
Thank you for taking the time to read this issue.
Contributor guide
Research direction
Start with arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S and compare its Clang and riscv64-linux-gnu-as output for test_kprobes_addresses[] and test_kprobes_functions[]. Read the linked report log and analysis, then reproduce under QEMU with the stated Clang, Linux, and riscv64 versions. Done means establishing whether label emission or section alignment causes the KUnit failure and identifying the appropriate LLVM behavior or kernel workaround.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- linux
- Domain
- compilers, operating-systems, testing
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100