-
Notifications
You must be signed in to change notification settings - Fork 14.8k
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.