Switch nearly all of the use of the UnwindPlan::Row's to go through

a shared pointer to ease some memory management issues with a patch
I'm working on.

The main complication with using SPs for these objects is that most
methods that build up an UnwindPlan will construct a Row to a given
instruction point in a function, then add additional regsaves in
the next instruction point to that row and push it again.  A little
care is needed to not mutate the previous instruction point's Row
once these are switched to being held behing shared pointers.

llvm-svn: 160214
This commit is contained in:
Jason Molenda 2012-07-14 04:52:53 +00:00
parent 64e1d4abc7
commit 1d42c7bc32
11 changed files with 198 additions and 138 deletions

View File

@ -240,6 +240,15 @@ public:
public:
Row ();
Row (const UnwindPlan::Row& rhs) :
m_offset(rhs.m_offset), m_cfa_reg_num(rhs.m_cfa_reg_num), m_cfa_offset(rhs.m_cfa_offset)
{
for (collection::const_iterator idx = rhs.m_register_locations.begin(); idx != rhs.m_register_locations.end(); ++idx)
{
m_register_locations[idx->first] = idx->second;
}
}
bool
GetRegisterInfo (uint32_t reg_num, RegisterLocation& register_location) const;
@ -360,6 +369,8 @@ public:
public:
typedef STD_SHARED_PTR(Row) RowSP;
UnwindPlan (lldb::RegisterKind reg_kind) :
m_row_list (),
m_plan_valid_address_range (),
@ -376,13 +387,13 @@ public:
Dump (Stream& s, Thread* thread, lldb::addr_t base_addr) const;
void
AppendRow (const Row& row);
AppendRow (RowSP row);
// Returns a pointer to the best row for the given offset into the function's instructions.
// If offset is -1 it indicates that the function start is unknown - the final row in the UnwindPlan is returned.
// In practice, the UnwindPlan for a function with no known start address will be the architectural default
// UnwindPlan which will only have one row.
const Row*
UnwindPlan::RowSP
GetRowForFunctionOffset (int offset) const;
lldb::RegisterKind
@ -402,7 +413,7 @@ public:
{
if (m_row_list.empty())
return LLDB_INVALID_REGNUM;
return m_row_list.front().GetCFARegister();
return m_row_list.front()->GetCFARegister();
}
// This UnwindPlan may not be valid at every address of the function span.
@ -423,10 +434,10 @@ public:
bool
IsValidRowIndex (uint32_t idx) const;
const UnwindPlan::Row&
const UnwindPlan::RowSP
GetRowAtIndex (uint32_t idx) const;
const UnwindPlan::Row&
const UnwindPlan::RowSP
GetLastRow () const;
lldb_private::ConstString
@ -453,7 +464,7 @@ public:
private:
typedef std::vector<Row> collection;
typedef std::vector<RowSP> collection;
collection m_row_list;
AddressRange m_plan_valid_address_range;
lldb::RegisterKind m_register_kind; // The RegisterKind these register numbers are in terms of - will need to be

View File

@ -536,13 +536,13 @@ ABIMacOSX_arm::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
pc_reg_num == LLDB_INVALID_REGNUM)
return false;
UnwindPlan::Row row;
UnwindPlan::RowSP row(new UnwindPlan::Row);
// Our Call Frame Address is the stack pointer value
row.SetCFARegister (sp_reg_num);
row->SetCFARegister (sp_reg_num);
// The previous PC is in the LR
row.SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
unwind_plan.AppendRow (row);
// All other registers are the same.
@ -557,17 +557,17 @@ ABIMacOSX_arm::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
uint32_t fp_reg_num = dwarf_r7; // apple uses r7 for all frames. Normal arm uses r11;
uint32_t pc_reg_num = dwarf_pc;
UnwindPlan::Row row;
UnwindPlan::RowSP row(new UnwindPlan::Row);
const int32_t ptr_size = 4;
unwind_plan.Clear ();
unwind_plan.SetRegisterKind (eRegisterKindDWARF);
row.SetCFARegister (fp_reg_num);
row.SetCFAOffset (2 * ptr_size);
row.SetOffset (0);
row->SetCFARegister (fp_reg_num);
row->SetCFAOffset (2 * ptr_size);
row->SetOffset (0);
row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
unwind_plan.AppendRow (row);
unwind_plan.SetSourceName ("arm-apple-ios default unwind plan");

