-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
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
| case eEncodingUint: |
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.