summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
diff options
context:
space:
mode:
authorTamas Berghammer <tberghammer@google.com>2015-04-15 09:38:48 +0000
committerTamas Berghammer <tberghammer@google.com>2015-04-15 09:38:48 +0000
commit63c8be9571df98df49d80cc760092de26106e82a (patch)
tree46f065208ff7d0b780a22efeb5cb09546fe27b9e /lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
parent23fc4b00a9f32f75d0f594658207043da5b55105 (diff)
Fix breakpoint trap opcode detection for arm linux
llvm-svn: 234986
Diffstat (limited to 'lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp')
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp36
1 files changed, 31 insertions, 5 deletions
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<uint32_t> (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<uint32_t> (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)