View File

@ -808,10 +808,10 @@ ABIMacOSX_i386::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
pc_reg_num == LLDB_INVALID_REGNUM)
return false;
UnwindPlan::Row row;
row.SetCFARegister (sp_reg_num);
row.SetCFAOffset (4);
row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
UnwindPlan::RowSP row(new UnwindPlan::Row);
row->SetCFARegister (sp_reg_num);
row->SetCFAOffset (4);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
unwind_plan.AppendRow (row);
unwind_plan.SetSourceName ("i386 at-func-entry default");
return true;
@ -824,18 +824,18 @@ ABIMacOSX_i386::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
uint32_t sp_reg_num = dwarf_esp;
uint32_t pc_reg_num = dwarf_eip;
UnwindPlan::Row row;
UnwindPlan::RowSP row(new UnwindPlan::Row);
const int32_t ptr_size = 4;
unwind_plan.Clear ();
unwind_plan.SetRegisterKind (eRegisterKindDWARF);
row.SetCFARegister (fp_reg_num);
row.SetCFAOffset (2 * ptr_size);
row.SetOffset (0);
row->SetCFARegister (fp_reg_num);
row->SetCFAOffset (2 * ptr_size);
row->SetOffset (0);
row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
row.SetRegisterLocationToAtCFAPlusOffset(sp_reg_num, ptr_size * 0, true);
row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
row->SetRegisterLocationToAtCFAPlusOffset(sp_reg_num, ptr_size * 0, true);
unwind_plan.AppendRow (row);
unwind_plan.SetSourceName ("i386 default unwind plan");

View File

@ -985,10 +985,10 @@ ABISysV_x86_64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
pc_reg_num == LLDB_INVALID_REGNUM)
return false;
UnwindPlan::Row row;
row.SetCFARegister (sp_reg_num);
row.SetCFAOffset (8);
row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
UnwindPlan::RowSP row(new UnwindPlan::Row);
row->SetCFARegister (sp_reg_num);
row->SetCFAOffset (8);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
unwind_plan.AppendRow (row);
unwind_plan.SetSourceName ("x86_64 at-func-entry default");
return true;
@ -1029,16 +1029,16 @@ ABISysV_x86_64::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
pc_reg_num == LLDB_INVALID_REGNUM)
return false;
UnwindPlan::Row row;
UnwindPlan::RowSP row(new UnwindPlan::Row);
const int32_t ptr_size = 8;
row.SetCFARegister (LLDB_REGNUM_GENERIC_FP);
row.SetCFAOffset (2 * ptr_size);
row.SetOffset (0);
row->SetCFARegister (LLDB_REGNUM_GENERIC_FP);
row->SetCFAOffset (2 * ptr_size);
row->SetOffset (0);
row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
row.SetRegisterLocationToAtCFAPlusOffset(sp_reg_num, ptr_size * 0, true);
row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
row->SetRegisterLocationToAtCFAPlusOffset(sp_reg_num, ptr_size * 0, true);
unwind_plan.AppendRow (row);
unwind_plan.SetSourceName ("x86_64 default unwind plan");

View File

@ -13583,13 +13583,13 @@ EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
unwind_plan.Clear();
unwind_plan.SetRegisterKind (eRegisterKindDWARF);
UnwindPlan::Row row;
UnwindPlan::RowSP row(new UnwindPlan::Row);
// Our previous Call Frame Address is the stack pointer
row.SetCFARegister (dwarf_sp);
row->SetCFARegister (dwarf_sp);
// Our previous PC is in the LR
row.SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
unwind_plan.AppendRow (row);
// All other registers are the same.

View File

