[Lldb-commits] [PATCH] D77047: AArch64 SVE register infos and core file support
Muhammad Omair Javaid via Phabricator via lldb-commits
lldb-commits at lists.llvm.org
Thu Jul 16 04:42:56 PDT 2020
omjavaid marked 9 inline comments as done.
omjavaid added inline comments.
================
Comment at: lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp:289
+
+ lldb_private::RegisterInfo *new_reg_info_p = reg_info_ref.data();
+
----------------
labath wrote:
> I think all uses of `new_reg_info_p` could just be replaced by `reg_info_ref`
Ack.
================
Comment at: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp:63-66
+ m_sve_note_payload.resize(m_sveregset.GetByteSize());
+ ::memcpy(GetSVEBuffer(), m_sveregset.GetDataStart(),
+ m_sveregset.GetByteSize());
+ ::memcpy(&m_sve_header, m_sveregset.GetDataStart(), sizeof(m_sve_header));
----------------
labath wrote:
> What's up with this copying? We already have the data in the `m_sveregset` DataExtractor. What's the reason for copying it into the `m_sve_note_payload` vector? Also, `m_sve_header` seems like it could just be a `reinterpret_cast`ed pointer into that buffer instead of a copy. (Maybe not even a pointer, just a utility function which performs the cast when called).
>
> Actually, when I think about casts and data extractors, I am reminded of endianness. This will access those fields using host endianness, which is most likely not what we want to do. So, probably the best/simplest solution would be to indeed declare a `user_sve_header` struct, but don't populate it via memcpy, but rather via the appropriate DataExtractor extraction methods. Since the only field of the user_sve_header used outside this function is the `vl` field, perhaps the struct could be a local variable and only the vector length would be persisted. That would be consistent with how the `flags` field is decoded and stored into the `m_sve_state` field.
>
> (If the struct fields are always little-endian (if that's true, I thought arm has BE variants) then you could also stick to the `reinterpret_cast` idea, but change the types of the struct fields to `llvm::support::ulittleXX_t` to read them as LE independently of the host.)
Agreed m_sve_note_payload is redundant. Most of the implementation was mirrored from ptrace implementation and I was lazy enough and did not remove the redundancies which are not needed in case of core dump.
About endianess of SVE data I dont think it will create any problem as the data is transferred in endian invariant format. According to the standard here:
* Whenever SVE scalable register values (Zn, Pn, FFR) are exchanged in memory
between userspace and the kernel, the register value is encoded in memory in
an endianness-invariant layout, with bits [(8 * i + 7) : (8 * i)] encoded at
byte offset i from the start of the memory representation. This affects for
example the signal frame (struct sve_context) and ptrace interface
(struct user_sve_header) and associated data.
================
Comment at: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp:84-86
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg == LLDB_INVALID_REGNUM)
+ return false;
----------------
labath wrote:
> This is already checked by ReadRegister and the false -> uint32_t conversion is dodgy. An assertion would completely suffice here.
Ack.
================
Comment at: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp:140
+ offset -= GetGPRSize();
+ if (IsFPR(reg) && offset < m_fpregset.GetByteSize()) {
+ value.SetFromMemoryData(reg_info, m_fpregset.GetDataStart() + offset,
----------------
labath wrote:
> This `IsFPR` check is now redundant.
Ack,
================
Comment at: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp:152-153
+ sve_reg_num = reg_info->value_regs[0];
+ else if (reg == GetRegNumFPCR() || reg == GetRegNumFPSR())
+ sve_reg_num = reg;
+ if (sve_reg_num != LLDB_INVALID_REGNUM) {
----------------
labath wrote:
> These two registers are special-cased both here and in the `CalculateSVEOffset`. Given that both functions also do a switch over the sve "states", it makes following the code quite challenging. What if we moved the handling of these registers completely up-front, and removed their handling from `CalculateSVEOffset` completely?
> I'm thinking of something like:
> ```
> if (reg == GetRegNumFPCR() && m_sve_state != SVEState::Disabled) {
> src = GetSVEBuffer() + GetFPCROffset(); // Or maybe just inline GetFPCROffset here
> } else if (reg == GetRegNumFPSR() && m_sve_state != SVEState::Disabled) {
> src = ...;
> } if (IsFPR(reg)) {
> // as usual, only you can assume that FP[CS]R are already handled if SVE is enabled
> }
> ```
Ok will try to update in next revision.
================
Comment at: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp:161-162
+ } else if (IsSVEVG(reg)) {
+ sve_vg = GetSVERegVG();
+ src = (uint8_t *)&sve_vg;
+ } else if (IsSVE(reg)) {
----------------
labath wrote:
> This also looks endian-incorrect. Maybe `value = GetSVERegVG(); return true;` ?
Endian invariant as explained above.
================
Comment at: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp:164
+ } else if (IsSVE(reg)) {
+ if (m_sve_state != SVEState::Disabled) {
+ if (m_sve_state == SVEState::FPSIMD) {
----------------
labath wrote:
> A switch over possible `m_sve_state` values would likely be cleaner.
Ack.
================
Comment at: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp:174
+ ::memcpy(sve_reg_non_live.data(),
+ (const uint8_t *)GetSVEBuffer() + offset, 16);
+ }
----------------
labath wrote:
> I guess it would be better to do the cast inside GetSVEBuffer. (and please make that a c++ reinterpret_cast).
Ack.
================
Comment at: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp:180
+ assert(offset < m_sveregset.GetByteSize());
+ src = (uint8_t *)GetSVEBuffer() + offset;
+ }
----------------
labath wrote:
> it seems that `src` should be a const pointer.
Ack.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D77047/new/
https://reviews.llvm.org/D77047
More information about the lldb-commits
mailing list