From 63c8be9571df98df49d80cc760092de26106e82a Mon Sep 17 00:00:00 2001 From: Tamas Berghammer Date: Wed, 15 Apr 2015 09:38:48 +0000 Subject: [PATCH] Fix breakpoint trap opcode detection for arm linux llvm-svn: 234986 --- .../Plugins/Platform/Linux/PlatformLinux.cpp | 3 +- .../Process/Linux/NativeProcessLinux.cpp | 36 ++++++++++++++++--- .../Process/Linux/NativeProcessLinux.h | 2 +- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp index 108de9d4bca0..c2ef981580c8 100644 --- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp +++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp @@ -583,8 +583,7 @@ PlatformLinux::GetSoftwareBreakpointTrapOpcode (Target &target, addr_class = bp_loc_sp->GetAddress ().GetAddressClass (); if (addr_class == eAddressClassCodeAlternateISA - || (addr_class == eAddressClassUnknown - && bp_loc_sp->GetAddress().GetOffset() & 1)) + || (addr_class == eAddressClassUnknown && (bp_site->GetLoadAddress() & 1))) { trap_opcode = g_thumb_breakpoint_opcode; trap_opcode_size = sizeof(g_thumb_breakpoint_opcode); diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp index 5712dc52ad5c..286e21afec50 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -3189,7 +3189,7 @@ NativeProcessLinux::GetArchitecture (ArchSpec &arch) const } Error -NativeProcessLinux::GetSoftwareBreakpointSize (NativeRegisterContextSP context_sp, uint32_t &actual_opcode_size) +NativeProcessLinux::GetSoftwareBreakpointPCOffset (NativeRegisterContextSP context_sp, uint32_t &actual_opcode_size) { // FIXME put this behind a breakpoint protocol class that can be // set per architecture. Need ARM, MIPS support here. @@ -3202,6 +3202,10 @@ NativeProcessLinux::GetSoftwareBreakpointSize (NativeRegisterContextSP context_s actual_opcode_size = static_cast (sizeof(g_aarch64_opcode)); return Error (); + case llvm::Triple::arm: + actual_opcode_size = 0; // On arm the PC don't get updated for breakpoint hits + return Error (); + case llvm::Triple::x86: case llvm::Triple::x86_64: actual_opcode_size = static_cast (sizeof(g_i386_opcode)); @@ -3223,14 +3227,20 @@ NativeProcessLinux::SetBreakpoint (lldb::addr_t addr, uint32_t size, bool hardwa } Error -NativeProcessLinux::GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hint, size_t &actual_opcode_size, const uint8_t *&trap_opcode_bytes) +NativeProcessLinux::GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hint, + size_t &actual_opcode_size, + const uint8_t *&trap_opcode_bytes) { - // FIXME put this behind a breakpoint protocol class that can be - // set per architecture. Need ARM, MIPS support here. + // FIXME put this behind a breakpoint protocol class that can be set per + // architecture. Need MIPS support here. static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xd4 }; + // The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the + // linux kernel does otherwise. + static const uint8_t g_arm_breakpoint_opcode[] = { 0xf0, 0x01, 0xf0, 0xe7 }; static const uint8_t g_i386_opcode [] = { 0xCC }; static const uint8_t g_mips64_opcode[] = { 0x00, 0x00, 0x00, 0x0d }; static const uint8_t g_mips64el_opcode[] = { 0x0d, 0x00, 0x00, 0x00 }; + static const uint8_t g_thumb_breakpoint_opcode[] = { 0x01, 0xde }; switch (m_arch.GetMachine ()) { @@ -3239,6 +3249,22 @@ NativeProcessLinux::GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hin actual_opcode_size = sizeof(g_aarch64_opcode); return Error (); + case llvm::Triple::arm: + switch (trap_opcode_size_hint) + { + case 2: + trap_opcode_bytes = g_thumb_breakpoint_opcode; + actual_opcode_size = sizeof(g_thumb_breakpoint_opcode); + return Error (); + case 4: + trap_opcode_bytes = g_arm_breakpoint_opcode; + actual_opcode_size = sizeof(g_arm_breakpoint_opcode); + return Error (); + default: + assert(false && "Unrecognised trap opcode size hint!"); + return Error ("Unrecognised trap opcode size hint!"); + } + case llvm::Triple::x86: case llvm::Triple::x86_64: trap_opcode_bytes = g_i386_opcode; @@ -3858,7 +3884,7 @@ NativeProcessLinux::FixupBreakpointPCAsNeeded (NativeThreadProtocolSP &thread_sp } uint32_t breakpoint_size = 0; - error = GetSoftwareBreakpointSize (context_sp, breakpoint_size); + error = GetSoftwareBreakpointPCOffset (context_sp, breakpoint_size); if (error.Fail ()) { if (log) diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h index 3c597b64e735..be205f8e4a4f 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h @@ -365,7 +365,7 @@ namespace process_linux { GetOrCreateThread (lldb::tid_t thread_id, bool &created); Error - GetSoftwareBreakpointSize (NativeRegisterContextSP context_sp, uint32_t &actual_opcode_size); + GetSoftwareBreakpointPCOffset (NativeRegisterContextSP context_sp, uint32_t &actual_opcode_size); Error FixupBreakpointPCAsNeeded (NativeThreadProtocolSP &thread_sp);