bool Architecture::FormatFunction( Document const& rDoc, Address const& rAddr, Function const& rFunc, PrintData & rPrintData) const { auto FuncLabel = rDoc.GetLabelFromAddress(rAddr); if (rFunc.GetSize() != 0 && rFunc.GetInstructionCounter() != 0) { std::ostringstream oss; oss << std::hex << std::showbase << std::left << "; size=" << rFunc.GetSize() << ", insn_cnt=" << rFunc.GetInstructionCounter(); rPrintData.AppendComment(oss.str()); } else rPrintData.AppendComment("; imported"); Id CurId; if (!rDoc.RetrieveDetailId(rAddr, 0, CurId)) return true; FunctionDetail FuncDtl; if (!rDoc.GetFunctionDetail(CurId, FuncDtl)) return true; rPrintData.AppendNewLine().AppendSpace(2).AppendComment(";").AppendSpace(); auto const& RetType = FuncDtl.GetReturnType(); std::string FuncName; Label CurLbl = rDoc.GetLabelFromAddress(rAddr); if (CurLbl.GetType() == Label::Unknown) FuncName = FuncDtl.GetName(); else FuncName = CurLbl.GetName(); FormatTypeDetail(RetType, rPrintData); rPrintData.AppendSpace().AppendLabel(FuncName).AppendOperator("("); bool FirstParam = true; auto const& Params = FuncDtl.GetParameters(); for (auto const& Param : Params) { if (FirstParam) FirstParam = false; else rPrintData.AppendOperator(",").AppendSpace(); FormatTypeDetail(Param.GetType(), rPrintData); rPrintData.AppendSpace().AppendLabel(Param.GetValue().GetName()); } rPrintData.AppendOperator(");"); return true; }
bool Architecture::FormatFunction( Document const& rDoc, BinaryStream const& rBinStrm, Address const& rAddr, Function const& rFunc, std::string & rStrMultiCell, Cell::Mark::List & rMarks) const { std::ostringstream oss; oss << std::hex << std::showbase << std::left; auto FuncLabel = rDoc.GetLabelFromAddress(rAddr); oss << "; " << FuncLabel.GetLabel() << ": size=" << rFunc.GetSize() << ", insn_cnt=" << rFunc.GetInstructionCounter(); rStrMultiCell = oss.str(); 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; }
bool Architecture::FormatValue( Document const& rDoc, BinaryStream const& rBinStrm, Address const& rAddr, Value const& rVal, std::string & rStrCell, Cell::Mark::List & rMarks) const { std::ostringstream oss; TOffset Off; u8 ValueType = rVal.GetSubType(); std::string BasePrefix = ""; bool IsUnk = false; auto const& rCurBinStrm = rDoc.GetBinaryStream(); if (!rDoc.ConvertAddressToFileOffset(rAddr, Off)) IsUnk = true; oss << std::setfill('0'); switch (ValueType) { case Value::BinaryType: BasePrefix = "0b"; break; // TODO: Unimplemented case Value::DecimalType: oss << std::dec; BasePrefix = "0n"; break; case Value::HexadecimalType: default: oss << std::hex; BasePrefix = "0x"; break; } Cell::Mark::Type MarkType = Cell::Mark::ImmediateType; switch (rVal.GetLength()) { case 1: default: { if (IsUnk) oss << "db (?)"; else { u8 Data; if (!rCurBinStrm.Read(Off, Data)) return false; oss << "db " << BasePrefix << std::setw(2) << static_cast<u16>(Data); // u8 type would be printed as char by ostream } break; } case 2: { if (IsUnk) oss << "dw (?)"; else { u16 Data; if (!rCurBinStrm.Read(Off, Data)) return false; Label Lbl = rDoc.GetLabelFromAddress(Data); if (Lbl.GetType() == Label::Unknown) oss << "dw " << BasePrefix << std::setw(4) << static_cast<u16>(Data); else { oss << "dw " << Lbl.GetLabel(); MarkType = Cell::Mark::LabelType; } } break; } case 4: { if (IsUnk) oss << "dd (?)"; else { u32 Data; if (!rCurBinStrm.Read(Off, Data)) return false; Label Lbl = rDoc.GetLabelFromAddress(Data); if (Lbl.GetType() == Label::Unknown) oss << "dd " << BasePrefix << std::setw(8) << static_cast<u32>(Data); else { oss << "dd " << Lbl.GetLabel(); MarkType = Cell::Mark::LabelType; } } break; } case 8: { if (IsUnk) oss << "dq (?)"; else { u64 Data; if (!rCurBinStrm.Read(Off, Data)) return false; Label Lbl = rDoc.GetLabelFromAddress(Data); if (Lbl.GetType() == Label::Unknown) oss << "dq " << BasePrefix << std::setw(16) << static_cast<u64>(Data); else { oss << "dq " << Lbl.GetLabel(); MarkType = Cell::Mark::LabelType; } } break; } } rMarks.push_back(Cell::Mark(Cell::Mark::KeywordType, 3)); rMarks.push_back(Cell::Mark(MarkType, oss.str().length() - 3)); rStrCell = oss.str(); return true; }