summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/Platform.cpp
diff options
context:
space:
mode:
authorAidan Dodds <aidan@codeplay.com>2016-02-22 17:29:56 +0000
committerAidan Dodds <aidan@codeplay.com>2016-02-22 17:29:56 +0000
commit933d8db9229ee4956f5a0e618ee81452ddb1820d (patch)
tree359b3223248384c49f40e1eb4c888e05234768d9 /lldb/source/Target/Platform.cpp
parent46e39cc6b0af95ffdc2ff21c9387c1939c82cd7c (diff)
downloadbcm5719-llvm-933d8db9229ee4956f5a0e618ee81452ddb1820d.tar.gz
bcm5719-llvm-933d8db9229ee4956f5a0e618ee81452ddb1820d.zip
Refactor GetSoftwareBreakpointTrapOpcode
This patch aims to reduce the code duplication among all of the platforms in GetSoftwareBreakpointTrapOpcode by pushing all common code into the Platform base class. Differential Revision: http://reviews.llvm.org/D17395 llvm-svn: 261536
Diffstat (limited to 'lldb/source/Target/Platform.cpp')
-rw-r--r--lldb/source/Target/Platform.cpp103
1 files changed, 103 insertions, 0 deletions
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index f92338e061f..bcf5241c50f 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -20,6 +20,7 @@
// Project includes
#include "lldb/Target/Platform.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Error.h"
@@ -2046,3 +2047,105 @@ Platform::ConnectToWaitingProcesses(lldb_private::Debugger& debugger, lldb_priva
error.Clear();
return 0;
}
+
+size_t
+Platform::GetSoftwareBreakpointTrapOpcode(Target &target, BreakpointSite *bp_site)
+{
+ ArchSpec arch = target.GetArchitecture();
+ const uint8_t *trap_opcode = nullptr;
+ size_t trap_opcode_size = 0;
+
+ switch (arch.GetMachine())
+ {
+ case llvm::Triple::aarch64:
+ {
+ static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4};
+ trap_opcode = g_aarch64_opcode;
+ trap_opcode_size = sizeof(g_aarch64_opcode);
+ }
+ break;
+
+ // TODO: support big-endian arm and thumb trap codes.
+ case llvm::Triple::arm:
+ {
+ // 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_thumb_breakpoint_opcode[] = {0x01, 0xde};
+
+ lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
+ AddressClass addr_class = eAddressClassUnknown;
+
+ if (bp_loc_sp)
+ {
+ addr_class = bp_loc_sp->GetAddress().GetAddressClass();
+ if (addr_class == eAddressClassUnknown && (bp_loc_sp->GetAddress().GetFileAddress() & 1))
+ addr_class = eAddressClassCodeAlternateISA;
+ }
+
+ if (addr_class == eAddressClassCodeAlternateISA)
+ {
+ trap_opcode = g_thumb_breakpoint_opcode;
+ trap_opcode_size = sizeof(g_thumb_breakpoint_opcode);
+ }
+ else
+ {
+ trap_opcode = g_arm_breakpoint_opcode;
+ trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
+ }
+ }
+ break;
+
+ case llvm::Triple::mips64:
+ {
+ static const uint8_t g_hex_opcode[] = {0x00, 0x00, 0x00, 0x0d};
+ trap_opcode = g_hex_opcode;
+ trap_opcode_size = sizeof(g_hex_opcode);
+ }
+ break;
+
+ case llvm::Triple::mips64el:
+ {
+ static const uint8_t g_hex_opcode[] = {0x0d, 0x00, 0x00, 0x00};
+ trap_opcode = g_hex_opcode;
+ trap_opcode_size = sizeof(g_hex_opcode);
+ }
+ break;
+
+ case llvm::Triple::hexagon:
+ {
+ static const uint8_t g_hex_opcode[] = {0x0c, 0xdb, 0x00, 0x54};
+ trap_opcode = g_hex_opcode;
+ trap_opcode_size = sizeof(g_hex_opcode);
+ }
+ break;
+
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ {
+ static const uint8_t g_ppc_opcode[] = {0x7f, 0xe0, 0x00, 0x08};
+ trap_opcode = g_ppc_opcode;
+ trap_opcode_size = sizeof(g_ppc_opcode);
+ }
+ break;
+
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ {
+ static const uint8_t g_i386_opcode[] = {0xCC};
+ trap_opcode = g_i386_opcode;
+ trap_opcode_size = sizeof(g_i386_opcode);
+ }
+ break;
+
+ default:
+ assert(!"Unhandled architecture in Platform::GetSoftwareBreakpointTrapOpcode");
+ break;
+ }
+
+ assert(bp_site);
+ if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
+ return trap_opcode_size;
+
+ return 0;
+}
OpenPOWER on IntegriCloud