This patch add fix for reading and writing floating point register based on SR.FR bit.
Details
- Reviewers
clayborg jaydeep labath - Commits
- rGa5124f8a01b3: Merging r284003: --------------------------------------------------------------…
rG47a2c5544710: [LLDB][MIPS] fix Floating point register read/write for big endian
rLLDB284003: [LLDB][MIPS] fix Floating point register read/write for big endian
rL284003: [LLDB][MIPS] fix Floating point register read/write for big endian
Diff Detail
- Repository
- rL LLVM
Event Timeline
source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp | ||
---|---|---|
1183 ↗ | (On Diff #71487) | Why do we need to do this remapping? Couldn't we structure the register infos in a way that reg_info->byte_offset is exactly the offset that ptrace expects? Or are you saying that ptrace does not accept register offsets, but some random register numbers instead? (I cannot tell, as the comment above is confusing.) |
1222 ↗ | (On Diff #71487) | This seems like a pretty complicated way to write assert(!reg_info->invalidate_regs); |
source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp | ||
---|---|---|
1183 ↗ | (On Diff #71487) | In case of MIPS, ptrace request PTRACE_PEEKUSER/PTRACE_POKEUSER accept register number as an offset. We used reg_info->byte_offset to find register value in the struct GPR_linux_mips. The struct GPR_linux_mips is same for 32 and 64 bit since ptrace always return 64 bit value irrespective of Arch (32 and 64) . Hence we can't modify reg_info->byte_offset to match exactly the offset that ptrace expects. |
source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp | ||
---|---|---|
1161 ↗ | (On Diff #71487) | Ok I think I understand this now. |
1183 ↗ | (On Diff #71487) | Ok, I see what you mean. byte_offset is out in that case. This is not that bad, as the "scheme" is confined to the single file, but still you have to admit that this function looks very odd: sometimes you return a register index, sometimes a register offset and sometimes a completely made up number... |
1207 ↗ | (On Diff #71487) | Isn't it possible to match the "config5" register by one of the numbering schemes, instead of by name? |
source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp | ||
---|---|---|
1183 ↗ | (On Diff #71505) | Changing LLDB numbering scheme is not feasible since there are lots of changes both at host and target site. Should I add new numbering scheme ? |
So it seems like this can be fixed by doing a few things:
1 - just set the RegisterInfo.offset to the actual offset in the buffer and don't use the offset as the ptrace key used to grab the register
2 - modify the RegisterInfo.kinds[eRegisterKindProcessPlugin] to be the offset to you to use for ptrace
There should be no need what so ever to do manual bit twiddling with src and dst.
The floating point register size can be dynamically changes . Hence following cases are possible when we read registers from ptrace in FPR_linux_mips buffer (In case of MIPS, ptrace always return value in 64 bit container irrespective of Arch).
- Floating point register size is 32 (SR.FR = 0).
a) In case of big endian system, the FPR_linux_mips.f0 will contains two floating point registers . The $f0 register will be store in upper 32 bit and $f1 register in lower 32 bit of FPR_linux_mips.f0. The FPR_linux_mips.f1 will contain don't care value and similarly for all other registers. Thus each even buffer will contain valid value and represent two registers.
b) In case of liitle endian , the $f0 will be store in lower 32 bit and $f1 in upper 32bit of FPR_linux_mips.f0. The FPR_linux_mips.f1 will contain don't care value and similarly for all other registers.
- Floating point register size is 64 (SR.FR = 1). In these case all buffer will have valid value.
Hence we need bit twiddling with src and dst (in case of SR.FR = 0) so that each buffer will represent value for single register.
Please comment why you are manually bit twiddling due to the size of the register that can change. We don't want anyone else copying this kind of code. Another solution would be to update the offset of the register when you change the byte size so none of this would need to be done. We are already updating the byte size of the register in the RegisterInfo, so why not do the same for the offset. You could store the original offset in the RegisterInfo.kinds[eRegisterKindProcessPlugin] as this field is only for the process plug-in's use.
These diff remove manually bit twiddling due to the size of the floating point register that can change. We use register offset to get floating point register data based on endianess and it's size. We have not remove bit twiddling for MSA register since it's need to be tested( require support in ptrace).
Thanks