https://bugs.llvm.org/show_bug.cgi?id=51673
Bug ID: 51673
Summary: AArch64 debug problems on Windows
Product: lldb
Version: 10.0
Hardware: Other
OS: Windows NT
Status: NEW
Severity: normal
Priority: P
Component: All Bugs
Assignee: lldb-dev@lists.llvm.org
Reporter: e...@andante.org
CC: jdevliegh...@apple.com, llvm-b...@lists.llvm.org
I was using lldb on Windows (Raspberry Pi 4 - ARM Cortex-A72 processor), and
there were a couple of x86-isms that persist that make it impossible to set and
use breakpoints.
Platform::GetSoftwareBreakpointTrapOpcode()
NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode()
Uses "0xd4 0x20 0x00 0x00" for breakpoint on aarch64, but this does not work on
Windows as it fails with a STATUS_ILLEGAL_INSTRUCTION exception being thrown.
case llvm::Triple::aarch64: {
static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4};
The compiler intrinsic __debug_break() generates "{0x00, 0x00, 0x3e, 0xd4}".
If I instead use this, then the program stops at the requested breakpoint, as
expected.
----------
TargetThreadWindows::DoResume()
NativeThreadWindows::DoResume()
Sets flag 0x100 for single step, but that's only valid for x86/x64.
if (resume_state == eStateStepping) {
uint32_t flags_index =
GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
uint64_t flags_value =
GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
flags_value |= 0x100; // Set the trap flag on the CPU /* only correct for
x86/x64 */
GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
}
For AArch64, it should instead be 0x200000, as this is the location of the 'SS'
bit of the PState register. Using this value, then single stepping works as
expected.
Without a fix in this area, single stepping simply doesn't work.
----------
ProcessWindows::RefreshStateAfterStop()
When handling EXCEPTION_BREAKPOINT, it assumes that the breakpoint instruction
is 1 byte, which is only correct for x86/x64.
// The current EIP is AFTER the BP opcode, which is one byte.
uint64_t pc = register_context->GetPC() - 1;
The basic theory here is that after a breakpoint exception, that the program
counter points to the instruction *after* the breakpoint, so we need to back up
one instruction to get to the real breakpoint. On x86, a breakpoint is a
single byte 0xCC. For AArch64 it needs to be 4 bytes (as noted above). Other
architectures are going to be different of course. One can temporarily tweak
this so that it works, of course, but on the surface it seems like the
breakpoint information is already encapsulated in Platform.cpp, I suppose it
would be best to simply leverage that.
Note that I am currently working in a LLVM 10.0 source tree, but I looked ahead
to version 12 and I see no changes in this area.
I should add that with fixes/tweaks in all 3 of these places, the AArch64 lldb
actually behaves pretty normally. I am still having a little trouble with PDB
files, but I can address that separately.
--
You are receiving this mail because:
You are the assignee for the bug.
_______________________________________________
lldb-dev mailing list
lldb-dev@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev