Esempio n. 1
0
static Expected<TypeServer2Record> deserializeTypeServerRecord(CVType &Record) {
  class StealTypeServerVisitor : public TypeVisitorCallbacks {
  public:
    explicit StealTypeServerVisitor(TypeServer2Record &TR) : TR(TR) {}

    Error visitKnownRecord(CVType &CVR, TypeServer2Record &Record) override {
      TR = Record;
      return Error::success();
    }

  private:
    TypeServer2Record &TR;
  };

  TypeServer2Record R(TypeRecordKind::TypeServer2);
  TypeDeserializer Deserializer;
  StealTypeServerVisitor Thief(R);
  TypeVisitorCallbackPipeline Pipeline;
  Pipeline.addCallbackToPipeline(Deserializer);
  Pipeline.addCallbackToPipeline(Thief);
  CVTypeVisitor Visitor(Pipeline);
  if (auto EC = Visitor.visitTypeRecord(Record))
    return std::move(EC);

  return R;
}
Esempio n. 2
0
Error CVTypeDumper::dump(const CVTypeArray &Types,
                         TypeVisitorCallbacks &Dumper) {
  TypeDatabaseVisitor DBV(TypeDB);
  TypeDeserializer Deserializer;
  TypeVisitorCallbackPipeline Pipeline;
  Pipeline.addCallbackToPipeline(Deserializer);
  Pipeline.addCallbackToPipeline(DBV);
  Pipeline.addCallbackToPipeline(Dumper);

  CVTypeVisitor Visitor(Pipeline);
  if (Handler)
    Visitor.addTypeServerHandler(*Handler);

  if (auto EC = Visitor.visitTypeStream(Types))
    return EC;
  return Error::success();
}
Esempio n. 3
0
Error CVTypeVisitor::visitFieldListMemberStream(BinaryStreamReader Reader) {
  FieldListDeserializer Deserializer(Reader);
  TypeVisitorCallbackPipeline Pipeline;
  Pipeline.addCallbackToPipeline(Deserializer);
  Pipeline.addCallbackToPipeline(Callbacks);

  TypeLeafKind Leaf;
  while (!Reader.empty()) {
    if (auto EC = Reader.readEnum(Leaf))
      return EC;

    CVMemberRecord Record;
    Record.Kind = Leaf;
    if (auto EC = ::visitMemberRecord(Record, Pipeline))
      return EC;
  }

  return Error::success();
}
Esempio n. 4
0
Error AnalysisStyle::dump() {
  auto Tpi = File.getPDBTpiStream();
  if (!Tpi)
    return Tpi.takeError();

  TypeDatabase TypeDB(Tpi->getNumTypeRecords());
  TypeDatabaseVisitor DBV(TypeDB);
  TypeVisitorCallbackPipeline Pipeline;
  HashLookupVisitor Hasher(*Tpi);
  // Add them to the database
  Pipeline.addCallbackToPipeline(DBV);
  // Store their hash values
  Pipeline.addCallbackToPipeline(Hasher);

  if (auto EC = codeview::visitTypeStream(Tpi->typeArray(), Pipeline))
    return EC;

  auto &Adjusters = Tpi->getHashAdjusters();
  DenseSet<uint32_t> AdjusterSet;
  for (const auto &Adj : Adjusters) {
    assert(AdjusterSet.find(Adj.second) == AdjusterSet.end());
    AdjusterSet.insert(Adj.second);
  }

  uint32_t Count = 0;
  outs() << "Searching for hash collisions\n";
  for (const auto &H : Hasher.Lookup) {
    if (H.second.size() <= 1)
      continue;
    ++Count;
    outs() << formatv("Hash: {0}, Count: {1} records\n", H.first,
                      H.second.size());
    for (const auto &R : H.second) {
      auto Iter = AdjusterSet.find(R.TI.getIndex());
      StringRef Prefix;
      if (Iter != AdjusterSet.end()) {
        Prefix = "[HEAD]";
        AdjusterSet.erase(Iter);
      }
      StringRef LeafName = getLeafTypeName(R.Record.Type);
      uint32_t TI = R.TI.getIndex();
      StringRef TypeName = TypeDB.getTypeName(R.TI);
      outs() << formatv("{0,-6} {1} ({2:x}) {3}\n", Prefix, LeafName, TI,
                        TypeName);
    }
  }

  outs() << "\n";
  outs() << "Dumping hash adjustment chains\n";
  for (const auto &A : Tpi->getHashAdjusters()) {
    TypeIndex TI(A.second);
    StringRef TypeName = TypeDB.getTypeName(TI);
    const CVType &HeadRecord = TypeDB.getTypeRecord(TI);
    assert(HeadRecord.Hash.hasValue());

    auto CollisionsIter = Hasher.Lookup.find(*HeadRecord.Hash);
    if (CollisionsIter == Hasher.Lookup.end())
      continue;

    const auto &Collisions = CollisionsIter->second;
    outs() << TypeName << "\n";
    outs() << formatv("    [HEAD] {0:x} {1} {2}\n", A.second,
                      getLeafTypeName(HeadRecord.Type), TypeName);
    for (const auto &Chain : Collisions) {
      if (Chain.TI == TI)
        continue;
      const CVType &TailRecord = TypeDB.getTypeRecord(Chain.TI);
      outs() << formatv("           {0:x} {1} {2}\n", Chain.TI.getIndex(),
                        getLeafTypeName(TailRecord.Type),
                        TypeDB.getTypeName(Chain.TI));
    }
  }
  outs() << formatv("There are {0} orphaned hash adjusters\n",
                    AdjusterSet.size());
  for (const auto &Adj : AdjusterSet) {
    outs() << formatv("    {0}\n", Adj);
  }

  uint32_t DistinctHashValues = Hasher.Lookup.size();
  outs() << formatv("{0}/{1} hash collisions", Count, DistinctHashValues);
  return Error::success();
}