diff options
author | Aidan Dodds <aidan@codeplay.com> | 2016-02-22 17:29:56 +0000 |
---|---|---|
committer | Aidan Dodds <aidan@codeplay.com> | 2016-02-22 17:29:56 +0000 |
commit | 933d8db9229ee4956f5a0e618ee81452ddb1820d (patch) | |
tree | 359b3223248384c49f40e1eb4c888e05234768d9 /lldb/source/Target/Platform.cpp | |
parent | 46e39cc6b0af95ffdc2ff21c9387c1939c82cd7c (diff) | |
download | bcm5719-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.cpp | 103 |
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; +} |