Skip to content

Commit 9d25c85

Browse files
committed
squeeze in one more level
1 parent 51e6692 commit 9d25c85

File tree

1 file changed

+110
-111
lines changed

1 file changed

+110
-111
lines changed

lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp

Lines changed: 110 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)