summaryrefslogtreecommitdiff
path: root/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-07-23 20:50:09 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-07-23 20:50:09 +0000
commitf3fbd1c0586ff6ec7895991e6c28f61a503c36a8 (patch)
tree48d008fd3df8c0e73271a4b18474e0aac6dbfe33 /source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
parent2fc5d2d1dfaf623ce4e24cd8590565902f8c557c (diff)
Notes
Diffstat (limited to 'source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp')
-rw-r--r--source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp542
1 files changed, 275 insertions, 267 deletions
diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
index 6d124b689341f..4d24cf1ab6de3 100644
--- a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
+++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
@@ -11,20 +11,20 @@
// C++ Includes
// Project includes
#include "llvm-c/Disassembler.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCDisassembler.h"
-#include "llvm/MC/MCExternalSymbolizer.h"
+#include "llvm/MC/MCDisassembler/MCDisassembler.h"
+#include "llvm/MC/MCDisassembler/MCExternalSymbolizer.h"
+#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCRelocationInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
-#include "llvm/ADT/SmallString.h"
// Other libraries and framework includes
#include "DisassemblerLLVMC.h"
@@ -53,7 +53,7 @@ public:
const lldb_private::Address &address,
AddressClass addr_class) :
Instruction (address, addr_class),
- m_disasm_sp (disasm.shared_from_this()),
+ m_disasm_wp (std::static_pointer_cast<DisassemblerLLVMC>(disasm.shared_from_this())),
m_does_branch (eLazyBoolCalculate),
m_has_delay_slot (eLazyBoolCalculate),
m_is_valid (false),
@@ -68,34 +68,38 @@ public:
{
if (m_does_branch == eLazyBoolCalculate)
{
- GetDisassemblerLLVMC().Lock(this, NULL);
- DataExtractor data;
- if (m_opcode.GetData(data))
+ std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
+ if (disasm_sp)
{
- bool is_alternate_isa;
- lldb::addr_t pc = m_address.GetFileAddress();
-
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
- const uint8_t *opcode_data = data.GetDataStart();
- const size_t opcode_data_len = data.GetByteSize();
- llvm::MCInst inst;
- const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
- opcode_data_len,
- pc,
- inst);
- // Be conservative, if we didn't understand the instruction, say it might branch...
- if (inst_size == 0)
- m_does_branch = eLazyBoolYes;
- else
+ disasm_sp->Lock(this, NULL);
+ DataExtractor data;
+ if (m_opcode.GetData(data))
{
- const bool can_branch = mc_disasm_ptr->CanBranch(inst);
- if (can_branch)
+ bool is_alternate_isa;
+ lldb::addr_t pc = m_address.GetFileAddress();
+
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
+ const uint8_t *opcode_data = data.GetDataStart();
+ const size_t opcode_data_len = data.GetByteSize();
+ llvm::MCInst inst;
+ const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
+ opcode_data_len,
+ pc,
+ inst);
+ // Be conservative, if we didn't understand the instruction, say it might branch...
+ if (inst_size == 0)
m_does_branch = eLazyBoolYes;
else
- m_does_branch = eLazyBoolNo;
+ {
+ const bool can_branch = mc_disasm_ptr->CanBranch(inst);
+ if (can_branch)
+ m_does_branch = eLazyBoolYes;
+ else
+ m_does_branch = eLazyBoolNo;
+ }
}
+ disasm_sp->Unlock();
}
- GetDisassemblerLLVMC().Unlock();
}
return m_does_branch == eLazyBoolYes;
}
@@ -105,34 +109,38 @@ public:
{
if (m_has_delay_slot == eLazyBoolCalculate)
{
- GetDisassemblerLLVMC().Lock(this, NULL);
- DataExtractor data;
- if (m_opcode.GetData(data))
+ std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
+ if (disasm_sp)
{
- bool is_alternate_isa;
- lldb::addr_t pc = m_address.GetFileAddress();
-
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
- const uint8_t *opcode_data = data.GetDataStart();
- const size_t opcode_data_len = data.GetByteSize();
- llvm::MCInst inst;
- const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
- opcode_data_len,
- pc,
- inst);
- // if we didn't understand the instruction, say it doesn't have a delay slot...
- if (inst_size == 0)
- m_has_delay_slot = eLazyBoolNo;
- else
+ disasm_sp->Lock(this, NULL);
+ DataExtractor data;
+ if (m_opcode.GetData(data))
{
- const bool has_delay_slot = mc_disasm_ptr->HasDelaySlot(inst);
- if (has_delay_slot)
- m_has_delay_slot = eLazyBoolYes;
- else
+ bool is_alternate_isa;
+ lldb::addr_t pc = m_address.GetFileAddress();
+
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
+ const uint8_t *opcode_data = data.GetDataStart();
+ const size_t opcode_data_len = data.GetByteSize();
+ llvm::MCInst inst;
+ const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
+ opcode_data_len,
+ pc,
+ inst);
+ // if we didn't understand the instruction, say it doesn't have a delay slot...
+ if (inst_size == 0)
m_has_delay_slot = eLazyBoolNo;
+ else
+ {
+ const bool has_delay_slot = mc_disasm_ptr->HasDelaySlot(inst);
+ if (has_delay_slot)
+ m_has_delay_slot = eLazyBoolYes;
+ else
+ m_has_delay_slot = eLazyBoolNo;
+ }
}
+ disasm_sp->Unlock();
}
- GetDisassemblerLLVMC().Unlock();
}
return m_has_delay_slot == eLazyBoolYes;
}
@@ -141,18 +149,22 @@ public:
GetDisasmToUse (bool &is_alternate_isa)
{
is_alternate_isa = false;
- DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
- if (llvm_disasm.m_alternate_disasm_ap.get() != NULL)
+ std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
+ if (disasm_sp)
{
- const AddressClass address_class = GetAddressClass ();
-
- if (address_class == eAddressClassCodeAlternateISA)
+ if (disasm_sp->m_alternate_disasm_ap.get() != NULL)
{
- is_alternate_isa = true;
- return llvm_disasm.m_alternate_disasm_ap.get();
+ const AddressClass address_class = GetAddressClass ();
+
+ if (address_class == eAddressClassCodeAlternateISA)
+ {
+ is_alternate_isa = true;
+ return disasm_sp->m_alternate_disasm_ap.get();
+ }
}
+ return disasm_sp->m_disasm_ap.get();
}
- return llvm_disasm.m_disasm_ap.get();
+ return nullptr;
}
size_t
@@ -163,101 +175,105 @@ public:
// All we have to do is read the opcode which can be easy for some
// architectures
bool got_op = false;
- DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
- const ArchSpec &arch = llvm_disasm.GetArchitecture();
- const lldb::ByteOrder byte_order = data.GetByteOrder();
-
- const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize();
- const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize();
- if (min_op_byte_size == max_op_byte_size)
+ std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
+ if (disasm_sp)
{
- // Fixed size instructions, just read that amount of data.
- if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size))
- return false;
+ const ArchSpec &arch = disasm_sp->GetArchitecture();
+ const lldb::ByteOrder byte_order = data.GetByteOrder();
- switch (min_op_byte_size)
+ const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize();
+ const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize();
+ if (min_op_byte_size == max_op_byte_size)
{
- case 1:
- m_opcode.SetOpcode8 (data.GetU8 (&data_offset), byte_order);
- got_op = true;
- break;
-
- case 2:
- m_opcode.SetOpcode16 (data.GetU16 (&data_offset), byte_order);
- got_op = true;
- break;
-
- case 4:
- m_opcode.SetOpcode32 (data.GetU32 (&data_offset), byte_order);
- got_op = true;
- break;
-
- case 8:
- m_opcode.SetOpcode64 (data.GetU64 (&data_offset), byte_order);
- got_op = true;
- break;
-
- default:
- m_opcode.SetOpcodeBytes(data.PeekData(data_offset, min_op_byte_size), min_op_byte_size);
- got_op = true;
- break;
- }
- }
- if (!got_op)
- {
- bool is_alternate_isa = false;
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
+ // Fixed size instructions, just read that amount of data.
+ if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size))
+ return false;
+
+ switch (min_op_byte_size)
+ {
+ case 1:
+ m_opcode.SetOpcode8 (data.GetU8 (&data_offset), byte_order);
+ got_op = true;
+ break;
+
+ case 2:
+ m_opcode.SetOpcode16 (data.GetU16 (&data_offset), byte_order);
+ got_op = true;
+ break;
+
+ case 4:
+ m_opcode.SetOpcode32 (data.GetU32 (&data_offset), byte_order);
+ got_op = true;
+ break;
+
+ case 8:
+ m_opcode.SetOpcode64 (data.GetU64 (&data_offset), byte_order);
+ got_op = true;
+ break;
- const llvm::Triple::ArchType machine = arch.GetMachine();
- if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb)
+ default:
+ m_opcode.SetOpcodeBytes(data.PeekData(data_offset, min_op_byte_size), min_op_byte_size);
+ got_op = true;
+ break;
+ }
+ }
+ if (!got_op)
{
- if (machine == llvm::Triple::thumb || is_alternate_isa)
+ bool is_alternate_isa = false;
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
+
+ const llvm::Triple::ArchType machine = arch.GetMachine();
+ if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb)
{
- uint32_t thumb_opcode = data.GetU16(&data_offset);
- if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
+ if (machine == llvm::Triple::thumb || is_alternate_isa)
{
- m_opcode.SetOpcode16 (thumb_opcode, byte_order);
- m_is_valid = true;
+ uint32_t thumb_opcode = data.GetU16(&data_offset);
+ if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
+ {
+ m_opcode.SetOpcode16 (thumb_opcode, byte_order);
+ m_is_valid = true;
+ }
+ else
+ {
+ thumb_opcode <<= 16;
+ thumb_opcode |= data.GetU16(&data_offset);
+ m_opcode.SetOpcode16_2 (thumb_opcode, byte_order);
+ m_is_valid = true;
+ }
}
else
{
- thumb_opcode <<= 16;
- thumb_opcode |= data.GetU16(&data_offset);
- m_opcode.SetOpcode16_2 (thumb_opcode, byte_order);
+ m_opcode.SetOpcode32 (data.GetU32(&data_offset), byte_order);
m_is_valid = true;
}
}
else
{
- m_opcode.SetOpcode32 (data.GetU32(&data_offset), byte_order);
- m_is_valid = true;
- }
- }
- else
- {
- // The opcode isn't evenly sized, so we need to actually use the llvm
- // disassembler to parse it and get the size.
- uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1));
- const size_t opcode_data_len = data.BytesLeft(data_offset);
- const addr_t pc = m_address.GetFileAddress();
- llvm::MCInst inst;
-
- llvm_disasm.Lock(this, NULL);
- const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
- opcode_data_len,
- pc,
- inst);
- llvm_disasm.Unlock();
- if (inst_size == 0)
- m_opcode.Clear();
- else
- {
- m_opcode.SetOpcodeBytes(opcode_data, inst_size);
- m_is_valid = true;
+ // The opcode isn't evenly sized, so we need to actually use the llvm
+ // disassembler to parse it and get the size.
+ uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1));
+ const size_t opcode_data_len = data.BytesLeft(data_offset);
+ const addr_t pc = m_address.GetFileAddress();
+ llvm::MCInst inst;
+
+ disasm_sp->Lock(this, NULL);
+ const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
+ opcode_data_len,
+ pc,
+ inst);
+ disasm_sp->Unlock();
+ if (inst_size == 0)
+ m_opcode.Clear();
+ else
+ {
+ m_opcode.SetOpcodeBytes(opcode_data, inst_size);
+ m_is_valid = true;
+ }
}
}
+ return m_opcode.GetByteSize();
}
- return m_opcode.GetByteSize();
+ return 0;
}
void
@@ -283,146 +299,148 @@ public:
std::string out_string;
std::string comment_string;
- DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
-
- DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;
+ std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
+ if (disasm_sp)
+ {
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;
- if (address_class == eAddressClassCodeAlternateISA)
- mc_disasm_ptr = llvm_disasm.m_alternate_disasm_ap.get();
- else
- mc_disasm_ptr = llvm_disasm.m_disasm_ap.get();
+ if (address_class == eAddressClassCodeAlternateISA)
+ mc_disasm_ptr = disasm_sp->m_alternate_disasm_ap.get();
+ else
+ mc_disasm_ptr = disasm_sp->m_disasm_ap.get();
- lldb::addr_t pc = m_address.GetFileAddress();
- m_using_file_addr = true;
+ lldb::addr_t pc = m_address.GetFileAddress();
+ m_using_file_addr = true;
- const bool data_from_file = GetDisassemblerLLVMC().m_data_from_file;
- bool use_hex_immediates = true;
- Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC;
+ const bool data_from_file = disasm_sp->m_data_from_file;
+ bool use_hex_immediates = true;
+ Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC;
- if (exe_ctx)
- {
- Target *target = exe_ctx->GetTargetPtr();
- if (target)
+ if (exe_ctx)
{
- use_hex_immediates = target->GetUseHexImmediates();
- hex_style = target->GetHexImmediateStyle();
-
- if (!data_from_file)
+ Target *target = exe_ctx->GetTargetPtr();
+ if (target)
{
- const lldb::addr_t load_addr = m_address.GetLoadAddress(target);
- if (load_addr != LLDB_INVALID_ADDRESS)
+ use_hex_immediates = target->GetUseHexImmediates();
+ hex_style = target->GetHexImmediateStyle();
+
+ if (!data_from_file)
{
- pc = load_addr;
- m_using_file_addr = false;
+ const lldb::addr_t load_addr = m_address.GetLoadAddress(target);
+ if (load_addr != LLDB_INVALID_ADDRESS)
+ {
+ pc = load_addr;
+ m_using_file_addr = false;
+ }
}
}
}
- }
- llvm_disasm.Lock(this, exe_ctx);
+ disasm_sp->Lock(this, exe_ctx);
- const uint8_t *opcode_data = data.GetDataStart();
- const size_t opcode_data_len = data.GetByteSize();
- llvm::MCInst inst;
- size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
- opcode_data_len,
- pc,
- inst);
+ const uint8_t *opcode_data = data.GetDataStart();
+ const size_t opcode_data_len = data.GetByteSize();
+ llvm::MCInst inst;
+ size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
+ opcode_data_len,
+ pc,
+ inst);
- if (inst_size > 0)
- {
- mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style);
- mc_disasm_ptr->PrintMCInst(inst, out_string, comment_string);
-
- if (!comment_string.empty())
+ if (inst_size > 0)
{
- AppendComment(comment_string);
+ mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style);
+ mc_disasm_ptr->PrintMCInst(inst, out_string, comment_string);
+
+ if (!comment_string.empty())
+ {
+ AppendComment(comment_string);
+ }
}
- }
- llvm_disasm.Unlock();
+ disasm_sp->Unlock();
- if (inst_size == 0)
- {
- m_comment.assign ("unknown opcode");
- inst_size = m_opcode.GetByteSize();
- StreamString mnemonic_strm;
- lldb::offset_t offset = 0;
- lldb::ByteOrder byte_order = data.GetByteOrder();
- switch (inst_size)
+ if (inst_size == 0)
{
- case 1:
- {
- const uint8_t uval8 = data.GetU8 (&offset);
- m_opcode.SetOpcode8 (uval8, byte_order);
- m_opcode_name.assign (".byte");
- mnemonic_strm.Printf("0x%2.2x", uval8);
- }
- break;
- case 2:
- {
- const uint16_t uval16 = data.GetU16(&offset);
- m_opcode.SetOpcode16(uval16, byte_order);
- m_opcode_name.assign (".short");
- mnemonic_strm.Printf("0x%4.4x", uval16);
- }
- break;
- case 4:
- {
- const uint32_t uval32 = data.GetU32(&offset);
- m_opcode.SetOpcode32(uval32, byte_order);
- m_opcode_name.assign (".long");
- mnemonic_strm.Printf("0x%8.8x", uval32);
- }
- break;
- case 8:
- {
- const uint64_t uval64 = data.GetU64(&offset);
- m_opcode.SetOpcode64(uval64, byte_order);
- m_opcode_name.assign (".quad");
- mnemonic_strm.Printf("0x%16.16" PRIx64, uval64);
- }
- break;
- default:
- if (inst_size == 0)
- return;
- else
- {
- const uint8_t *bytes = data.PeekData(offset, inst_size);
- if (bytes == NULL)
+ m_comment.assign ("unknown opcode");
+ inst_size = m_opcode.GetByteSize();
+ StreamString mnemonic_strm;
+ lldb::offset_t offset = 0;
+ lldb::ByteOrder byte_order = data.GetByteOrder();
+ switch (inst_size)
+ {
+ case 1:
+ {
+ const uint8_t uval8 = data.GetU8 (&offset);
+ m_opcode.SetOpcode8 (uval8, byte_order);
+ m_opcode_name.assign (".byte");
+ mnemonic_strm.Printf("0x%2.2x", uval8);
+ }
+ break;
+ case 2:
+ {
+ const uint16_t uval16 = data.GetU16(&offset);
+ m_opcode.SetOpcode16(uval16, byte_order);
+ m_opcode_name.assign (".short");
+ mnemonic_strm.Printf("0x%4.4x", uval16);
+ }
+ break;
+ case 4:
+ {
+ const uint32_t uval32 = data.GetU32(&offset);
+ m_opcode.SetOpcode32(uval32, byte_order);
+ m_opcode_name.assign (".long");
+ mnemonic_strm.Printf("0x%8.8x", uval32);
+ }
+ break;
+ case 8:
+ {
+ const uint64_t uval64 = data.GetU64(&offset);
+ m_opcode.SetOpcode64(uval64, byte_order);
+ m_opcode_name.assign (".quad");
+ mnemonic_strm.Printf("0x%16.16" PRIx64, uval64);
+ }
+ break;
+ default:
+ if (inst_size == 0)
return;
- m_opcode_name.assign (".byte");
- m_opcode.SetOpcodeBytes(bytes, inst_size);
- mnemonic_strm.Printf("0x%2.2x", bytes[0]);
- for (uint32_t i=1; i<inst_size; ++i)
- mnemonic_strm.Printf(" 0x%2.2x", bytes[i]);
- }
- break;
+ else
+ {
+ const uint8_t *bytes = data.PeekData(offset, inst_size);
+ if (bytes == NULL)
+ return;
+ m_opcode_name.assign (".byte");
+ m_opcode.SetOpcodeBytes(bytes, inst_size);
+ mnemonic_strm.Printf("0x%2.2x", bytes[0]);
+ for (uint32_t i=1; i<inst_size; ++i)
+ mnemonic_strm.Printf(" 0x%2.2x", bytes[i]);
+ }
+ break;
+ }
+ m_mnemonics.swap(mnemonic_strm.GetString());
+ return;
}
- m_mnemonics.swap(mnemonic_strm.GetString());
- return;
- }
- else
- {
- if (m_does_branch == eLazyBoolCalculate)
+ else
{
- const bool can_branch = mc_disasm_ptr->CanBranch(inst);
- if (can_branch)
- m_does_branch = eLazyBoolYes;
- else
- m_does_branch = eLazyBoolNo;
+ if (m_does_branch == eLazyBoolCalculate)
+ {
+ const bool can_branch = mc_disasm_ptr->CanBranch(inst);
+ if (can_branch)
+ m_does_branch = eLazyBoolYes;
+ else
+ m_does_branch = eLazyBoolNo;
+ }
}
- }
- static RegularExpression s_regex("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?");
+ static RegularExpression s_regex("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?");
- RegularExpression::Match matches(3);
+ RegularExpression::Match matches(3);
- if (s_regex.Execute(out_string.c_str(), &matches))
- {
- matches.GetMatchAtIndex(out_string.c_str(), 1, m_opcode_name);
- matches.GetMatchAtIndex(out_string.c_str(), 2, m_mnemonics);
+ if (s_regex.Execute(out_string.c_str(), &matches))
+ {
+ matches.GetMatchAtIndex(out_string.c_str(), 1, m_opcode_name);
+ matches.GetMatchAtIndex(out_string.c_str(), 2, m_mnemonics);
+ }
}
}
}
@@ -444,14 +462,14 @@ public:
return m_opcode.GetByteSize();
}
- DisassemblerLLVMC &
- GetDisassemblerLLVMC ()
+ std::shared_ptr<DisassemblerLLVMC>
+ GetDisassembler ()
{
- return *(DisassemblerLLVMC *)m_disasm_sp.get();
+ return m_disasm_wp.lock();
}
protected:
- DisassemblerSP m_disasm_sp; // for ownership
+ std::weak_ptr<DisassemblerLLVMC> m_disasm_wp;
LazyBool m_does_branch;
LazyBool m_has_delay_slot;
bool m_is_valid;
@@ -633,7 +651,7 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s
}
else
{
- thumb_arch_name = "thumbv7";
+ thumb_arch_name = "thumbv8.2a";
}
thumb_arch.GetTriple().setArchName(llvm::StringRef(thumb_arch_name.c_str()));
}
@@ -643,22 +661,12 @@ DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_s
// in case the code uses instructions which are not available in the oldest arm version
// (used when no sub architecture is specified)
if (triple.getArch() == llvm::Triple::arm && triple.getSubArch() == llvm::Triple::NoSubArch)
- triple.setArchName("armv8.1a");
+ triple.setArchName("armv8.2a");
const char *triple_str = triple.getTriple().c_str();
- // v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization
- //
- // Cortex-M3 devices (e.g. armv7m) can only execute thumb (T2) instructions,
- // so hardcode the primary disassembler to thumb mode. Same for Cortex-M4 (armv7em).
- //
- // Handle the Cortex-M0 (armv6m) the same; the ISA is a subset of the T and T32
- // instructions defined in ARMv7-A.
-
- if ((triple.getArch() == llvm::Triple::arm || triple.getArch() == llvm::Triple::thumb)
- && (arch.GetCore() == ArchSpec::Core::eCore_arm_armv7m
- || arch.GetCore() == ArchSpec::Core::eCore_arm_armv7em
- || arch.GetCore() == ArchSpec::Core::eCore_arm_armv6m))
+ // ARM Cortex M0-M7 devices only execute thumb instructions
+ if (arch.IsAlwaysThumbInstructions ())
{
triple_str = thumb_arch.GetTriple().getTriple().c_str();
}