summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins')
-rw-r--r--lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.cpp17
-rw-r--r--lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.h11
-rw-r--r--lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.h5
-rw-r--r--lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp271
-rw-r--r--lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h87
-rw-r--r--lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp42
-rw-r--r--lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h26
-rw-r--r--lldb/source/Plugins/Process/Utility/ARMDefines.h9
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp19
-rw-r--r--lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp224
-rw-r--r--lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h78
-rw-r--r--lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp15
-rw-r--r--lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h23
13 files changed, 571 insertions, 256 deletions
diff --git a/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.cpp b/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.cpp
index de8b5f8ff67..4be89faaca5 100644
--- a/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.cpp
+++ b/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.cpp
@@ -15,8 +15,8 @@
using namespace lldb;
using namespace lldb_private;
-lldb_private::ArchDefaultUnwindPlan *
-ArchDefaultUnwindPlan_x86_64::CreateInstance (const lldb_private::ArchSpec &arch)
+ArchDefaultUnwindPlan *
+ArchDefaultUnwindPlan_x86_64::CreateInstance (const ArchSpec &arch)
{
if (arch.GetMachine () == llvm::Triple::x86_64)
return new ArchDefaultUnwindPlan_x86_64 ();
@@ -24,7 +24,7 @@ ArchDefaultUnwindPlan_x86_64::CreateInstance (const lldb_private::ArchSpec &arch
}
ArchDefaultUnwindPlan_x86_64::ArchDefaultUnwindPlan_x86_64() :
- lldb_private::ArchDefaultUnwindPlan(),
+ ArchDefaultUnwindPlan(),
m_unwind_plan_sp (new UnwindPlan)
{
UnwindPlan::Row row;
@@ -96,15 +96,16 @@ ArchDefaultUnwindPlan_x86_64::GetPluginDescriptionStatic()
}
UnwindPlanSP
-ArchDefaultUnwindPlan_x86_64::GetArchDefaultUnwindPlan (Thread& thread, Address current_pc)
+ArchDefaultUnwindPlan_x86_64::GetArchDefaultUnwindPlan (Thread& thread,
+ const Address &current_pc)
{
return m_unwind_plan_sp;
}
-lldb_private::ArchDefaultUnwindPlan *
-ArchDefaultUnwindPlan_i386::CreateInstance (const lldb_private::ArchSpec &arch)
+ArchDefaultUnwindPlan *
+ArchDefaultUnwindPlan_i386::CreateInstance (const ArchSpec &arch)
{
if (arch.GetMachine () == llvm::Triple::x86)
return new ArchDefaultUnwindPlan_i386 ();
@@ -112,7 +113,7 @@ ArchDefaultUnwindPlan_i386::CreateInstance (const lldb_private::ArchSpec &arch)
}
ArchDefaultUnwindPlan_i386::ArchDefaultUnwindPlan_i386() :
- lldb_private::ArchDefaultUnwindPlan(),
+ ArchDefaultUnwindPlan(),
m_unwind_plan_sp (new UnwindPlan)
{
UnwindPlan::Row row;
@@ -185,7 +186,7 @@ ArchDefaultUnwindPlan_i386::GetPluginDescriptionStatic()
}
UnwindPlanSP
-ArchDefaultUnwindPlan_i386::GetArchDefaultUnwindPlan (Thread& thread, Address current_pc)
+ArchDefaultUnwindPlan_i386::GetArchDefaultUnwindPlan (Thread& thread, const Address &current_pc)
{
return m_unwind_plan_sp;
}
diff --git a/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.h b/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.h
index 53b37dfc829..ce5abb1c0d8 100644
--- a/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.h
+++ b/lldb/source/Plugins/ArchDefaultUnwindPlan/x86/ArchDefaultUnwindPlan-x86.h
@@ -15,8 +15,6 @@
#include "lldb/Target/Thread.h"
#include "lldb/Symbol/UnwindPlan.h"
-namespace lldb_private {
-
class ArchDefaultUnwindPlan_x86_64 : public lldb_private::ArchDefaultUnwindPlan
{
public:
@@ -24,7 +22,8 @@ public:
~ArchDefaultUnwindPlan_x86_64 () { }
virtual lldb::UnwindPlanSP
- GetArchDefaultUnwindPlan (Thread& thread, Address current_pc);
+ GetArchDefaultUnwindPlan (lldb_private::Thread& thread,
+ const lldb_private::Address &current_pc);
static lldb_private::ArchDefaultUnwindPlan *
CreateInstance (const lldb_private::ArchSpec &arch);
@@ -66,7 +65,8 @@ public:
~ArchDefaultUnwindPlan_i386 () { }
virtual lldb::UnwindPlanSP
- GetArchDefaultUnwindPlan (Thread& thread, Address current_pc);
+ GetArchDefaultUnwindPlan (lldb_private::Thread& thread,
+ const lldb_private::Address& current_pc);
static lldb_private::ArchDefaultUnwindPlan *
CreateInstance (const lldb_private::ArchSpec &arch);
@@ -101,7 +101,4 @@ private:
lldb::UnwindPlanSP m_unwind_plan_sp;
};
-
-} // namespace lldb_private
-
#endif // liblldb_UnwindAssembly_x86_h_
diff --git a/lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.h b/lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.h
index 70e1d202672..c01bef581d7 100644
--- a/lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.h
+++ b/lldb/source/Plugins/ArchVolatileRegs/x86/ArchVolatileRegs-x86.h
@@ -15,8 +15,6 @@
#include "lldb/Target/ArchVolatileRegs.h"
#include <set>
-namespace lldb_private {
-
class ArchVolatileRegs_x86 : public lldb_private::ArchVolatileRegs
{
public:
@@ -62,7 +60,4 @@ private:
std::set<int> m_non_volatile_regs;
};
-
-} // namespace lldb_private
-
#endif // liblldb_ArchVolatileRegs_x86_h_
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index 702ca061da3..f6c52c0d8be 100644
--- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -181,21 +181,24 @@ EmulateInstructionARM::GetPluginDescriptionStatic ()
}
EmulateInstruction *
-EmulateInstructionARM::CreateInstance (const ArchSpec &arch)
+EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
{
- if (arch.GetTriple().getArch() == llvm::Triple::arm)
- {
- std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
-
- if (emulate_insn_ap.get())
- return emulate_insn_ap.release();
- }
- else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
+ if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type))
{
- std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
-
- if (emulate_insn_ap.get())
- return emulate_insn_ap.release();
+ if (arch.GetTriple().getArch() == llvm::Triple::arm)
+ {
+ std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
+
+ if (emulate_insn_ap.get())
+ return emulate_insn_ap.release();
+ }
+ else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
+ {
+ std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
+
+ if (emulate_insn_ap.get())
+ return emulate_insn_ap.release();
+ }
}
return NULL;
@@ -340,7 +343,7 @@ EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding enc
Register dwarf_reg;
dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
Register sp_reg;
- sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
+ sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
for (i=0; i<15; ++i)
{
if (BitIsSet (registers, i))
@@ -1247,7 +1250,7 @@ EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding
EmulateInstruction::Context context;
context.type = EmulateInstruction::eContextAdjustStackPointer;
Register sp_reg;
- sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
+ sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
context.SetRegisterPlusOffset (sp_reg, sp_offset);
if (d == 15)
@@ -1312,7 +1315,7 @@ EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding
EmulateInstruction::Context context;
context.type = EmulateInstruction::eContextAddition;
Register sp_reg;
- sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
+ sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
Register other_reg;
other_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
context.SetRegisterRegisterOperands (sp_reg, other_reg);
@@ -1849,7 +1852,7 @@ EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding
EmulateInstruction::Context context;
context.type = EmulateInstruction::eContextPushRegisterOnStack;
Register sp_reg;
- sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
+ sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
context.SetRegisterPlusOffset (sp_reg, addr - sp);
if (Rt != 15)
{
@@ -1952,7 +1955,7 @@ EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding en
Register dwarf_reg;
dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
Register sp_reg;
- sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
+ sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
for (i=0; i<regs; ++i)
{
dwarf_reg.num = start_reg + d + i;
@@ -2047,7 +2050,7 @@ EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding enc
Register dwarf_reg;
dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
Register sp_reg;
- sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
+ sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
for (i=0; i<regs; ++i)
{
dwarf_reg.num = start_reg + d + i;
@@ -9330,7 +9333,7 @@ EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding
EmulateInstruction::Context context;
context.type = eContextSubtraction;
Register sp_reg;
- sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
+ sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
Register dwarf_reg;
dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
@@ -10604,7 +10607,7 @@ EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding enc
// // Combine the word-aligned words in the correct order for current endianness.
// D[d+r] = if BigEndian() then word1:word2 else word2:word1;
uint64_t data;
- if (m_byte_order == eByteOrderBig)
+ if (GetByteOrder() == eByteOrderBig)
{
data = word1;
data = (data << 32) | word2;
@@ -10791,7 +10794,7 @@ EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding enc
data_reg.num = start_reg + d + r;
- if (m_byte_order == eByteOrderBig)
+ if (GetByteOrder() == eByteOrderBig)
{
context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
@@ -10931,7 +10934,7 @@ EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
// // Combine the word-aligned words in the correct order for current endianness.
// D[d] = if BigEndian() then word1:word2 else word2:word1;
uint64_t data64;
- if (m_byte_order == eByteOrderBig)
+ if (GetByteOrder() == eByteOrderBig)
{
data64 = word1;
data64 = (data64 << 32) | word2;
@@ -11059,7 +11062,7 @@ EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
if (!success)
return false;
- if (m_byte_order == eByteOrderBig)
+ if (GetByteOrder() == eByteOrderBig)
{
if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
return false;
@@ -12064,7 +12067,7 @@ EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncod
}
EmulateInstructionARM::ARMOpcode*
-EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode)
+EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
{
static ARMOpcode
g_arm_opcodes[] =
@@ -12289,7 +12292,8 @@ EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode)
for (size_t i=0; i<k_num_arm_opcodes; ++i)
{
- if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value)
+ if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
+ (g_arm_opcodes[i].variants & arm_isa) != 0)
return &g_arm_opcodes[i];
}
return NULL;
@@ -12297,7 +12301,7 @@ EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode)
EmulateInstructionARM::ARMOpcode*
-EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode)
+EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
{
static ARMOpcode
@@ -12607,7 +12611,8 @@ EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode)
const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
for (size_t i=0; i<k_num_thumb_opcodes; ++i)
{
- if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value)
+ if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
+ (g_thumb_opcodes[i].variants & arm_isa) != 0)
return &g_thumb_opcodes[i];
}
return NULL;
@@ -12636,24 +12641,30 @@ EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
}
bool
-EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr)
+EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
{
- m_opcode = insn_opcode;
+ if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
+ {
+ if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
+ m_opcode_mode = eModeThumb;
+ else
+ {
+ AddressClass addr_class = inst_addr.GetAddressClass();
- if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
- m_opcode_mode = eModeThumb;
- else
- {
- AddressClass addr_class = inst_addr.GetAddressClass();
-
- if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
- m_opcode_mode = eModeARM;
- else if (addr_class == eAddressClassCodeAlternateISA)
- m_opcode_mode = eModeThumb;
- else
- return false;
- }
- return true;
+ if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
+ m_opcode_mode = eModeARM;
+ else if (addr_class == eAddressClassCodeAlternateISA)
+ m_opcode_mode = eModeThumb;
+ else
+ return false;
+ }
+ if (m_opcode_mode == eModeThumb)
+ m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
+ else
+ m_opcode_cpsr = CPSR_MODE_USR;
+ return true;
+ }
+ return false;
}
bool
@@ -12711,6 +12722,12 @@ EmulateInstructionARM::ArchVersion ()
bool
EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
{
+ // If we are ignoring conditions, then always return true.
+ // this allows us to iterate over disassembly code and still
+ // emulate an instruction even if we don't have all the right
+ // bits set in the CPSR register...
+ if (m_ignore_conditions)
+ return true;
const uint32_t cond = CurrentCond (opcode);
@@ -12855,7 +12872,7 @@ EmulateInstructionARM::CurrentModeIsPrivileged ()
return false;
if (mode == 16)
- return false;
+ return false;
return true;
}
@@ -13188,123 +13205,72 @@ EmulateInstructionARM::WriteFlags (Context &context,
}
bool
-EmulateInstructionARM::EvaluateInstruction ()
+EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
{
// Advance the ITSTATE bits to their values for the next instruction.
if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
m_it_session.ITAdvance();
-
- ARMOpcode *opcode_data;
+ ARMOpcode *opcode_data = NULL;
if (m_opcode_mode == eModeThumb)
- opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32());
+ opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
else if (m_opcode_mode == eModeARM)
- opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32());
- else
- return false;
+ opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
- if (!opcode_data)
+ if (opcode_data == NULL)
return false;
- // Verify that we're the right arch for this opcode
- switch (m_arm_isa)
+ const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
+ m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
+
+ bool success = false;
+ if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
{
- case ARMv4:
- if (opcode_data->variants != ARMvAll)
- return false;
- break;
-
- case ARMv4T:
- if ((opcode_data->variants!= ARMvAll)
- && (opcode_data->variants != ARMV4T_ABOVE))
- return false;
- break;
-
- case ARMv5T:
- case ARMv5TE:
- if ((opcode_data->variants != ARMvAll)
- && (opcode_data->variants != ARMV4T_ABOVE)
- && (opcode_data->variants != ARMV5_ABOVE))
- return false;
- break;
-
- case ARMv5TEJ:
- if ((opcode_data->variants != ARMvAll)
- && (opcode_data->variants != ARMV4T_ABOVE)
- && (opcode_data->variants != ARMV5_ABOVE)
- && (opcode_data->variants != ARMV5J_ABOVE))
- return false;
- break;
-
- case ARMv6:
- case ARMv6K:
- if ((opcode_data->variants != ARMvAll)
- && (opcode_data->variants != ARMV4T_ABOVE)
- && (opcode_data->variants != ARMV5_ABOVE)
- && (opcode_data->variants != ARMV5J_ABOVE)
- && (opcode_data->variants != ARMV6_ABOVE))
- return false;
- break;
-
- case ARMv6T2:
- case ARMv7:
- case ARMv8:
- if ((opcode_data->variants != ARMvAll)
- && (opcode_data->variants != ARMV4T_ABOVE)
- && (opcode_data->variants != ARMV5_ABOVE)
- && (opcode_data->variants != ARMV5J_ABOVE)
- && (opcode_data->variants != ARMV6_ABOVE)
- && (opcode_data->variants != ARMV6T2_ABOVE))
- return false;
- break;
-
- default:
-// if (opcode_data->variants != ARMvAll)
-// return false;
- break;
+ m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
+ dwarf_cpsr,
+ 0,
+ &success);
}
+
+ // Only return false if we are unable to read the CPSR if we care about conditions
+ if (success == false && m_ignore_conditions == false)
+ return false;
- // Just for now, for testing purposes.
- if (m_baton == NULL)
- fprintf (stdout, "\nEvaluateInstruction, opcode (0x%x), found = '%s'\n", m_opcode.GetOpcode32(),
- opcode_data->name);
-
- bool success;
- if (m_baton)
+ uint32_t orig_pc_value = 0;
+ if (auto_advance_pc)
{
- uint32_t cpsr_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
- if (success)
- m_opcode_cpsr = cpsr_value;
+ orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
+ if (!success)
+ return false;
}
- uint32_t orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
- if (!success)
- return false;
-
- success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); // Call the Emulate... function.
- if (!success)
- return false;
-
- uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
+ // Call the Emulate... function.
+ success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
if (!success)
return false;
- if (m_advance_pc && (after_pc_value == orig_pc_value))
+ if (auto_advance_pc)
{
- if (opcode_data->size == eSize32)
- after_pc_value += 4;
- else if (opcode_data->size == eSize16)
- after_pc_value += 2;
-
- EmulateInstruction::Context context;
- context.type = eContextAdvancePC;
- context.SetNoArgs();
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
+ uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
+ if (!success)
return false;
+ if (auto_advance_pc && (after_pc_value == orig_pc_value))
+ {
+ if (opcode_data->size == eSize32)
+ after_pc_value += 4;
+ else if (opcode_data->size == eSize16)
+ after_pc_value += 2;
+
+ EmulateInstruction::Context context;
+ context.type = eContextAdvancePC;
+ context.SetNoArgs();
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
+ return false;
+
+ }
}
-
return true;
}
@@ -13331,10 +13297,6 @@ EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, Option
}
test_opcode = value_sp->GetUInt64Value ();
- // If the instruction emulation does not directly update the PC, advance the PC to the next instruction after
- // performing the emulation.
- SetAdvancePC (true);
-
if (arch.GetTriple().getArch() == llvm::Triple::arm)
{
m_opcode_mode = eModeARM;
@@ -13392,7 +13354,7 @@ EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, Option
&EmulationStateARM::ReadPseudoRegister,
&EmulationStateARM::WritePseudoRegister);
- bool success = EvaluateInstruction ();
+ bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
if (!success)
{
out_stream->Printf ("TestEmulation: EvaluateInstruction() failed.\n");
@@ -13406,3 +13368,26 @@ EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, Option
return success;
}
+
+const char *
+EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
+{
+ if (reg_kind == eRegisterKindGeneric)
+ {
+ switch (reg_num)
+ {
+ case LLDB_REGNUM_GENERIC_PC: return "pc";
+ case LLDB_REGNUM_GENERIC_SP: return "sp";
+ case LLDB_REGNUM_GENERIC_FP: return "fp";
+ case LLDB_REGNUM_GENERIC_RA: return "lr";
+ case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
+ default: return NULL;
+ }
+ }
+ else if (reg_kind == eRegisterKindDWARF)
+ {
+ return GetARMDWARFRegisterName (reg_num);
+ }
+ return NULL;
+}
+
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
index faaae730680..bb7b7c23b3b 100644
--- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
+++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
@@ -75,8 +75,28 @@ public:
GetPluginDescriptionStatic ();
static lldb_private::EmulateInstruction *
- CreateInstance (const lldb_private::ArchSpec &arch);
+ CreateInstance (const lldb_private::ArchSpec &arch,
+ InstructionType inst_type);
+ static bool
+ SupportsEmulatingIntructionsOfTypeStatic (InstructionType inst_type)
+ {
+ switch (inst_type)
+ {
+ case eInstructionTypeAny:
+ case eInstructionTypePrologueEpilogue:
+ case eInstructionTypePCModifying:
+ return true;
+
+ case eInstructionTypeAll:
+ return false;
+
+ default:
+ break;
+ }
+ return false;
+ }
+
virtual const char *
GetPluginName()
{
@@ -106,38 +126,43 @@ public:
};
EmulateInstructionARM (const ArchSpec &arch) :
- EmulateInstruction (lldb::eByteOrderLittle,
- 4,
- arch),
+ EmulateInstruction (arch),
m_arm_isa (0),
m_opcode_mode (eModeInvalid),
m_opcode_cpsr (0),
- m_it_session ()
+ m_it_session (),
+ m_ignore_conditions (false)
{
+ SetArchitecture (arch);
}
- EmulateInstructionARM (const ArchSpec &arch,
- void *baton,
- ReadMemory read_mem_callback,
- WriteMemory write_mem_callback,
- ReadRegister read_reg_callback,
- WriteRegister write_reg_callback) :
- EmulateInstruction (lldb::eByteOrderLittle, // Byte order for ARM
- 4, // Address size in byte
- arch,
- baton,
- read_mem_callback,
- write_mem_callback,
- read_reg_callback,
- write_reg_callback),
- m_arm_isa (0),
- m_opcode_mode (eModeInvalid),
- m_opcode_cpsr (0),
- m_it_session ()
+// EmulateInstructionARM (const ArchSpec &arch,
+// bool ignore_conditions,
+// void *baton,
+// ReadMemory read_mem_callback,
+// WriteMemory write_mem_callback,
+// ReadRegister read_reg_callback,
+// WriteRegister write_reg_callback) :
+// EmulateInstruction (arch,
+// ignore_conditions,
+// baton,
+// read_mem_callback,
+// write_mem_callback,
+// read_reg_callback,
+// write_reg_callback),
+// m_arm_isa (0),
+// m_opcode_mode (eModeInvalid),
+// m_opcode_cpsr (0),
+// m_it_session ()
+// {
+// }
+
+ virtual bool
+ SupportsEmulatingIntructionsOfType (InstructionType inst_type)
{
+ return SupportsEmulatingIntructionsOfTypeStatic (inst_type);
}
-
-
+
virtual bool
SetArchitecture (const ArchSpec &arch);
@@ -145,14 +170,17 @@ public:
ReadInstruction ();
virtual bool
- SetInstruction (const Opcode &insn_opcode, const Address &inst_addr);
+ SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target);
virtual bool
- EvaluateInstruction ();
+ EvaluateInstruction (uint32_t evaluate_options);
virtual bool
TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data);
+ virtual const char *
+ GetRegisterName (uint32_t reg_kind, uint32_t reg_num);
+
uint32_t
ArchVersion();
@@ -340,10 +368,10 @@ protected:
static ARMOpcode*
- GetARMOpcodeForInstruction (const uint32_t opcode);
+ GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t isa_mask);
static ARMOpcode*
- GetThumbOpcodeForInstruction (const uint32_t opcode);
+ GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t isa_mask);
// A8.6.123 PUSH
bool
@@ -948,6 +976,7 @@ protected:
uint32_t m_opcode_cpsr;
uint32_t m_new_inst_cpsr; // This can get updated by the opcode.
ITSession m_it_session;
+ bool m_ignore_conditions;
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
index 7fb65a495be..72fc484e0d9 100644
--- a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
+++ b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
@@ -187,11 +187,12 @@ EmulationStateARM::ReadFromPseudoAddress (lldb::addr_t p_address, uint32_t size,
}
size_t
-EmulationStateARM::ReadPseudoMemory (void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr,
- void *dst,
- size_t length)
+EmulationStateARM::ReadPseudoMemory (EmulateInstruction *instruction,
+ void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr,
+ void *dst,
+ size_t length)
{
if (!baton)
return 0;
@@ -230,11 +231,12 @@ EmulationStateARM::ReadPseudoMemory (void *baton,
}
size_t
-EmulationStateARM::WritePseudoMemory (void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr,
- const void *dst,
- size_t length)
+EmulationStateARM::WritePseudoMemory (EmulateInstruction *instruction,
+ void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr,
+ const void *dst,
+ size_t length)
{
if (!baton)
return 0;
@@ -250,10 +252,11 @@ EmulationStateARM::WritePseudoMemory (void *baton,
}
bool
-EmulationStateARM::ReadPseudoRegister (void *baton,
- uint32_t reg_kind,
- uint32_t reg_num,
- uint64_t &reg_value)
+EmulationStateARM::ReadPseudoRegister (EmulateInstruction *instruction,
+ void *baton,
+ uint32_t reg_kind,
+ uint32_t reg_num,
+ uint64_t &reg_value)
{
if (!baton)
return false;
@@ -284,11 +287,12 @@ EmulationStateARM::ReadPseudoRegister (void *baton,
}
bool
-EmulationStateARM::WritePseudoRegister (void *baton,
- const EmulateInstruction::Context &context,
- uint32_t reg_kind,
- uint32_t reg_num,
- uint64_t reg_value)
+EmulationStateARM::WritePseudoRegister (EmulateInstruction *instruction,
+ void *baton,
+ const EmulateInstruction::Context &context,
+ uint32_t reg_kind,
+ uint32_t reg_num,
+ uint64_t reg_value)
{
if (!baton)
return false;
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
index 025ff9e3d94..1dcc680f973 100644
--- a/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
+++ b/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h
@@ -16,8 +16,6 @@
#include "lldb/Core/Opcode.h"
#include "lldb/Interpreter/NamedOptionValue.h"
-namespace lldb_private {
-
class EmulationStateARM {
public:
@@ -45,37 +43,41 @@ public:
ClearPseudoMemory ();
bool
- LoadPseudoRegistersFromFrame (StackFrame &frame);
+ LoadPseudoRegistersFromFrame (lldb_private::StackFrame &frame);
bool
- LoadStateFromDictionary (OptionValueDictionary *test_data);
+ LoadStateFromDictionary (lldb_private::OptionValueDictionary *test_data);
bool
CompareState (EmulationStateARM &other_state);
static size_t
- ReadPseudoMemory (void *baton,
- const EmulateInstruction::Context &context,
+ ReadPseudoMemory (lldb_private::EmulateInstruction *instruction,
+ void *baton,
+ const lldb_private::EmulateInstruction::Context &context,
lldb::addr_t addr,
void *dst,
size_t length);
static size_t
- WritePseudoMemory (void *baton,
- const EmulateInstruction::Context &context,
+ WritePseudoMemory (lldb_private::EmulateInstruction *instruction,
+ void *baton,
+ const lldb_private::EmulateInstruction::Context &context,
lldb::addr_t addr,
const void *dst,
size_t length);
static bool
- ReadPseudoRegister (void *baton,
+ ReadPseudoRegister (lldb_private::EmulateInstruction *instruction,
+ void *baton,
uint32_t reg_kind,
uint32_t reg_num,
uint64_t &reg_value);
static bool
- WritePseudoRegister (void *baton,
- const EmulateInstruction::Context &context,
+ WritePseudoRegister (lldb_private::EmulateInstruction *instruction,
+ void *baton,
+ const lldb_private::EmulateInstruction::Context &context,
uint32_t reg_kind,
uint32_t reg_num,
uint64_t reg_value);
@@ -97,7 +99,5 @@ private:
DISALLOW_COPY_AND_ASSIGN (EmulationStateARM);
};
-
-} // namespace lldb_private
#endif // lldb_EmulationStateARM_h_
diff --git a/lldb/source/Plugins/Process/Utility/ARMDefines.h b/lldb/source/Plugins/Process/Utility/ARMDefines.h
index 0ef8c61449a..3cc9d4674c3 100644
--- a/lldb/source/Plugins/Process/Utility/ARMDefines.h
+++ b/lldb/source/Plugins/Process/Utility/ARMDefines.h
@@ -79,6 +79,15 @@ static inline const char *ARMCondCodeToString(uint32_t CC)
#define CPSR_Z_POS 30
#define CPSR_N_POS 31
+// CPSR mode definitions
+#define CPSR_MODE_USR 0x10u
+#define CPSR_MODE_FIQ 0x11u
+#define CPSR_MODE_IRQ 0x12u
+#define CPSR_MODE_SVC 0x13u
+#define CPSR_MODE_ABT 0x17u
+#define CPSR_MODE_UND 0x1bu
+#define CPSR_MODE_SYS 0x1fu
+
// Masks for CPSR
#define MASK_CPSR_MODE_MASK (0x0000001fu)
#define MASK_CPSR_T (1u << CPSR_T_POS)
diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 351b6eb2bc9..3e9cef34c19 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -143,16 +143,21 @@ ThreadGDBRemote::GetUnwinder ()
{
const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ());
const llvm::Triple::ArchType machine = target_arch.GetMachine();
- if (machine == llvm::Triple::x86_64 || machine == llvm::Triple::x86)
+ switch (machine)
{
- m_unwinder_ap.reset (new UnwindLLDB (*this));
- }
+ case llvm::Triple::x86_64:
+ case llvm::Triple::x86:
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ m_unwinder_ap.reset (new UnwindLLDB (*this));
+ break;
+
+ default:
#if defined(__APPLE__)
- else
- {
- m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this));
- }
+ m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this));
#endif
+ break;
+ }
}
return m_unwinder_ap.get();
}
diff --git a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
index 1379cd4ce12..d9855b7c788 100644
--- a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
+++ b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
@@ -12,16 +12,16 @@
#include "llvm-c/EnhancedDisassembly.h"
#include "lldb/Core/Address.h"
-#include "lldb/Core/Error.h"
#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Disassembler.h"
+#include "lldb/Core/Error.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Core/StreamFile.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
-#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/Target.h"
-#include "lldb/Target/UnwindAssembly.h"
using namespace lldb;
using namespace lldb_private;
@@ -33,19 +33,108 @@ using namespace lldb_private;
//-----------------------------------------------------------------------------------------------
bool
-UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan)
+UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& range,
+ Thread& thread,
+ UnwindPlan& unwind_plan)
{
+#if 0
+ UnwindPlan::Row row;
+ UnwindPlan::Row::RegisterLocation regloc;
+
+ m_unwind_plan_sp->SetRegisterKind (eRegisterKindGeneric);
+ row.SetCFARegister (LLDB_REGNUM_GENERIC_FP);
+ row.SetCFAOffset (2 * 8);
+ row.SetOffset (0);
+
+ regloc.SetAtCFAPlusOffset (2 * -8);
+ row.SetRegisterInfo (LLDB_REGNUM_GENERIC_FP, regloc);
+ regloc.SetAtCFAPlusOffset (1 * -8);
+ row.SetRegisterInfo (LLDB_REGNUM_GENERIC_PC, regloc);
+ regloc.SetIsCFAPlusOffset (0);
+ row.SetRegisterInfo (LLDB_REGNUM_GENERIC_SP, regloc);
+
+ m_unwind_plan_sp->AppendRow (row);
+ m_unwind_plan_sp->SetSourceName ("x86_64 architectural default");
+#endif
+
+ if (range.GetByteSize() > 0 &&
+ range.GetBaseAddress().IsValid() &&
+ m_inst_emulator_ap.get())
+ {
+#if 0
+ Target &target = thread.GetProcess().GetTarget();
+ const ArchSpec &target_arch = target.GetArchitecture();
+ bool prefer_file_cache = true;
+ Error error;
+ DataBufferHeap data_buffer (range.GetByteSize(), 0);
+ if (target.ReadMemory (range.GetBaseAddress(),
+ prefer_file_cache,
+ data_buffer.GetBytes(),
+ data_buffer.GetByteSize(),
+ error) == data_buffer.GetByteSize())
+ {
+ DataExtractor data (data_buffer.GetBytes(),
+ data_buffer.GetByteSize(),
+ target_arch.GetByteOrder(),
+ target_arch.GetAddressByteSize());
+ }
+#endif
+ StreamFile strm (stdout, false);
+
+ ExecutionContext exe_ctx;
+ thread.CalculateExecutionContext(exe_ctx);
+ DisassemblerSP disasm_sp (Disassembler::DisassembleRange (m_arch,
+ NULL,
+ exe_ctx,
+ range));
+ if (disasm_sp)
+ {
+
+ m_range_ptr = &range;
+ m_thread_ptr = &thread;
+ m_unwind_plan_ptr = &unwind_plan;
+
+ const uint32_t addr_byte_size = m_arch.GetAddressByteSize();
+ const bool show_address = true;
+ const bool show_bytes = true;
+ const bool raw = false;
+ // Initialize the stack pointer with a known value. In the 32 bit case
+ // it will be 0x80000000, and in the 64 bit case 0x8000000000000000.
+ // We use the address byte size to be safe for any future addresss sizes
+ SetRegisterValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, (1ull << ((addr_byte_size * 8) - 1)));
+
+ const InstructionList &inst_list = disasm_sp->GetInstructionList ();
+ const size_t num_instructions = inst_list.GetSize();
+ for (size_t idx=0; idx<num_instructions; ++idx)
+ {
+ Instruction *inst = inst_list.GetInstructionAtIndex (idx).get();
+ if (inst)
+ {
+ inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, &exe_ctx, raw);
+ strm.EOL();
+
+ m_inst_emulator_ap->SetInstruction (inst->GetOpcode(), inst->GetAddress(), exe_ctx.target);
+ m_inst_emulator_ap->EvaluateInstruction (eEmulateInstructionOptionIgnoreConditions);
+ }
+ }
+ }
+ }
return false;
}
bool
-UnwindAssemblyInstEmulation::GetFastUnwindPlan (AddressRange& func, Thread& thread, UnwindPlan &unwind_plan)
+UnwindAssemblyInstEmulation::GetFastUnwindPlan (AddressRange& func,
+ Thread& thread,
+ UnwindPlan &unwind_plan)
{
return false;
}
bool
-UnwindAssemblyInstEmulation::FirstNonPrologueInsn (AddressRange& func, Target& target, Thread* thread, Address& first_non_prologue_insn)
+UnwindAssemblyInstEmulation::FirstNonPrologueInsn (AddressRange& func,
+ Target& target,
+ Thread* thread,
+ Address& first_non_prologue_insn)
{
return false;
}
@@ -53,6 +142,10 @@ UnwindAssemblyInstEmulation::FirstNonPrologueInsn (AddressRange& func, Target& t
UnwindAssembly *
UnwindAssemblyInstEmulation::CreateInstance (const ArchSpec &arch)
{
+ std::auto_ptr<lldb_private::EmulateInstruction> inst_emulator_ap (EmulateInstruction::FindPlugin (arch, eInstructionTypePrologueEpilogue, NULL));
+ // Make sure that all prologue instructions are handled
+ if (inst_emulator_ap.get())
+ return new UnwindAssemblyInstEmulation (arch, inst_emulator_ap.release());
return NULL;
}
@@ -106,3 +199,120 @@ UnwindAssemblyInstEmulation::GetPluginDescriptionStatic()
{
return "Instruction emulation based unwind information.";
}
+
+
+
+size_t
+UnwindAssemblyInstEmulation::ReadMemory (EmulateInstruction *instruction,
+ void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr,
+ void *dst,
+ size_t dst_len)
+{
+ //UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton;
+ printf ("UnwindAssemblyInstEmulation::ReadMemory (context.type = %i, context.info_type = %i, addr = 0x%16.16llx, dst = %p, dst_len = %zu)\n",
+ context.type,
+ context.info_type,
+ addr,
+ dst,
+ dst_len);
+ return dst_len;
+}
+
+size_t
+UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction,
+ void *baton,
+ const EmulateInstruction::Context &context,
+ lldb::addr_t addr,
+ const void *dst,
+ size_t dst_len)
+{
+ // UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton;
+
+ DataExtractor data (dst,
+ dst_len,
+ instruction->GetArchitecture ().GetByteOrder(),
+ instruction->GetArchitecture ().GetAddressByteSize());
+ StreamFile strm(stdout, false);
+
+ strm.Printf ("UnwindAssemblyInstEmulation::WriteMemory (context.type = %i, context.info_type = %i, ",
+ context.type,
+ context.info_type);
+ data.Dump(&strm, 0, eFormatBytes, 1, dst_len, UINT32_MAX, addr, 0, 0);
+ strm.EOL();
+ return dst_len;
+}
+
+bool
+UnwindAssemblyInstEmulation::ReadRegister (EmulateInstruction *instruction,
+ void *baton,
+ uint32_t reg_kind,
+ uint32_t reg_num,
+ uint64_t &reg_value)
+{
+ UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton;
+ const char *reg_name = instruction->GetRegisterName (reg_kind, reg_num);
+
+ reg_value = inst_emulator->GetRegisterValue (reg_kind, reg_num);
+
+ printf ("UnwindAssemblyInstEmulation::ReadRegister (name = \"%s\") => value = 0x%16.16llx\n", reg_name, reg_value);
+
+ return true;
+}
+
+bool
+UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
+ void *baton,
+ const EmulateInstruction::Context &context,
+ uint32_t reg_kind,
+ uint32_t reg_num,
+ uint64_t reg_value)
+{
+ UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton;
+ const char *reg_name = instruction->GetRegisterName (reg_kind, reg_num);
+
+ printf ("UnwindAssemblyInstEmulation::WriteRegister (name = \"%s\", value = 0x%16.16llx, context.type = %i, context.info_type = %i)\n",
+ reg_name,
+ reg_value,
+ context.type,
+ context.info_type);
+
+ inst_emulator->SetRegisterValue (reg_kind, reg_num, reg_value);
+
+ switch (context.type)
+ {
+ case EmulateInstruction::eContextInvalid:
+ case EmulateInstruction::eContextReadOpcode:
+ case EmulateInstruction::eContextImmediate:
+ case EmulateInstruction::eContextAdjustBaseRegister:
+ case EmulateInstruction::eContextRegisterPlusOffset:
+ case EmulateInstruction::eContextAdjustPC:
+ case EmulateInstruction::eContextRegisterStore:
+ case EmulateInstruction::eContextRegisterLoad:
+ case EmulateInstruction::eContextRelativeBranchImmediate:
+ case EmulateInstruction::eContextAbsoluteBranchRegister:
+ case EmulateInstruction::eContextSupervisorCall:
+ case EmulateInstruction::eContextTableBranchReadMemory:
+ case EmulateInstruction::eContextWriteRegisterRandomBits:
+ case EmulateInstruction::eContextWriteMemoryRandomBits:
+ case EmulateInstruction::eContextMultiplication:
+ case EmulateInstruction::eContextAddition:
+ case EmulateInstruction::eContextSubtraction:
+ case EmulateInstruction::eContextAdvancePC:
+ case EmulateInstruction::eContextReturnFromException:
+ break;
+
+ case EmulateInstruction::eContextPushRegisterOnStack:
+ break;
+
+ case EmulateInstruction::eContextPopRegisterOffStack:
+ break;
+
+ case EmulateInstruction::eContextAdjustStackPointer:
+ break;
+ }
+ return true;
+}
+
+
diff --git a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
index f6137389c95..c18cbabdfa7 100644
--- a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
+++ b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
@@ -11,8 +11,8 @@
#define liblldb_UnwindAssemblyInstEmulation_h_
#include "lldb/lldb-private.h"
+#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Target/UnwindAssembly.h"
-#include "lldb/Target/Thread.h"
class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly
{
@@ -43,7 +43,6 @@ public:
static lldb_private::UnwindAssembly *
CreateInstance (const lldb_private::ArchSpec &arch);
-
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
@@ -69,14 +68,83 @@ public:
GetPluginVersion();
private:
+
+ static size_t
+ ReadMemory (lldb_private::EmulateInstruction *instruction,
+ void *baton,
+ const lldb_private::EmulateInstruction::Context &context,
+ lldb::addr_t addr,
+ void *dst,
+ size_t length);
+
+ static size_t
+ WriteMemory (lldb_private::EmulateInstruction *instruction,
+ void *baton,
+ const lldb_private::EmulateInstruction::Context &context,
+ lldb::addr_t addr,
+ const void *dst,
+ size_t length);
+
+ static bool
+ ReadRegister (lldb_private::EmulateInstruction *instruction,
+ void *baton,
+ uint32_t reg_kind,
+ uint32_t reg_num,
+ uint64_t &reg_value);
+
+ static bool
+ WriteRegister (lldb_private::EmulateInstruction *instruction,
+ void *baton,
+ const lldb_private::EmulateInstruction::Context &context,
+ uint32_t reg_kind,
+ uint32_t reg_num,
+ uint64_t reg_value);
+
// Call CreateInstance to get an instance of this class
- UnwindAssemblyInstEmulation(int cpu) :
- lldb_private::UnwindAssembly(), m_cpu(cpu)
+ UnwindAssemblyInstEmulation (const lldb_private::ArchSpec &arch,
+ lldb_private::EmulateInstruction *inst_emulator) :
+ UnwindAssembly (arch),
+ m_inst_emulator_ap (inst_emulator),
+ m_range_ptr (NULL),
+ m_thread_ptr (NULL),
+ m_unwind_plan_ptr (NULL)
+ {
+ if (m_inst_emulator_ap.get())
+ {
+ m_inst_emulator_ap->SetBaton (this);
+ m_inst_emulator_ap->SetCallbacks (ReadMemory, WriteMemory, ReadRegister, WriteRegister);
+ }
+ }
+
+ static uint64_t
+ MakeRegisterKindValuePair (uint32_t reg_kind, uint32_t reg_num)
+ {
+ return (uint64_t)reg_kind << 32 | reg_num;
+ }
+
+ void
+ SetRegisterValue (uint32_t reg_kind, uint32_t reg_num, uint64_t reg_value)
+ {
+ m_register_values[MakeRegisterKindValuePair (reg_kind, reg_num)] = reg_value;
+ }
+
+ uint64_t
+ GetRegisterValue (uint32_t reg_kind, uint32_t reg_num)
{
+ const uint64_t reg_id = MakeRegisterKindValuePair (reg_kind, reg_num);
+ RegisterValueMap::const_iterator pos = m_register_values.find(reg_id);
+ if (pos != m_register_values.end())
+ return pos->second;
+ return (uint64_t)reg_kind << 24 | (uint64_t)reg_num;
}
- int m_cpu;
+ std::auto_ptr<lldb_private::EmulateInstruction> m_inst_emulator_ap;
+ lldb_private::AddressRange* m_range_ptr;
+ lldb_private::Thread* m_thread_ptr;
+ lldb_private::UnwindPlan* m_unwind_plan_ptr;
+ typedef std::map<uint64_t, uint64_t> RegisterValueMap;
+ RegisterValueMap m_register_values;
};
#endif // liblldb_UnwindAssemblyInstEmulation_h_
diff --git a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
index 28bb3364243..8382e3ea26f 100644
--- a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
+++ b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
@@ -818,6 +818,17 @@ AssemblyParse_x86::find_first_non_prologue_insn (Address &address)
// UnwindAssemblyParser_x86 method definitions
//-----------------------------------------------------------------------------------------------
+UnwindAssembly_x86::UnwindAssembly_x86 (const ArchSpec &arch, int cpu) :
+ lldb_private::UnwindAssembly(arch),
+ m_cpu(cpu)
+{
+}
+
+
+UnwindAssembly_x86::~UnwindAssembly_x86 ()
+{
+}
+
bool
UnwindAssembly_x86::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, Thread& thread, UnwindPlan& unwind_plan)
{
@@ -844,9 +855,9 @@ UnwindAssembly_x86::CreateInstance (const ArchSpec &arch)
{
const llvm::Triple::ArchType cpu = arch.GetMachine ();
if (cpu == llvm::Triple::x86)
- return new UnwindAssembly_x86 (k_i386);
+ return new UnwindAssembly_x86 (arch, k_i386);
else if (cpu == llvm::Triple::x86_64)
- return new UnwindAssembly_x86 (k_x86_64);
+ return new UnwindAssembly_x86 (arch, k_x86_64);
return NULL;
}
diff --git a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h
index 4c29dcf7b28..f5d039141b2 100644
--- a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h
+++ b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h
@@ -12,25 +12,29 @@
#include "lldb/lldb-private.h"
#include "lldb/Target/UnwindAssembly.h"
-#include "lldb/Target/Thread.h"
-namespace lldb_private {
-
class UnwindAssembly_x86 : public lldb_private::UnwindAssembly
{
public:
- ~UnwindAssembly_x86 () { }
+ ~UnwindAssembly_x86 ();
virtual bool
- GetNonCallSiteUnwindPlanFromAssembly (AddressRange& func, lldb_private::Thread& thread, UnwindPlan& unwind_plan);
+ GetNonCallSiteUnwindPlanFromAssembly (lldb_private::AddressRange& func,
+ lldb_private::Thread& thread,
+ lldb_private::UnwindPlan& unwind_plan);
virtual bool
- GetFastUnwindPlan (AddressRange& func, lldb_private::Thread& thread, UnwindPlan &unwind_plan);
+ GetFastUnwindPlan (lldb_private::AddressRange& func,
+ lldb_private::Thread& thread,
+ lldb_private::UnwindPlan &unwind_plan);
// thread may be NULL in which case we only use the Target (e.g. if this is called pre-process-launch).
virtual bool
- FirstNonPrologueInsn (AddressRange& func, lldb_private::Target& target, lldb_private::Thread* thread, Address& first_non_prologue_insn);
+ FirstNonPrologueInsn (lldb_private::AddressRange& func,
+ lldb_private::Target& target,
+ lldb_private::Thread* thread,
+ lldb_private::Address& first_non_prologue_insn);
static lldb_private::UnwindAssembly *
CreateInstance (const lldb_private::ArchSpec &arch);
@@ -61,13 +65,10 @@ public:
GetPluginVersion();
private:
- UnwindAssembly_x86(int cpu) :
- lldb_private::UnwindAssembly(), m_cpu(cpu) { } // Call CreateInstance instead.
+ UnwindAssembly_x86 (const lldb_private::ArchSpec &arch, int cpu);
int m_cpu;
};
-} // namespace lldb_private
-
#endif // liblldb_UnwindAssembly_x86_h_
OpenPOWER on IntegriCloud