示例#1
0
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;
}
示例#2
0
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;
}