@ -182,14 +182,14 @@ RegisterContextLLDB::InitializeZerothFrame()
m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame ();
m_full_unwind_plan_sp = GetFullUnwindPlanForFrame ();
const UnwindPlan::Row *active_row = NULL;
UnwindPlan::RowSP active_row;
int cfa_offset = 0;
int row_register_kind;
if (m_full_unwind_plan_sp && m_full_unwind_plan_sp->PlanValidAtAddress (m_current_pc))
{
active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
if (active_row && log)
if (active_row.get() && log)
{
StreamString active_row_strm;
active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
@ -198,7 +198,7 @@ RegisterContextLLDB::InitializeZerothFrame()
}
}
if (active_row == NULL)
if (!active_row.get())
{
m_frame_type = eNotAValidFrame;
return;
@ -356,8 +356,8 @@ RegisterContextLLDB::InitializeNonZerothFrame()
m_current_offset_backed_up_one = -1;
addr_t cfa_regval;
int row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
const UnwindPlan::Row *row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0);
if (row)
UnwindPlan::RowSP row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0);
if (row.get())
{
uint32_t cfa_regnum = row->GetCFARegister();
int cfa_offset = row->GetCFAOffset();
@ -505,7 +505,7 @@ RegisterContextLLDB::InitializeNonZerothFrame()
// We've set m_frame_type and m_sym_ctx before this call.
m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame ();
const UnwindPlan::Row *active_row = NULL;
UnwindPlan::RowSP active_row;
int cfa_offset = 0;
int row_register_kind;
@ -516,7 +516,7 @@ RegisterContextLLDB::InitializeNonZerothFrame()
{
active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind ();
if (active_row && log)
if (active_row.get() && log)
{
StreamString active_row_strm;
active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
@ -531,7 +531,7 @@ RegisterContextLLDB::InitializeNonZerothFrame()
{
active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
if (active_row && log)
if (active_row.get() && log)
{
StreamString active_row_strm;
active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
@ -541,7 +541,7 @@ RegisterContextLLDB::InitializeNonZerothFrame()
}
}
if (active_row == NULL)
if (!active_row.get())
{
m_frame_type = eNotAValidFrame;
return;
@ -1038,7 +1038,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
if (m_fast_unwind_plan_sp)
{
const UnwindPlan::Row *active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
UnwindPlan::RowSP active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind ();
uint32_t row_regnum;
if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum))
@ -1071,7 +1071,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
if (m_full_unwind_plan_sp)
{
const UnwindPlan::Row *active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind ();
uint32_t row_regnum;
if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum))

View File

@ -86,23 +86,29 @@ UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange&
RegisterValue cfa_reg_value;
cfa_reg_value.SetUInt (m_initial_sp, m_cfa_reg_info.byte_size);
SetRegisterValue (m_cfa_reg_info, cfa_reg_value);
const InstructionList &inst_list = disasm_sp->GetInstructionList ();
const size_t num_instructions = inst_list.GetSize();
UnwindPlan::RowSP prologue_completed_row;
if (num_instructions > 0)
{
Instruction *inst = inst_list.GetInstructionAtIndex (0).get();
const addr_t base_addr = inst->GetAddress().GetFileAddress();
// Initialize the current row with the one row that was created
// from the CreateFunctionEntryUnwind call above...
m_curr_row = unwind_plan.GetLastRow();
UnwindPlan::RowSP last_row = unwind_plan.GetLastRow();
UnwindPlan::Row *newrow = new UnwindPlan::Row;
if (last_row.get())
*newrow = *last_row.get();
m_curr_row.reset(newrow);
for (size_t idx=0; idx<num_instructions; ++idx)
{
inst = inst_list.GetInstructionAtIndex (idx).get();
if (inst)
{
if (log && log->GetVerbose ())
{
StreamString strm;
@ -120,9 +126,13 @@ UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange&
{
// Be sure to not edit the offset unless our row has changed
// so that the "!=" call above doesn't trigger every time
m_curr_row.SetOffset (inst->GetAddress().GetFileAddress() + inst->GetOpcode().GetByteSize() - base_addr);
m_curr_row->SetOffset (inst->GetAddress().GetFileAddress() + inst->GetOpcode().GetByteSize() - base_addr);
// Append the new row
unwind_plan.AppendRow (m_curr_row);
UnwindPlan::Row *newrow = new UnwindPlan::Row;
*newrow = *m_curr_row.get();
m_curr_row.reset(newrow);
}
}
}
@ -362,7 +372,7 @@ UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction,
{
m_pushed_regs[reg_num] = addr;
const int32_t offset = addr - m_initial_sp;
m_curr_row.SetRegisterLocationToAtCFAPlusOffset (reg_num, offset, cant_replace);
m_curr_row->SetRegisterLocationToAtCFAPlusOffset (reg_num, offset, cant_replace);
if (is_return_address_reg)
{
// This push was pushing the return address register,
@ -372,7 +382,7 @@ UnwindAssemblyInstEmulation::WriteMemory (EmulateInstruction *instruction,
{
uint32_t pc_reg_num = pc_reg_info.kinds[unwind_reg_kind];
if (pc_reg_num != LLDB_INVALID_REGNUM)
m_curr_row.SetRegisterLocationToAtCFAPlusOffset (pc_reg_num, offset, can_replace);
m_curr_row->SetRegisterLocationToAtCFAPlusOffset (pc_reg_num, offset, can_replace);
}
}
}
@ -488,7 +498,7 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
const uint32_t reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
if (reg_num != LLDB_INVALID_REGNUM)
{
m_curr_row.SetRegisterLocationToSame (reg_num, must_replace);
m_curr_row->SetRegisterLocationToSame (reg_num, must_replace);
}
}
break;
@ -500,8 +510,8 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
m_cfa_reg_info = *reg_info;
const uint32_t cfa_reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
assert (cfa_reg_num != LLDB_INVALID_REGNUM);
m_curr_row.SetCFARegister(cfa_reg_num);
m_curr_row.SetCFAOffset(m_initial_sp - reg_value.GetAsUInt64());
m_curr_row->SetCFARegister(cfa_reg_num);
m_curr_row->SetCFAOffset(m_initial_sp - reg_value.GetAsUInt64());
}
break;
@ -510,7 +520,7 @@ UnwindAssemblyInstEmulation::WriteRegister (EmulateInstruction *instruction,
// subsequent adjustments to the stack pointer.
if (!m_fp_is_cfa)
{
m_curr_row.SetCFAOffset (m_initial_sp - reg_value.GetAsUInt64());
m_curr_row->SetCFAOffset (m_initial_sp - reg_value.GetAsUInt64());
}
break;
}

View File

@ -161,7 +161,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;
lldb_private::UnwindPlan::RowSP m_curr_row;
typedef std::map<uint64_t, uint64_t> PushedRegisterToAddrMap;
uint64_t m_initial_sp;
lldb_private::RegisterInfo m_cfa_reg_info;

View File

@ -531,7 +531,7 @@ AssemblyParse_x86::instruction_length (Address addr, int &length)
bool
AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
{
UnwindPlan::Row row;
UnwindPlan::RowSP row(new UnwindPlan::Row);
int non_prologue_insn_count = 0;
m_cur_insn = m_func_bounds.GetBaseAddress ();
int current_func_text_offset = 0;
@ -548,20 +548,26 @@ AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
unwind_plan.SetRegisterKind (eRegisterKindLLDB);
// At the start of the function, find the CFA by adding wordsize to the SP register
row.SetOffset (current_func_text_offset);
row.SetCFARegister (m_lldb_sp_regnum);
row.SetCFAOffset (m_wordsize);
row->SetOffset (current_func_text_offset);
row->SetCFARegister (m_lldb_sp_regnum);
row->SetCFAOffset (m_wordsize);
// caller's stack pointer value before the call insn is the CFA address
initial_regloc.SetIsCFAPlusOffset (0);
row.SetRegisterInfo (m_lldb_sp_regnum, initial_regloc);
row->SetRegisterInfo (m_lldb_sp_regnum, initial_regloc);
// saved instruction pointer can be found at CFA - wordsize.
current_sp_bytes_offset_from_cfa = m_wordsize;
initial_regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa);
row.SetRegisterInfo (m_lldb_ip_regnum, initial_regloc);
row->SetRegisterInfo (m_lldb_ip_regnum, initial_regloc);
unwind_plan.AppendRow (row);
// Allocate a new Row, populate it with the existing Row contents.
UnwindPlan::Row *newrow = new UnwindPlan::Row;
*newrow = *row.get();
row.reset(newrow);
const bool prefer_file_cache = true;
Target *target = m_exe_ctx.GetTargetPtr();
@ -584,21 +590,29 @@ AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
if (push_rbp_pattern_p ())
{
row.SetOffset (current_func_text_offset + insn_len);
row->SetOffset (current_func_text_offset + insn_len);
current_sp_bytes_offset_from_cfa += m_wordsize;
row.SetCFAOffset (current_sp_bytes_offset_from_cfa);
row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
UnwindPlan::Row::RegisterLocation regloc;
regloc.SetAtCFAPlusOffset (-row.GetCFAOffset());
row.SetRegisterInfo (m_lldb_fp_regnum, regloc);
regloc.SetAtCFAPlusOffset (-row->GetCFAOffset());
row->SetRegisterInfo (m_lldb_fp_regnum, regloc);
unwind_plan.AppendRow (row);
// Allocate a new Row, populate it with the existing Row contents.
newrow = new UnwindPlan::Row;
*newrow = *row.get();
row.reset(newrow);
goto loopnext;
}
if (mov_rsp_rbp_pattern_p ())
{
row.SetOffset (current_func_text_offset + insn_len);
row.SetCFARegister (m_lldb_fp_regnum);
row->SetOffset (current_func_text_offset + insn_len);
row->SetCFARegister (m_lldb_fp_regnum);
unwind_plan.AppendRow (row);
// Allocate a new Row, populate it with the existing Row contents.
newrow = new UnwindPlan::Row;
*newrow = *row.get();
row.reset(newrow);
goto loopnext;
}
@ -615,15 +629,19 @@ AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
current_sp_bytes_offset_from_cfa += m_wordsize;
if (nonvolatile_reg_p (machine_regno) && machine_regno_to_lldb_regno (machine_regno, lldb_regno))
{
row.SetOffset (current_func_text_offset + insn_len);
if (row.GetCFARegister() == m_lldb_sp_regnum)
row->SetOffset (current_func_text_offset + insn_len);
if (row->GetCFARegister() == m_lldb_sp_regnum)
{
row.SetCFAOffset (current_sp_bytes_offset_from_cfa);
row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
}
UnwindPlan::Row::RegisterLocation regloc;
regloc.SetAtCFAPlusOffset (-current_sp_bytes_offset_from_cfa);
row.SetRegisterInfo (lldb_regno, regloc);
row->SetRegisterInfo (lldb_regno, regloc);
unwind_plan.AppendRow (row);
// Allocate a new Row, populate it with the existing Row contents.
newrow = new UnwindPlan::Row;
*newrow = *row.get();
row.reset(newrow);
}
goto loopnext;
}
@ -632,11 +650,15 @@ AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
{
if (machine_regno_to_lldb_regno (machine_regno, lldb_regno))
{
row.SetOffset (current_func_text_offset + insn_len);
row->SetOffset (current_func_text_offset + insn_len);
UnwindPlan::Row::RegisterLocation regloc;
regloc.SetAtCFAPlusOffset (-row.GetCFAOffset());
row.SetRegisterInfo (lldb_regno, regloc);
regloc.SetAtCFAPlusOffset (-row->GetCFAOffset());
row->SetRegisterInfo (lldb_regno, regloc);
unwind_plan.AppendRow (row);
// Allocate a new Row, populate it with the existing Row contents.
newrow = new UnwindPlan::Row;
*newrow = *row.get();
row.reset(newrow);
goto loopnext;
}
}
@ -644,11 +666,15 @@ AssemblyParse_x86::get_non_call_site_unwind_plan (UnwindPlan &unwind_plan)
if (sub_rsp_pattern_p (stack_offset))
{
current_sp_bytes_offset_from_cfa += stack_offset;
if (row.GetCFARegister() == m_lldb_sp_regnum)
if (row->GetCFARegister() == m_lldb_sp_regnum)
{
row.SetOffset (current_func_text_offset + insn_len);
row.SetCFAOffset (current_sp_bytes_offset_from_cfa);
row->SetOffset (current_func_text_offset + insn_len);
row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
unwind_plan.AppendRow (row);
// Allocate a new Row, populate it with the existing Row contents.
newrow = new UnwindPlan::Row;
*newrow = *row.get();
row.reset(newrow);
}
goto loopnext;
}
@ -722,21 +748,21 @@ loopnext:
if (ret_insn_offset != LLDB_INVALID_ADDRESS)
{
// Create a fresh, empty Row and RegisterLocation - don't mention any other registers
UnwindPlan::Row epi_row;
UnwindPlan::RowSP epi_row(new UnwindPlan::Row);
UnwindPlan::Row::RegisterLocation epi_regloc;
// When the ret instruction is about to be executed, here's our state
epi_row.SetOffset (ret_insn_offset);
epi_row.SetCFARegister (m_lldb_sp_regnum);
epi_row.SetCFAOffset (m_wordsize);
epi_row->SetOffset (ret_insn_offset);
epi_row->SetCFARegister (m_lldb_sp_regnum);
epi_row->SetCFAOffset (m_wordsize);
// caller's stack pointer value before the call insn is the CFA address
epi_regloc.SetIsCFAPlusOffset (0);
epi_row.SetRegisterInfo (m_lldb_sp_regnum, epi_regloc);
epi_row->SetRegisterInfo (m_lldb_sp_regnum, epi_regloc);
// saved instruction pointer can be found at CFA - wordsize
epi_regloc.SetAtCFAPlusOffset (-m_wordsize);
epi_row.SetRegisterInfo (m_lldb_ip_regnum, epi_regloc);
epi_row->SetRegisterInfo (m_lldb_ip_regnum, epi_regloc);
unwind_plan.AppendRow (epi_row);
}
@ -755,7 +781,7 @@ loopnext:
bool
AssemblyParse_x86::get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_plan)
{
UnwindPlan::Row row;
UnwindPlan::RowSP row(new UnwindPlan::Row);
UnwindPlan::Row::RegisterLocation pc_reginfo;
UnwindPlan::Row::RegisterLocation sp_reginfo;
UnwindPlan::Row::RegisterLocation fp_reginfo;
@ -790,30 +816,41 @@ AssemblyParse_x86::get_fast_unwind_plan (AddressRange& func, UnwindPlan &unwind_
}
pc_reginfo.SetAtCFAPlusOffset (-m_wordsize);
row.SetRegisterInfo (m_lldb_ip_regnum, pc_reginfo);
row->SetRegisterInfo (m_lldb_ip_regnum, pc_reginfo);
sp_reginfo.SetIsCFAPlusOffset (0);
row.SetRegisterInfo (m_lldb_sp_regnum, sp_reginfo);
row->SetRegisterInfo (m_lldb_sp_regnum, sp_reginfo);
// Zero instructions into the function
row.SetCFARegister (m_lldb_sp_regnum);
row.SetCFAOffset (m_wordsize);
row.SetOffset (0);
row->SetCFARegister (m_lldb_sp_regnum);
row->SetCFAOffset (m_wordsize);
row->SetOffset (0);
unwind_plan.AppendRow (row);
UnwindPlan::Row *newrow = new UnwindPlan::Row;
*newrow = *row.get();
row.reset(newrow);
// push %rbp has executed - stack moved, rbp now saved
row.SetCFAOffset (2 * m_wordsize);
row->SetCFAOffset (2 * m_wordsize);
fp_reginfo.SetAtCFAPlusOffset (2 * -m_wordsize);
row.SetRegisterInfo (m_lldb_fp_regnum, fp_reginfo);
row.SetOffset (1);
row->SetRegisterInfo (m_lldb_fp_regnum, fp_reginfo);
row->SetOffset (1);
unwind_plan.AppendRow (row);
newrow = new UnwindPlan::Row;
*newrow = *row.get();
row.reset(newrow);
// mov %rsp, %rbp has executed
row.SetCFARegister (m_lldb_fp_regnum);
row.SetCFAOffset (2 * m_wordsize);
row.SetOffset (prologue_size); /// 3 or 4 bytes depending on arch
row->SetCFARegister (m_lldb_fp_regnum);
row->SetCFAOffset (2 * m_wordsize);
row->SetOffset (prologue_size); /// 3 or 4 bytes depending on arch
unwind_plan.AppendRow (row);
newrow = new UnwindPlan::Row;
*newrow = *row.get();
row.reset(newrow);
unwind_plan.SetPlanValidAddressRange (func);
return true;
}

View File

@ -403,7 +403,9 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
int32_t data_align = cie->data_align;
unwind_plan.SetPlanValidAddressRange (range);
UnwindPlan::Row row = cie->initial_row;
UnwindPlan::Row *cie_initial_row = new UnwindPlan::Row;
*cie_initial_row = cie->initial_row;
UnwindPlan::RowSP row(cie_initial_row);
unwind_plan.SetRegisterKind (m_reg_kind);
@ -426,7 +428,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
// value and adding (delta * code_align). All other
// values in the new row are initially identical to the current row.
unwind_plan.AppendRow(row);
row.SlideOffset(extended_opcode * code_align);
row->SlideOffset(extended_opcode * code_align);
}
break;
@ -440,7 +442,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
reg_num = extended_opcode;
op_offset = (int32_t)m_cfi_data.GetULEB128(&offset) * data_align;
reg_location.SetAtCFAPlusOffset(op_offset);
row.SetRegisterInfo (reg_num, reg_location);
row->SetRegisterInfo (reg_num, reg_location);
}
break;
@ -455,8 +457,8 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
// by the register index in that state, so we need to convert our
// GCC register number from the EH frame info, to a register index
if (unwind_plan.IsValidRowIndex(0) && unwind_plan.GetRowAtIndex(0).GetRegisterInfo(reg_num, reg_location))
row.SetRegisterInfo (reg_num, reg_location);
if (unwind_plan.IsValidRowIndex(0) && unwind_plan.GetRowAtIndex(0)->GetRegisterInfo(reg_num, reg_location))
row->SetRegisterInfo (reg_num, reg_location);
}
break;
}
@ -476,7 +478,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
// are initially identical to the current row. The new location value
// should always be greater than the current one.
unwind_plan.AppendRow(row);
row.SetOffset(m_cfi_data.GetPointer(&offset) - startaddr.GetFileAddress());
row->SetOffset(m_cfi_data.GetPointer(&offset) - startaddr.GetFileAddress());
}
break;
@ -486,7 +488,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
// This instruction is identical to DW_CFA_advance_loc except for the
// encoding and size of the delta argument.
unwind_plan.AppendRow(row);
row.SlideOffset (m_cfi_data.GetU8(&offset) * code_align);
row->SlideOffset (m_cfi_data.GetU8(&offset) * code_align);
}
break;
@ -496,7 +498,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
// This instruction is identical to DW_CFA_advance_loc except for the
// encoding and size of the delta argument.
unwind_plan.AppendRow(row);
row.SlideOffset (m_cfi_data.GetU16(&offset) * code_align);
row->SlideOffset (m_cfi_data.GetU16(&offset) * code_align);
}
break;
@ -506,7 +508,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
// This instruction is identical to DW_CFA_advance_loc except for the
// encoding and size of the delta argument.
unwind_plan.AppendRow(row);
row.SlideOffset (m_cfi_data.GetU32(&offset) * code_align);
row->SlideOffset (m_cfi_data.GetU32(&offset) * code_align);
}
break;
@ -518,7 +520,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
op_offset = (int32_t)m_cfi_data.GetULEB128(&offset) * data_align;
reg_location.SetAtCFAPlusOffset(op_offset);
row.SetRegisterInfo (reg_num, reg_location);
row->SetRegisterInfo (reg_num, reg_location);
}
break;
@ -528,8 +530,8 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
// number. This instruction is identical to DW_CFA_restore except for
// the encoding and size of the register argument.
reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
if (unwind_plan.IsValidRowIndex(0) && unwind_plan.GetRowAtIndex(0).GetRegisterInfo(reg_num, reg_location))
row.SetRegisterInfo (reg_num, reg_location);
if (unwind_plan.IsValidRowIndex(0) && unwind_plan.GetRowAtIndex(0)->GetRegisterInfo(reg_num, reg_location))
row->SetRegisterInfo (reg_num, reg_location);
}
break;
@ -540,7 +542,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
// register to undefined.
reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
reg_location.SetUndefined();
row.SetRegisterInfo (reg_num, reg_location);
row->SetRegisterInfo (reg_num, reg_location);
}
break;
@ -551,7 +553,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
// register to same value.
reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
reg_location.SetSame();
row.SetRegisterInfo (reg_num, reg_location);
row->SetRegisterInfo (reg_num, reg_location);
}
break;
@ -564,7 +566,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
uint32_t other_reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
reg_location.SetInRegister(other_reg_num);
row.SetRegisterInfo (reg_num, reg_location);
row->SetRegisterInfo (reg_num, reg_location);
}
break;
@ -600,8 +602,8 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
// register and offset.
reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
op_offset = (int32_t)m_cfi_data.GetULEB128(&offset);
row.SetCFARegister (reg_num);
row.SetCFAOffset (op_offset);
row->SetCFARegister (reg_num);
row->SetCFAOffset (op_offset);
}
break;
@ -611,7 +613,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
// number. The required action is to define the current CFA rule to
// use the provided register (but to keep the old offset).
reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
row.SetCFARegister (reg_num);
row->SetCFARegister (reg_num);
}
break;
@ -622,7 +624,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
// the current CFA rule to use the provided offset (but
// to keep the old register).
op_offset = (int32_t)m_cfi_data.GetULEB128(&offset);
row.SetCFAOffset (op_offset);
row->SetCFAOffset (op_offset);
}
break;
@ -648,7 +650,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
const uint8_t *block_data = (uint8_t *)m_cfi_data.GetData(&offset, block_len);
reg_location.SetAtDWARFExpression(block_data, block_len);
row.SetRegisterInfo (reg_num, reg_location);
row->SetRegisterInfo (reg_num, reg_location);
}
break;
@ -661,7 +663,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align;
reg_location.SetAtCFAPlusOffset(op_offset);
row.SetRegisterInfo (reg_num, reg_location);
row->SetRegisterInfo (reg_num, reg_location);
}
break;
@ -673,8 +675,8 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
// that the second operand is signed and factored.
reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align;
row.SetCFARegister (reg_num);
row.SetCFAOffset (op_offset);
row->SetCFARegister (reg_num);
row->SetCFAOffset (op_offset);
}
break;
@ -684,7 +686,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
// offset. This instruction is identical to DW_CFA_def_cfa_offset
// except that the operand is signed and factored.
op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align;
row.SetCFAOffset (op_offset);
row->SetCFAOffset (op_offset);
}
break;
@ -741,7 +743,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, Unwi
// }
//#endif
reg_location.SetIsDWARFExpression(block_data, block_len);
row.SetRegisterInfo (reg_num, reg_location);
row->SetRegisterInfo (reg_num, reg_location);
}
break;

