| Issue |
87471
|
| Summary |
lldb does not support "<vector>" and "<union>" when describing registers
|
| Labels |
lldb
|
| Assignees |
|
| Reporter |
DavidSpickett
|
This was reported to me by someone trying to debug SVE and SME code that switched streaming modes, using qemu-user. When in streaming mode they could not read the Z registers but they could in non-streaming mode. Qemu was returning valid data each time but lldb refused to display it in streaming mode.
The cause is a difference in how lldb-server and qemu describe the type of these registers. lldb-server describes them as:
```
<reg name="z31" bitsize="256" regnum="193" encoding="vector" format="vector-uint8" group="Scalable Vector Extension Registers" ehframe_regnum="127" dwarf_regnum="127" />
```
And this gets converted to `eEncodingVector`. We can see that lldb-server sets that in the source:
```
// Defines a Z vector register with 16-byte default size
#define DEFINE_ZREG(reg) \
{ \
#reg, nullptr, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, \
SVE_REG_KIND(reg), nullptr, nullptr, nullptr, \
}
```
This format lets us handle any amount of elements in the vector. So if you increase the vector length, no problem.
qemu on the other hand uses `<vector>` and `<union>` (see https://sourceware.org/gdb/current/onlinedocs/gdb.html/Target-Description-Format.html):
```
<vector id="svevqu" type="uint128" count="16"/>
<...>
</union><union id="svev">
<field name="q" type="svevnq"/>
<field name="d" type="svevnd"/>
<field name="s" type="svevns"/>
<field name="h" type="svevnh"/>
<field name="b" type="svevnb"/>
</union>
<reg name="z0" bitsize="2048" regnum="34" type="svev"/>
```
lldb doesn't recognise the type `svev` and so defaults to unsigned int. That goes through https://github.com/llvm/llvm-project/blob/e05c1b46d0d3739cc48ad912dbe6e9affce05927/lldb/source/Utility/RegisterValue.cpp#L189 which only supports up to 128 bit numbers. So you can read the Z registers if the vector length is less than 128 bits (vg = 2) but as soon as it goes beyond that, lldb rejects the data.
The example I was given used streaming mode and set qemu's SVE/SME default vector lengths like:
```
-cpu max,sve-default-vector-length=16,sme-default-vector-length=64
```
But you can also reproduce by writing vg from within lldb `register write vg 4`.
We could add some arbitrary sized integer support (`Scalar` already stores the value using `APSInt` and `APFloat`). This would be the quick fix.
Long term we should support `<vector>` and `<union>` as they do have some advantages. `<union>` causes the debugger to display the vector in multiple ways, which can be useful for SVE where you don't know what type is in the register at a given point.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs