@@ -140,23 +140,65 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
140140 m_forward_branch_offset = 0 ;
141141
142142 inst = inst_list.GetInstructionAtIndex (idx).get ();
143- if (inst) {
144- lldb::addr_t current_offset =
145- inst->GetAddress ().GetFileAddress () - base_addr;
146- auto it = saved_unwind_states.upper_bound (current_offset);
147- assert (it != saved_unwind_states.begin () &&
148- " Unwind row for the function entry missing" );
149- --it; // Move it to the row corresponding to the current offset
150-
151- // If the offset of m_curr_row don't match with the offset we see in
152- // saved_unwind_states then we have to update m_curr_row and
153- // m_register_values based on the saved values. It is happening after we
154- // processed an epilogue and a return to caller instruction.
155- if (it->second .first ->GetOffset () != m_curr_row->GetOffset ()) {
156- UnwindPlan::Row *newrow = new UnwindPlan::Row;
157- *newrow = *it->second .first ;
158- m_curr_row.reset (newrow);
159- m_register_values = it->second .second ;
143+ if (!inst)
144+ continue ;
145+
146+ lldb::addr_t current_offset =
147+ inst->GetAddress ().GetFileAddress () - base_addr;
148+ auto it = saved_unwind_states.upper_bound (current_offset);
149+ assert (it != saved_unwind_states.begin () &&
150+ " Unwind row for the function entry missing" );
151+ --it; // Move it to the row corresponding to the current offset
152+
153+ // If the offset of m_curr_row don't match with the offset we see in
154+ // saved_unwind_states then we have to update m_curr_row and
155+ // m_register_values based on the saved values. It is happening after we
156+ // processed an epilogue and a return to caller instruction.
157+ if (it->second .first ->GetOffset () != m_curr_row->GetOffset ()) {
158+ UnwindPlan::Row *newrow = new UnwindPlan::Row;
159+ *newrow = *it->second .first ;
160+ m_curr_row.reset (newrow);
161+ m_register_values = it->second .second ;
162+ // re-set the CFA register ivars to match the new m_curr_row.
163+ if (sp_reg_info.name &&
164+ m_curr_row->GetCFAValue ().IsRegisterPlusOffset ()) {
165+ uint32_t row_cfa_regnum =
166+ m_curr_row->GetCFAValue ().GetRegisterNumber ();
167+ lldb::RegisterKind row_kind = m_unwind_plan_ptr->GetRegisterKind ();
168+ // set m_cfa_reg_info to the row's CFA reg.
169+ m_cfa_reg_info =
170+ *m_inst_emulator_up->GetRegisterInfo (row_kind, row_cfa_regnum);
171+ // set m_fp_is_cfa.
172+ if (sp_reg_info.kinds [row_kind] == row_cfa_regnum)
173+ m_fp_is_cfa = false ;
174+ else
175+ m_fp_is_cfa = true ;
176+ }
177+ }
178+
179+ m_inst_emulator_up->SetInstruction (inst->GetOpcode (), inst->GetAddress (),
180+ nullptr );
181+
182+ if (last_condition != m_inst_emulator_up->GetInstructionCondition ()) {
183+ if (m_inst_emulator_up->GetInstructionCondition () !=
184+ EmulateInstruction::UnconditionalCondition &&
185+ saved_unwind_states.count (current_offset) == 0 ) {
186+ // If we don't have a saved row for the current offset then save our
187+ // current state because we will have to restore it after the
188+ // conditional block.
189+ auto new_row = std::make_shared<UnwindPlan::Row>(*m_curr_row.get ());
190+ saved_unwind_states.insert (
191+ {current_offset, {new_row, m_register_values}});
192+ }
193+
194+ // If the last instruction was conditional with a different condition
195+ // then the then current condition then restore the condition.
196+ if (last_condition != EmulateInstruction::UnconditionalCondition) {
197+ const auto &saved_state =
198+ saved_unwind_states.at (condition_block_start_offset);
199+ m_curr_row = std::make_shared<UnwindPlan::Row>(*saved_state.first );
200+ m_curr_row->SetOffset (current_offset);
201+ m_register_values = saved_state.second ;
160202 // re-set the CFA register ivars to match the new m_curr_row.
161203 if (sp_reg_info.name &&
162204 m_curr_row->GetCFAValue ().IsRegisterPlusOffset ()) {
@@ -172,105 +214,62 @@ bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
172214 else
173215 m_fp_is_cfa = true ;
174216 }
217+ // The last instruction might already created a row for this offset
218+ // and we want to overwrite it.
219+ bool replace_existing = true ;
220+ unwind_plan.InsertRow (std::make_shared<UnwindPlan::Row>(*m_curr_row),
221+ replace_existing);
175222 }
176223
177- m_inst_emulator_up->SetInstruction (inst->GetOpcode (),
178- inst->GetAddress (), nullptr );
179-
180- if (last_condition != m_inst_emulator_up->GetInstructionCondition ()) {
181- if (m_inst_emulator_up->GetInstructionCondition () !=
182- EmulateInstruction::UnconditionalCondition &&
183- saved_unwind_states.count (current_offset) == 0 ) {
184- // If we don't have a saved row for the current offset then save our
185- // current state because we will have to restore it after the
186- // conditional block.
187- auto new_row = std::make_shared<UnwindPlan::Row>(*m_curr_row.get ());
188- saved_unwind_states.insert (
189- {current_offset, {new_row, m_register_values}});
190- }
191-
192- // If the last instruction was conditional with a different condition
193- // then the then current condition then restore the condition.
194- if (last_condition != EmulateInstruction::UnconditionalCondition) {
195- const auto &saved_state =
196- saved_unwind_states.at (condition_block_start_offset);
197- m_curr_row = std::make_shared<UnwindPlan::Row>(*saved_state.first );
198- m_curr_row->SetOffset (current_offset);
199- m_register_values = saved_state.second ;
200- // re-set the CFA register ivars to match the new m_curr_row.
201- if (sp_reg_info.name &&
202- m_curr_row->GetCFAValue ().IsRegisterPlusOffset ()) {
203- uint32_t row_cfa_regnum =
204- m_curr_row->GetCFAValue ().GetRegisterNumber ();
205- lldb::RegisterKind row_kind =
206- m_unwind_plan_ptr->GetRegisterKind ();
207- // set m_cfa_reg_info to the row's CFA reg.
208- m_cfa_reg_info = *m_inst_emulator_up->GetRegisterInfo (
209- row_kind, row_cfa_regnum);
210- // set m_fp_is_cfa.
211- if (sp_reg_info.kinds [row_kind] == row_cfa_regnum)
212- m_fp_is_cfa = false ;
213- else
214- m_fp_is_cfa = true ;
215- }
216- // The last instruction might already created a row for this offset
217- // and we want to overwrite it.
218- bool replace_existing = true ;
219- unwind_plan.InsertRow (
220- std::make_shared<UnwindPlan::Row>(*m_curr_row),
221- replace_existing);
222- }
223-
224- // We are starting a new conditional block at the actual offset
225- condition_block_start_offset = current_offset;
226- }
224+ // We are starting a new conditional block at the actual offset
225+ condition_block_start_offset = current_offset;
226+ }
227227
228- if (log && log->GetVerbose ()) {
229- StreamString strm;
230- lldb_private::FormatEntity::Entry format;
231- FormatEntity::Parse (" ${frame.pc}: " , format);
232- inst->Dump (&strm, inst_list.GetMaxOpcocdeByteSize (), show_address,
233- show_bytes, show_control_flow_kind, nullptr , nullptr ,
234- nullptr , &format, 0 );
235- log->PutString (strm.GetString ());
236- }
228+ if (log && log->GetVerbose ()) {
229+ StreamString strm;
230+ lldb_private::FormatEntity::Entry format;
231+ FormatEntity::Parse (" ${frame.pc}: " , format);
232+ inst->Dump (&strm, inst_list.GetMaxOpcocdeByteSize (), show_address,
233+ show_bytes, show_control_flow_kind, nullptr , nullptr ,
234+ nullptr , &format, 0 );
235+ log->PutString (strm.GetString ());
236+ }
237237
238- last_condition = m_inst_emulator_up->GetInstructionCondition ();
239-
240- m_inst_emulator_up->EvaluateInstruction (
241- eEmulateInstructionOptionIgnoreConditions);
242-
243- // If the current instruction is a branch forward then save the current
244- // CFI information for the offset where we are branching.
245- if (m_forward_branch_offset != 0 &&
246- range.ContainsFileAddress (inst->GetAddress ().GetFileAddress () +
247- m_forward_branch_offset)) {
248- auto newrow = std::make_shared<UnwindPlan::Row>(*m_curr_row.get ());
249- newrow->SetOffset (current_offset + m_forward_branch_offset);
250- saved_unwind_states.insert ({current_offset + m_forward_branch_offset,
251- {newrow, m_register_values}});
252- unwind_plan.InsertRow (newrow);
253- }
238+ last_condition = m_inst_emulator_up->GetInstructionCondition ();
239+
240+ m_inst_emulator_up->EvaluateInstruction (
241+ eEmulateInstructionOptionIgnoreConditions);
242+
243+ // If the current instruction is a branch forward then save the current
244+ // CFI information for the offset where we are branching.
245+ if (m_forward_branch_offset != 0 &&
246+ range.ContainsFileAddress (inst->GetAddress ().GetFileAddress () +
247+ m_forward_branch_offset)) {
248+ auto newrow = std::make_shared<UnwindPlan::Row>(*m_curr_row.get ());
249+ newrow->SetOffset (current_offset + m_forward_branch_offset);
250+ saved_unwind_states.insert ({current_offset + m_forward_branch_offset,
251+ {newrow, m_register_values}});
252+ unwind_plan.InsertRow (newrow);
253+ }
254254
255- // Were there any changes to the CFI while evaluating this instruction?
256- if (m_curr_row_modified) {
257- // Save the modified row if we don't already have a CFI row in the
258- // current address
259- if (saved_unwind_states.count (current_offset +
260- inst->GetOpcode ().GetByteSize ()) == 0 ) {
261- m_curr_row->SetOffset (current_offset +
262- inst->GetOpcode ().GetByteSize ());
263- unwind_plan.InsertRow (m_curr_row);
264- saved_unwind_states.insert (
265- {current_offset + inst->GetOpcode ().GetByteSize (),
266- {m_curr_row, m_register_values}});
267-
268- // Allocate a new Row for m_curr_row, copy the current state
269- // into it
270- UnwindPlan::Row *newrow = new UnwindPlan::Row;
271- *newrow = *m_curr_row.get ();
272- m_curr_row.reset (newrow);
273- }
255+ // Were there any changes to the CFI while evaluating this instruction?
256+ if (m_curr_row_modified) {
257+ // Save the modified row if we don't already have a CFI row in the
258+ // current address
259+ if (saved_unwind_states.count (current_offset +
260+ inst->GetOpcode ().GetByteSize ()) == 0 ) {
261+ m_curr_row->SetOffset (current_offset +
262+ inst->GetOpcode ().GetByteSize ());
263+ unwind_plan.InsertRow (m_curr_row);
264+ saved_unwind_states.insert (
265+ {current_offset + inst->GetOpcode ().GetByteSize (),
266+ {m_curr_row, m_register_values}});
267+
268+ // Allocate a new Row for m_curr_row, copy the current state
269+ // into it
270+ UnwindPlan::Row *newrow = new UnwindPlan::Row;
271+ *newrow = *m_curr_row.get ();
272+ m_curr_row.reset (newrow);
274273 }
275274 }
276275 }
0 commit comments