View File

@ -296,35 +296,35 @@ UnwindPlan::Row::SetCFARegister (uint32_t reg_num)
}
void
UnwindPlan::AppendRow (const UnwindPlan::Row &row)
UnwindPlan::AppendRow (UnwindPlan::RowSP row)
{
if (m_row_list.empty() || m_row_list.back().GetOffset() != row.GetOffset())
if (m_row_list.empty() || m_row_list.back()->GetOffset() != row->GetOffset())
m_row_list.push_back(row);
else
m_row_list.back() = row;
}
const UnwindPlan::Row *
UnwindPlan::RowSP
UnwindPlan::GetRowForFunctionOffset (int offset) const
{
const UnwindPlan::Row *row_ptr = NULL;
RowSP row;
if (!m_row_list.empty())
{
if (offset == -1)
row_ptr = &m_row_list.back();
row = m_row_list.back();
else
{
collection::const_iterator pos, end = m_row_list.end();
for (pos = m_row_list.begin(); pos != end; ++pos)
{
if (pos->GetOffset() <= offset)
row_ptr = &*pos;
if ((*pos)->GetOffset() <= offset)
row = *pos;
else
break;
}
}
}
return row_ptr;
return row;
}
bool
@ -333,7 +333,7 @@ UnwindPlan::IsValidRowIndex (uint32_t idx) const
return idx < m_row_list.size();
}
const UnwindPlan::Row&
const UnwindPlan::RowSP
UnwindPlan::GetRowAtIndex (uint32_t idx) const
{
// You must call IsValidRowIndex(idx) first before calling this!!!
@ -341,7 +341,7 @@ UnwindPlan::GetRowAtIndex (uint32_t idx) const
return m_row_list[idx];
}
const UnwindPlan::Row&
const UnwindPlan::RowSP
UnwindPlan::GetLastRow () const
{
// You must call GetRowCount() first to make sure there is at least one row
@ -410,7 +410,7 @@ UnwindPlan::Dump (Stream& s, Thread *thread, lldb::addr_t base_addr) const
for (pos = begin; pos != end; ++pos)
{
s.Printf ("row[%u]: ", (uint32_t)std::distance (begin, pos));
pos->Dump(s, this, thread, base_addr);
(*pos)->Dump(s, this, thread, base_addr);
}
}