diff --git a/lldb/include/lldb/Symbol/UnwindPlan.h b/lldb/include/lldb/Symbol/UnwindPlan.h index e064ca5e0006..a7f70655ace1 100644 --- a/lldb/include/lldb/Symbol/UnwindPlan.h +++ b/lldb/include/lldb/Symbol/UnwindPlan.h @@ -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 collection; + typedef std::vector 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 diff --git a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp index d3b82b2d352f..384c7eea786a 100644 --- a/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp +++ b/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp @@ -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"); diff --git a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp index 2998e6bbf82d..7f16ae3b2235 100644 --- a/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp +++ b/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp @@ -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"); diff --git a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp index 93254982aa4c..7b5631c1bcad 100644 --- a/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp +++ b/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp @@ -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"); diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index b443bf349e31..7157f405385d 100644 --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -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. diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index 10053dd760a4..d1040d37d314 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -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)) diff --git a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp index 6d2b0a54b6a6..6dc75adaa02b 100644 --- a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp +++ b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp @@ -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; idxGetVerbose ()) { 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; } diff --git a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h index 3ee8cca88dec..c40c65f61b10 100644 --- a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h +++ b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h @@ -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 PushedRegisterToAddrMap; uint64_t m_initial_sp; lldb_private::RegisterInfo m_cfa_reg_info; diff --git a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp index 27e3622696df..09185d67ee7d 100644 --- a/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp +++ b/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp @@ -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; } diff --git a/lldb/source/Symbol/DWARFCallFrameInfo.cpp b/lldb/source/Symbol/DWARFCallFrameInfo.cpp index edc6d151f049..b11130317435 100644 --- a/lldb/source/Symbol/DWARFCallFrameInfo.cpp +++ b/lldb/source/Symbol/DWARFCallFrameInfo.cpp @@ -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; diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp index da5400fdfa88..b7a19b5b3747 100644 --- a/lldb/source/Symbol/UnwindPlan.cpp +++ b/lldb/source/Symbol/UnwindPlan.cpp @@ -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); } }