Added the start of the CFI row production using the

emulate instruction classes.

llvm-svn: 130556
This commit is contained in:
Greg Clayton
2011-04-29 22:50:31 +00:00
parent 9a5f84facb
commit e5b3498eef
5 changed files with 110 additions and 22 deletions

View File

@@ -467,6 +467,12 @@ public:
return m_opcode;
}
lldb::addr_t
GetAddress () const
{
return m_addr;
}
const ArchSpec &
GetArchitecture () const
{
@@ -571,7 +577,7 @@ protected:
WriteMemory m_write_mem_callback;
ReadRegister m_read_reg_callback;
WriteRegister m_write_reg_callback;
lldb::addr_t m_opcode_pc;
lldb::addr_t m_addr;
Opcode m_opcode;

View File

@@ -58,7 +58,7 @@ EmulateInstruction::EmulateInstruction (const ArchSpec &arch) :
m_write_mem_callback (&WriteMemoryDefault),
m_read_reg_callback (&ReadRegisterDefault),
m_write_reg_callback (&WriteRegisterDefault),
m_opcode_pc (LLDB_INVALID_ADDRESS)
m_addr (LLDB_INVALID_ADDRESS)
{
::memset (&m_opcode, 0, sizeof (m_opcode));
}
@@ -536,13 +536,13 @@ bool
EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target)
{
m_opcode = opcode;
m_opcode_pc = LLDB_INVALID_ADDRESS;
m_addr = LLDB_INVALID_ADDRESS;
if (inst_addr.IsValid())
{
if (target)
m_opcode_pc = inst_addr.GetLoadAddress (target);
if (m_opcode_pc == LLDB_INVALID_ADDRESS)
m_opcode_pc = inst_addr.GetFileAddress ();
m_addr = inst_addr.GetLoadAddress (target);
if (m_addr == LLDB_INVALID_ADDRESS)
m_addr = inst_addr.GetFileAddress ();
}
return true;
}

View File

@@ -12729,7 +12729,7 @@ EmulateInstructionARM::ReadInstruction ()
if (!success)
{
m_opcode_mode = eModeInvalid;
m_opcode_pc = LLDB_INVALID_ADDRESS;
m_addr = LLDB_INVALID_ADDRESS;
}
return success;
}

View File

@@ -18,7 +18,6 @@
#include "lldb/Core/Error.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
@@ -108,16 +107,27 @@ UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange&
const InstructionList &inst_list = disasm_sp->GetInstructionList ();
const size_t num_instructions = inst_list.GetSize();
for (size_t idx=0; idx<num_instructions; ++idx)
if (num_instructions > 0)
{
Instruction *inst = inst_list.GetInstructionAtIndex (idx).get();
if (inst)
{
inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, &exe_ctx, raw);
strm.EOL();
Instruction *inst = inst_list.GetInstructionAtIndex (0).get();
const addr_t base_addr = inst->GetAddress().GetFileAddress();
m_inst_emulator_ap->SetInstruction (inst->GetOpcode(), inst->GetAddress(), exe_ctx.target);
m_inst_emulator_ap->EvaluateInstruction (eEmulateInstructionOptionIgnoreConditions);
for (size_t idx=0; idx<num_instructions; ++idx)
{
inst = inst_list.GetInstructionAtIndex (idx).get();
if (inst)
{
m_curr_row.Clear();
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_curr_row.SetOffset (inst->GetAddress().GetFileAddress() + inst->GetOpcode().GetByteSize() - base_addr);
m_inst_emulator_ap->EvaluateInstruction (eEmulateInstructionOptionIgnoreConditions);
}
}
}
}
@@ -255,7 +265,7 @@ UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction,
const void *dst,
size_t dst_len)
{
// UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton;
UnwindAssemblyInstEmulation *inst_emulator = (UnwindAssemblyInstEmulation *)baton;
DataExtractor data (dst,
dst_len,
@@ -267,6 +277,53 @@ UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction,
data.Dump(&strm, 0, eFormatBytes, 1, dst_len, UINT32_MAX, addr, 0, 0);
strm.PutCString (", context = ");
context.Dump(stdout, instruction);
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::eContextArithmetic:
case EmulateInstruction::eContextAdvancePC:
case EmulateInstruction::eContextReturnFromException:
case EmulateInstruction::eContextPopRegisterOffStack:
case EmulateInstruction::eContextAdjustStackPointer:
break;
case EmulateInstruction::eContextPushRegisterOnStack:
switch (context.info_type)
{
case EmulateInstruction::eInfoTypeRegisterToRegisterPlusOffset:
{
UnwindPlan::Row::RegisterLocation regloc;
const uint32_t dwarf_reg_num = context.info.RegisterToRegisterPlusOffset.data_reg.kinds[eRegisterKindDWARF];
const addr_t reg_cfa_offset = inst_emulator->m_curr_row.GetCFAOffset() + context.info.RegisterToRegisterPlusOffset.offset;
regloc.SetIsCFAPlusOffset (reg_cfa_offset);
inst_emulator->m_curr_row.SetRegisterInfo (dwarf_reg_num, regloc);
}
break;
default:
assert (!"unhandled case, add code to handle this!");
break;
}
break;
break;
}
return dst_len;
}
@@ -300,8 +357,6 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
inst_emulator->SetRegisterValue (reg_info, reg_value);
UnwindPlan::Row::RegisterLocation regloc;
switch (context.type)
{
case EmulateInstruction::eContextInvalid:
@@ -321,15 +376,40 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
case EmulateInstruction::eContextArithmetic:
case EmulateInstruction::eContextAdvancePC:
case EmulateInstruction::eContextReturnFromException:
break;
case EmulateInstruction::eContextPushRegisterOnStack:
break;
case EmulateInstruction::eContextPopRegisterOffStack:
{
switch (context.info_type)
{
case EmulateInstruction::eInfoTypeRegisterPlusOffset:
{
const uint32_t dwarf_reg_num = reg_info.kinds[eRegisterKindDWARF];
UnwindPlan::Row::RegisterLocation regloc;
regloc.SetSame();
inst_emulator->m_curr_row.SetRegisterInfo (dwarf_reg_num, regloc);
}
break;
default:
assert (!"unhandled case, add code to handle this!");
break;
}
}
break;
case EmulateInstruction::eContextAdjustStackPointer:
switch (context.info_type)
{
case EmulateInstruction::eInfoTypeImmediateSigned:
inst_emulator->m_curr_row.SetCFAOffset (inst_emulator->m_curr_row.GetCFAOffset() + context.info.signed_immediate);
break;
default:
assert (!"unhandled case, add code to handle this!");
break;
}
break;
}
return true;

View File

@@ -12,6 +12,7 @@
#include "lldb/lldb-private.h"
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/UnwindAssembly.h"
class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly
@@ -128,6 +129,7 @@ private:
lldb_private::AddressRange* m_range_ptr;
lldb_private::Thread* m_thread_ptr;
lldb_private::UnwindPlan* m_unwind_plan_ptr;
lldb_private::UnwindPlan::Row m_curr_row;
typedef std::map<uint64_t, uint64_t> RegisterValueMap;
RegisterValueMap m_register_values;
};