<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/219750>219750</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[PowerPC][AArch64][RISCV] DBG_LABEL underfills stackmap shadows
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
yqtian-se
</td>
</tr>
</table>
<pre>
PowerPC, AArch64, and RISC-V can emit a stackmap patching shadow that is four bytes shorter than requested when a `DBG_LABEL` immediately follows the `STACKMAP` machine instruction.
The three attached LLVM IR modules differ only by one adjacent debug intrinsic. With a 32-byte shadow request, the module containing `llvm.dbg.label` has only 28 encoded bytes from the stackmap address through the end of the basic block on all three targets. The module without the intrinsic has the requested 32 bytes.
The `llvm.dbg.value` variant exposes the other side of the same subtype-dependent scan: `DBG_VALUE` stops trimming, so the backend emits the full NOP budget in addition to the following instructions and overpads the shadow.
This reproduces with LLVM trunk at revision `50d4fbcc610e478190408685f02fe5818779c154` on x86-64 Linux.
## Reproducer
The following four files are attached individually. The LLVM IR files use a final `.txt` suffix only because GitHub does not accept `.ll` uploads:
[reproduce.sh](https://github.com/user-attachments/files/31607283/reproduce.sh)
[with-dbg-label.ll.txt](https://github.com/user-attachments/files/31607286/with-dbg-label.ll.txt)
[with-dbg-value.ll.txt](https://github.com/user-attachments/files/31607285/with-dbg-value.ll.txt)
[without-debug.ll.txt](https://github.com/user-attachments/files/31607284/without-debug.ll.txt)
Run:
```bash
bash reproduce.sh
```
The script defaults to an LLVM build containing all three targets. Separate target builds can be selected with `PPC_LLC`, `AARCH64_LLC`, `RISCV_LLC` and the corresponding `*_OBJDUMP` variables. `LLVM_AS` and `OPT` select the verifier tools when needed.
All three modules are accepted by `llvm-as` and `opt -passes=verify`. Every code-generation invocation also uses `-verify-machineinstrs`.
## Actual behavior
```text
Requested shadow: 32 bytes
powerpc NOPs: without-debug=3 DBG_LABEL=2 DBG_VALUE=8
powerpc bytes: without-debug=32 DBG_LABEL=28 DBG_VALUE=52
aarch64 NOPs: without-debug=6 DBG_LABEL=5 DBG_VALUE=8
aarch64 bytes: without-debug=32 DBG_LABEL=28 DBG_VALUE=40
riscv NOPs: without-debug=7 DBG_LABEL=6 DBG_VALUE=8
riscv bytes: without-debug=32 DBG_LABEL=28 DBG_VALUE=36
```
The byte totals include the ordinary instructions after the NOPs through the end of the basic block: 20 bytes on PowerPC, 8 bytes on AArch64, and 4 bytes on RISC-V. Object disassembly is used for the NOP counts.
Immediately before the target AsmPrinter, `DBG_LABEL` and `DBG_VALUE` are adjacent to `STACKMAP 0, 32`. Removing all debug machine instructions makes the ordinary Machine IR identical among the three variants.
## Cause
The affected implementations are:
- `PPCAsmPrinter::LowerSTACKMAP()`;
- `AArch64AsmPrinter::LowerSTACKMAP()`; and
- `RISCVAsmPrinter::LowerSTACKMAP()`.
Their shadow-trimming loops apply encoded-instruction semantics directly to a mixed list containing zero-width debug instructions. In outline, each loop does this:
```cpp
if (MII == MBB.end() || MII->isCall() ||
MII->getOpcode() == <target>::DBG_VALUE ||
MII->getOpcode() == TargetOpcode::PATCHPOINT ||
MII->getOpcode() == TargetOpcode::STACKMAP)
break;
++MII;
NumNOPBytes -= NOPBytes;
```
`DBG_LABEL` is neither skipped nor a stopping condition, so it consumes one instruction's worth of the requested shadow even though it emits no bytes. `DBG_VALUE` is a stopping condition, so the full NOP budget is emitted instead. Debug subtype therefore changes both the emitted NOP count and final object layout.
As a diagnostic control, skipping every `MII->isDebugInstr()` before applying the stop/count logic makes all three variants match the no-debug layout on all three targets. This control establishes the source of the difference; it is not intended to prescribe the final patch structure.
## Expected behavior
Zero-width debug instructions should not consume bytes or stop this encoded-byte scan. All three variants should provide the requested 32-byte shadow and should have the same ordinary object layout.
`llvm/docs/StackMaps.rst` states that LLVM guarantees the requested instruction shadow following a stackmap's instruction offset. The `DBG_LABEL` result violates that guarantee by ending the basic block after 28 bytes.
## Impact and evidence boundary
The four-byte underfill and the subtype-dependent object layouts are directly confirmed in generated object code. A runtime that destructively patches all 32 requested bytes could consequently write beyond the available shadow in the `DBG_LABEL` variant.
No runtime patching experiment was performed, and this report does not claim a demonstrated runtime failure or exploitability. The `DBG_VALUE` case is conservative overpadding rather than underfilling.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJysWE1v4zjS_jXMpWBDkWzHOeSg2J0Zv2_SMdKZXmAvDYosWZxQpIaknHh__YIfku0k25jZHaCBjiWxvuupp0itFTuFeEPmt2S-vqC9a7S5OfzhBFUTixeV5ocbkpVb_YpmuyL5CsrSsGYx839SxeFp8201-Q6MKsBWOKBgHWUvLe2go441Qu3ANpTrV3ANdSAs1Lo3UB0cWrCNNg6Nf6XA4B89WoccXhtUQIEssvXtLz_uy9sv92SRgWhb5II6lAeotZT61YJr0H_37blc_f9DufWftdSrRRDKOtMzJ7SakqwkWfncILjGIAJ1jrIGOdzff3-AzRO0mvcSLXBR12hAK3mA6gBaIVD-O2WoHHCs-h0I5YxQVrAp_EO4BigU-cS7M_iZ_PAR8tZFycC0clQoHw-yyKTct1Ne7aaSVii91Q21UWu-BFRMc-QpSLXRbZA0RpZybtB6543ud014iYqDrsOfFbWCQSU1ewGtgEqZvHbU7NDZKTwf7XoVrtG9CwdH14I1_skxJ0UezTkJ5akfeyp79H7sqRFUOcC3TluMUrRr0IAVHAcTLW0RbF-5Q4cTjh0q7iNsGVWkKIfMfy_vf_vihVqnOwvOiLYVaucja3Vylb14z33tRV11LyV8fdxC1fMdOhDKh0v4KgAXD8Xa8Zk4KREbylnv0XSUR1Exn6PDwoLBzmjeM7QhbrF6nOnVC1AHBvfCej1kkc0zPqsrxhaXGc6ulpfX2SxbLpbzOstrnC8vl1dX1-xyPvPeaQVvy8VkMYN7ofq3pJDkBckLeBpUmmPgjw6EXqqFr1xqTspaKC72gvdUykNM91Do8ePeIlCohaLSWzt1by7Eua9r8ZaqHxn1n_0i3K99BVyjBaUdUMawc-GUDJXbd1JTbklRJsPnt2OcprYh8zXJl41zXfgkvyP53U64pq-mTLckv-stmkm0vEXlLMnvgpEkvysuF9lVvixIfncmMr-OenwSJrzaTUIbTaUMjvzvChckv_tc9gfNofD_Ps3zU81nsk81695NAhr9fYpnSfEH0VFvVj716pjiRRb_VdQ2JCv9f3CWoZNvjnVrmRGdx9Ga9tL3qwaqYmVWvZD8FCQ_Qa1v2FFD3fAknrFh9lQIFiWyMD18Z5JFtt2uftzfr7wF-co_KMun1a-L2flDP8C-p0cBAnznM20M2k4rnvCa5OWPx9v_W__2sB1BrpJop_6ld-BH-W0QQBbZ4_Y5tFMwKUjcoxG18KNOa2njhFOIHHlq93L0dxhFoaFDs4VRMMDthNoTTbpzMOmotWhJsQ5aDr414csezQH8HJnsUKGhAQGF2msW_6TSao8D1ouZxJOTNDsDLno151hUMtdTCRU2dC-0eVcLDt-cr5NxZET89Hg-DA-SlZ2nEh0Dj9G-WOGs6EixLgCOU79Y5_FnHAXFenkqIsr8TEZ-LmN5LmSek6ykNBCZoyEfpCzOLZl_MGQU8TND3ltyKmTmm8MIy_YAPzHk6lzI4oMho4j_1pBi8XnHBl7jtKPSglBM9hzjRDdcKGoO7yZoHckcBlf-BD3xluZZ4jlawQnPXB6fvqOcs-ObyD6n8Fj97huNC-s7oa3kwRPN3iKHWo8WAdO9cgOD2ZywyQprbaJnCVtK226NUA5NwokzJpqa74yjhHYdqKLTp6wUAtgUeWjMJ2z1fkC4SCk_YawWWvoy0Kch2A_pu80TCM-XBKMSaKvVLpoe4CMRMHveuis_y495pXUdwVK0nUQ_EmhKocER5ScJRU9iUZSkKO99lkbGnS_9iFhkpLgdzqSE_elzPp7D2YDHf-7kkYoKk8BmMnBEkNpTRtp18jDw6clJfMFiS30EPeU3yJw8hHEErXhDDlJYdzqN_oVGT14Fd824BRxTNYWNAt07KRT6RCNlTdAfSZNrhP04OVnXkawUNZB8-bDZACnWpFjDw-3tFBWPPgK5WpGrFTxsNhNSfBF2RaU8e0Wy0rd9-mCH7rHzrg7fRJmkWMWqJsWXGM-xcP-KmOcgI70JYrbl8-rX7ePm6_OJnL8q5JjW62BGZZC-xGIi-S3Jbx82m_jza99-fdzehuafeGHDr_T1OXx92B4tKBRxE3kRXYcclDZhYdVd55PM_Lz3GU0LhgglYPs2gM1Ze5L8ysKrNq4ZUM28G3uAe1TgQXjXeElxQ1E6bVEf4EPYn5ny6WZjg9DQxco6pHwK61CcabHyp0xENtZQtUMLlXYJj9PJERYDpsWFQEc0lfSgezfQE28eF3SntHWChd4wWgbzfDS90RgoB1lkY70GczY-bGPTDlgbOlMk5PJ-k_wuGiL1TrAEf0cWOMAatNSx6IPScbwlS__jrivsYC6gdbSSwjYJWq3uDRu30rj8o2LoQUmEEPuVxyOR8gu509AZ9DS2itMiBizcdEAsjt7gOfJ-eesi1J7Tpn_-DFHANrqXPChPJTgMPROCFUBlxLV4-8ComkL5MWBJVmf0XqTxfbrWn91d-CJI3zd0j8ddfZxBnxVHYqYkv-Oa-Z3im6Ps5YF2dmpsXCwddSHk1EW-v-upocohvr9nOMPoaNRx3T3eLoUGPP1W17VFF3fd961v0PbSwV5oeTRjtMBza4xM__3tSSQ0-fLs6iPlddN2lMW2QR9YxRAq3StOzeF0Ve9NjHCvOJpaSDluGR_vP86CGzeAcToxrWph2hAiSJQe-XDEF8IUSjC9cqLF6CLHFJ-9JzmhSlNPFflJyGNlsZB1X23-hfIqX41wCBUedLKY7qmQfvEZUiPUcAN3FvBUeylgX_Vo1ngniG8dGuGJB7xSCx2aWnvnBpLn0nWLNu549cAkFa3HIWy1T30IwCC6pkL2xleqFy61cLQSUrjDWU2MeMuoRYjIYNHsqQ_ScP0TasHQMCvC1eSYO6F2yakLflPw6-KaXuDN5dVymc2vrvPZRXNT5fS6WmLN83xxPWPXxewyW84vL2teUKwrfiFu8ixfZMsiy_LZPJ9Nl5fVYslzVmBdz-rFjMwybKmQ03C7ps3uQljb401-eX01zy7CfYQNd7Z5rvAVwluS52S-vjA3YUes-p0ls8zTGHsU44ST4bJ34NnzNZnfDvQ6_Aj0i8zXx2Xh6Lw93kDG9NuL3sibn1w7JFQIJnVG-0ol-V2w18NEcmh_k_87AAD__80wcro">