forked from OSchip/llvm-project
More cleanup in `frame diagnose,` eliminating a bunch of messy cases.
llvm-svn: 281545
This commit is contained in:
parent
e3612a039f
commit
561a9bbffc
|
@ -224,6 +224,8 @@ MatchUnaryOp(std::function<bool(const Instruction::Operand &)> base,
|
|||
std::function<bool(const Instruction::Operand &)>
|
||||
MatchRegOp(const RegisterInfo &info);
|
||||
|
||||
std::function<bool(const Instruction::Operand &)> FetchRegOp(ConstString ®);
|
||||
|
||||
std::function<bool(const Instruction::Operand &)> MatchImmOp(int64_t imm);
|
||||
|
||||
std::function<bool(const Instruction::Operand &)> FetchImmOp(int64_t &imm);
|
||||
|
|
|
@ -1404,6 +1404,17 @@ lldb_private::OperandMatchers::MatchRegOp(const RegisterInfo &info) {
|
|||
};
|
||||
}
|
||||
|
||||
std::function<bool(const Instruction::Operand &)>
|
||||
lldb_private::OperandMatchers::FetchRegOp(ConstString ®) {
|
||||
return [®](const Instruction::Operand &op) {
|
||||
if (op.m_type != Instruction::Operand::Type::Register) {
|
||||
return false;
|
||||
}
|
||||
reg = op.m_register;
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
std::function<bool(const Instruction::Operand &)>
|
||||
lldb_private::OperandMatchers::MatchImmOp(int64_t imm) {
|
||||
return [imm](const Instruction::Operand &op) {
|
||||
|
|
|
@ -1519,8 +1519,6 @@ lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg,
|
|||
return ValueObjectSP();
|
||||
}
|
||||
|
||||
ValueObjectSP source_path;
|
||||
|
||||
for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii) {
|
||||
// This is not an exact algorithm, and it sacrifices accuracy for
|
||||
// generality. Recognizing "mov" and "ld" instructions –– and which are
|
||||
|
@ -1623,67 +1621,29 @@ lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg,
|
|||
}
|
||||
|
||||
// We have an origin operand. Can we track its value down?
|
||||
switch (origin_operand->m_type) {
|
||||
default:
|
||||
break;
|
||||
case Instruction::Operand::Type::Register:
|
||||
ValueObjectSP source_path;
|
||||
ConstString origin_register;
|
||||
int64_t origin_offset = 0;
|
||||
|
||||
if (FetchRegOp(origin_register)(*origin_operand)) {
|
||||
source_path = DoGuessValueAt(frame, origin_register, 0, disassembler,
|
||||
variables, instruction_sp->GetAddress());
|
||||
} else if (MatchUnaryOp(
|
||||
MatchOpType(Instruction::Operand::Type::Dereference),
|
||||
FetchRegOp(origin_register))(*origin_operand) ||
|
||||
MatchUnaryOp(
|
||||
MatchOpType(Instruction::Operand::Type::Dereference),
|
||||
MatchBinaryOp(MatchOpType(Instruction::Operand::Type::Sum),
|
||||
FetchRegOp(origin_register),
|
||||
FetchImmOp(origin_offset)))(*origin_operand)) {
|
||||
source_path =
|
||||
DoGuessValueAt(frame, origin_operand->m_register, 0, disassembler,
|
||||
DoGuessValueAt(frame, origin_register, origin_offset, disassembler,
|
||||
variables, instruction_sp->GetAddress());
|
||||
break;
|
||||
case Instruction::Operand::Type::Dereference: {
|
||||
const Instruction::Operand &pointer = origin_operand->m_children[0];
|
||||
switch (pointer.m_type) {
|
||||
default:
|
||||
break;
|
||||
case Instruction::Operand::Type::Register:
|
||||
source_path = DoGuessValueAt(frame, pointer.m_register, 0, disassembler,
|
||||
variables, instruction_sp->GetAddress());
|
||||
if (source_path) {
|
||||
Error err;
|
||||
source_path = source_path->Dereference(err);
|
||||
if (!err.Success()) {
|
||||
source_path.reset();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Instruction::Operand::Type::Sum: {
|
||||
const Instruction::Operand *origin_register = nullptr;
|
||||
const Instruction::Operand *origin_offset = nullptr;
|
||||
if (pointer.m_children.size() != 2) {
|
||||
break;
|
||||
}
|
||||
if (pointer.m_children[0].m_type ==
|
||||
Instruction::Operand::Type::Register &&
|
||||
pointer.m_children[1].m_type ==
|
||||
Instruction::Operand::Type::Immediate) {
|
||||
origin_register = &pointer.m_children[0];
|
||||
origin_offset = &pointer.m_children[1];
|
||||
} else if (pointer.m_children[1].m_type ==
|
||||
Instruction::Operand::Type::Register &&
|
||||
pointer.m_children[0].m_type ==
|
||||
Instruction::Operand::Type::Immediate) {
|
||||
origin_register = &pointer.m_children[1];
|
||||
origin_offset = &pointer.m_children[0];
|
||||
}
|
||||
if (!origin_register) {
|
||||
break;
|
||||
}
|
||||
int64_t signed_origin_offset =
|
||||
origin_offset->m_negative ? -((int64_t)origin_offset->m_immediate)
|
||||
: origin_offset->m_immediate;
|
||||
source_path = DoGuessValueAt(frame, origin_register->m_register,
|
||||
signed_origin_offset, disassembler,
|
||||
variables, instruction_sp->GetAddress());
|
||||
if (!source_path) {
|
||||
break;
|
||||
}
|
||||
source_path =
|
||||
GetValueForDereferincingOffset(frame, source_path, offset);
|
||||
break;
|
||||
if (!source_path) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
source_path =
|
||||
GetValueForDereferincingOffset(frame, source_path, offset);
|
||||
}
|
||||
|
||||
if (source_path) {
|
||||
|
|
Loading…
Reference in New Issue