More cleanup in `frame diagnose,` eliminating a bunch of messy cases.

llvm-svn: 281545
This commit is contained in:
Sean Callanan 2016-09-14 21:54:28 +00:00
parent e3612a039f
commit 561a9bbffc
3 changed files with 33 additions and 60 deletions

View File

@ -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 &reg);
std::function<bool(const Instruction::Operand &)> MatchImmOp(int64_t imm);
std::function<bool(const Instruction::Operand &)> FetchImmOp(int64_t &imm);

View File

@ -1404,6 +1404,17 @@ lldb_private::OperandMatchers::MatchRegOp(const RegisterInfo &info) {
};
}
std::function<bool(const Instruction::Operand &)>
lldb_private::OperandMatchers::FetchRegOp(ConstString &reg) {
return [&reg](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) {

View File

@ -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) {