bool Architecture::FormatInstruction( Document const& rDoc, Address const& rAddr, Instruction const& rInsn, PrintData & rPrintData) const { char const* Sep = nullptr; rPrintData.AppendMnemonic(rInsn.GetName()); std::string OpRefCmt; rDoc.GetComment(rAddr, OpRefCmt); for (unsigned int i = 0; i < OPERAND_NO; ++i) { Operand const* pOprd = rInsn.Operand(i); if (pOprd == nullptr) break; if (pOprd->GetType() == O_NONE) break; if (Sep != nullptr) rPrintData.AppendOperator(Sep).AppendSpace(); else Sep = ","; if (!FormatOperand(rDoc, rAddr, rInsn, *pOprd, i, rPrintData)) return false; Address OpRefAddr; if (OpRefCmt.empty() && rInsn.GetOperandReference(rDoc, i, rAddr, OpRefAddr)) { Id OpId; if (rDoc.RetrieveDetailId(OpRefAddr, 0, OpId)) { FunctionDetail FuncDtl; if (rDoc.GetFunctionDetail(OpId, FuncDtl)) { // TODO: provide helper to avoid this... u16 CmtOff = static_cast<u16>(rPrintData.GetCurrentText().length()) - 6 - 1 - rAddr.ToString().length(); rPrintData.AppendSpace().AppendComment(";").AppendSpace(); FormatTypeDetail(FuncDtl.GetReturnType(), rPrintData); rPrintData.AppendSpace().AppendLabel(FuncDtl.GetName()).AppendOperator("("); if (!FuncDtl.GetParameters().empty()) rPrintData.AppendNewLine().AppendSpace(CmtOff).AppendComment(";").AppendSpace(3); bool FirstParam = true; for (auto const& rParam : FuncDtl.GetParameters()) { if (FirstParam) FirstParam = false; else rPrintData.AppendOperator(",").AppendNewLine().AppendSpace(CmtOff).AppendComment(";").AppendSpace(3); FormatTypeDetail(rParam.GetType(), rPrintData); rPrintData.AppendSpace().AppendLabel(rParam.GetValue().GetName()); } rPrintData.AppendOperator(");"); } } } } return true; }
bool Architecture::FormatOperand( Document const& rDoc, Address const& rAddr, Instruction const& rInsn, Operand const& rOprd, u8 OperandNo, PrintData & rPrintData) const { rPrintData.MarkOffset(); auto const& rBinStrm = rDoc.GetBinaryStream(); if (rOprd.GetType() == O_NONE) return true; u32 OprdType = rOprd.GetType(); auto const* pCpuInfo = GetCpuInformation(); std::string MemBegChar = "["; std::string MemEndChar = "]"; if (OprdType & O_MEM) rPrintData.AppendOperator("["); if (OprdType & O_REL || OprdType & O_ABS) { Address DstAddr; if (rInsn.GetOperandReference(rDoc, 0, rAddr, DstAddr)) { auto Lbl = rDoc.GetLabelFromAddress(DstAddr); if (Lbl.GetType() != Label::Unknown) rPrintData.AppendLabel(Lbl.GetLabel()); else rPrintData.AppendAddress(rAddr); } else rPrintData.AppendImmediate(rOprd.GetValue(), rAddr.GetOffsetSize()); } else if (OprdType & O_DISP || OprdType & O_IMM) { if (rOprd.GetType() & O_NO_REF) { rPrintData.AppendImmediate(rOprd.GetValue(), rAddr.GetOffsetSize()); return true; } Address OprdAddr = rDoc.MakeAddress(rOprd.GetSegValue(), rOprd.GetValue()); auto Lbl = rDoc.GetLabelFromAddress(OprdAddr); if (Lbl.GetType() != Label::Unknown) rPrintData.AppendLabel(Lbl.GetLabel()); else rPrintData.AppendAddress(OprdAddr); } else if (OprdType & O_REG) { if (pCpuInfo == nullptr) return false; auto pRegName = pCpuInfo->ConvertIdentifierToName(rOprd.GetReg()); if (pRegName == nullptr) return false; rPrintData.AppendRegister(pRegName); } if (OprdType & O_MEM) rPrintData.AppendOperator("]"); return true; }
bool Architecture::FormatInstruction( Document const& rDoc, BinaryStream const& rBinStrm, Address const& rAddr, Instruction const& rInsn, std::string & rStrCell, Cell::Mark::List & rMarks) const { char Sep = '\0'; std::ostringstream oss; oss << rInsn.GetName() << " "; rMarks.push_back(Cell::Mark(Cell::Mark::MnemonicType, oss.str().size())); for (unsigned int i = 0; i < OPERAND_NO; ++i) { Operand const* pOprd = rInsn.Operand(i); if (pOprd == nullptr) break; if (pOprd->GetType() == O_NONE) break; if (Sep != '\0') { oss << Sep << " "; rMarks.push_back(Cell::Mark(Cell::Mark::OperatorType, 2)); } u32 OprdType = pOprd->GetType(); std::string OprdName = pOprd->GetName(); std::string MemBegChar = "["; std::string MemEndChar = "]"; // NOTE: Since we have to mark all characters with good type, we handle O_MEM here. if (pOprd->GetType() & O_MEM) { MemBegChar = *OprdName.begin(); MemEndChar = *OprdName.rbegin(); OprdName = OprdName.substr(1, OprdName.length() - 2); } if (OprdType & O_MEM) { oss << MemBegChar; rMarks.push_back(Cell::Mark(Cell::Mark::OperatorType, 1)); } do { if (OprdType & O_REL || OprdType & O_ABS) { Address DstAddr; if (rInsn.GetOperandReference(rDoc, 0, rAddr, DstAddr)) { auto Lbl = rDoc.GetLabelFromAddress(DstAddr); OprdName = Lbl.GetLabel(); Cell::Mark::Type MarkType = Cell::Mark::LabelType; if (OprdName.empty()) { OprdName = DstAddr.ToString(); MarkType = Cell::Mark::ImmediateType; } oss << OprdName; rMarks.push_back(Cell::Mark(MarkType, OprdName.length())); } else { oss << OprdName; rMarks.push_back(Cell::Mark(Cell::Mark::ImmediateType, OprdName.length())); } } else if (OprdType & O_DISP || OprdType & O_IMM) { if (pOprd->GetType() & O_NO_REF) { std::string ValueName = pOprd->GetName(); oss << ValueName; rMarks.push_back(Cell::Mark(Cell::Mark::ImmediateType, ValueName.length())); break; } Address OprdAddr(Address::UnknownType, pOprd->GetSegValue(), pOprd->GetValue()); auto Lbl = rDoc.GetLabelFromAddress(OprdAddr); std::string LabelName = Lbl.GetLabel(); if (LabelName.empty()) { std::string ValueName = OprdName; oss << ValueName; rMarks.push_back(Cell::Mark(Cell::Mark::ImmediateType, ValueName.length())); break; } oss << LabelName; rMarks.push_back(Cell::Mark(Cell::Mark::LabelType, LabelName.length())); } else if (OprdType & O_REG) { if (OprdName.empty()) { auto pCpuInfo = GetCpuInformation(); OprdName = pCpuInfo->ConvertIdentifierToName(pOprd->GetReg()); } oss << OprdName; rMarks.push_back(Cell::Mark(Cell::Mark::RegisterType, OprdName.length())); } } while (0); if (OprdType & O_MEM) { oss << MemEndChar; rMarks.push_back(Cell::Mark(Cell::Mark::OperatorType, 1)); } Sep = ','; } //auto rExpr = rInsn.GetSemantic(); //if (rExpr.empty() == false) //{ // auto BegMark = oss.str().length(); // oss << " [ "; // auto itExpr = std::begin(rExpr); // oss << (*itExpr)->ToString(); // ++itExpr; // std::for_each(itExpr, std::end(rExpr), [&oss](Expression const* pExpr) // { // oss << "; " << pExpr->ToString(); // }); // oss << " ]"; // rMarks.push_back(Cell::Mark::KeywordType, oss.str().length() - BegMark); //} rStrCell = oss.str(); return true; }