Ejemplo n.º 1
0
unsigned UserDefinedCodeViewTypesBuilder::GetEnumTypeIndex(
    const EnumTypeDescriptor &TypeDescriptor,
    const EnumRecordTypeDescriptor *TypeRecords) {

  ClassOptions CO = GetCommonClassOptions();
  unsigned FieldListIndex =
      GetEnumFieldListType(TypeDescriptor.ElementCount, TypeRecords);
  TypeIndex FieldListIndexType = TypeIndex(FieldListIndex);
  TypeIndex ElementTypeIndex = TypeIndex(TypeDescriptor.ElementType);

  EnumRecord EnumRecord(TypeDescriptor.ElementCount, CO, FieldListIndexType,
                        TypeDescriptor.Name, StringRef(),
                        ElementTypeIndex);

  TypeIndex Type = TypeTable.writeKnownType(EnumRecord);
  UserDefinedTypes.push_back(std::make_pair(TypeDescriptor.Name, Type.getIndex()));
  return Type.getIndex();
}
Ejemplo n.º 2
0
Error TypeDumpVisitor::visitTypeBegin(CVType &Record, TypeIndex Index) {
  W->startLine() << getLeafTypeName(Record.Type);
  W->getOStream() << " (" << HexNumber(Index.getIndex()) << ")";
  W->getOStream() << " {\n";
  W->indent();
  W->printEnum("TypeLeafKind", unsigned(Record.Type),
               makeArrayRef(LeafTypeNames));
  return Error::success();
}
Ejemplo n.º 3
0
unsigned UserDefinedCodeViewTypesBuilder::GetPointerTypeIndex(const PointerTypeDescriptor& PointerDescriptor)
{
    uint32_t elementType = PointerDescriptor.ElementType;
    PointerKind pointerKind = PointerDescriptor.Is64Bit ? PointerKind::Near64 : PointerKind::Near32;
    PointerMode pointerMode = PointerDescriptor.IsReference ? PointerMode::LValueReference : PointerMode::Pointer;
    PointerOptions pointerOptions = PointerDescriptor.IsConst ? PointerOptions::Const : PointerOptions::None;

    PointerRecord PointerToClass(TypeIndex(elementType), pointerKind, pointerMode, pointerOptions, 0);
    TypeIndex PointerIndex = TypeTable.writeKnownType(PointerToClass);
    return PointerIndex.getIndex();
}
Ejemplo n.º 4
0
void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI,
                                        const DILocation *InlinedAt,
                                        const InlineSite &Site) {
  MCSymbol *InlineBegin = MMI->getContext().createTempSymbol(),
           *InlineEnd = MMI->getContext().createTempSymbol();

  assert(SubprogramToFuncId.count(Site.Inlinee));
  TypeIndex InlineeIdx = SubprogramToFuncId[Site.Inlinee];

  // SymbolRecord
  OS.AddComment("Record length");
  OS.emitAbsoluteSymbolDiff(InlineEnd, InlineBegin, 2);   // RecordLength
  OS.EmitLabel(InlineBegin);
  OS.AddComment("Record kind: S_INLINESITE");
  OS.EmitIntValue(SymbolRecordKind::S_INLINESITE, 2); // RecordKind

  OS.AddComment("PtrParent");
  OS.EmitIntValue(0, 4);
  OS.AddComment("PtrEnd");
  OS.EmitIntValue(0, 4);
  OS.AddComment("Inlinee type index");
  OS.EmitIntValue(InlineeIdx.getIndex(), 4);

  unsigned FileId = maybeRecordFile(Site.Inlinee->getFile());
  unsigned StartLineNum = Site.Inlinee->getLine();
  SmallVector<unsigned, 3> SecondaryFuncIds;
  collectInlineSiteChildren(SecondaryFuncIds, FI, Site);

  OS.EmitCVInlineLinetableDirective(Site.SiteFuncId, FileId, StartLineNum,
                                    FI.Begin, FI.End, SecondaryFuncIds);

  OS.EmitLabel(InlineEnd);

  for (const LocalVariable &Var : Site.InlinedLocals)
    emitLocalVariable(Var);

  // Recurse on child inlined call sites before closing the scope.
  for (const DILocation *ChildSite : Site.ChildSites) {
    auto I = FI.InlineSites.find(ChildSite);
    assert(I != FI.InlineSites.end() &&
           "child site not in function inline site map");
    emitInlinedCallSite(FI, ChildSite, I->second);
  }

  // Close the scope.
  OS.AddComment("Record length");
  OS.EmitIntValue(2, 2);                                  // RecordLength
  OS.AddComment("Record kind: S_INLINESITE_END");
  OS.EmitIntValue(SymbolRecordKind::S_INLINESITE_END, 2); // RecordKind
}
Ejemplo n.º 5
0
unsigned UserDefinedCodeViewTypesBuilder::GetEnumFieldListType(
    uint64 Count, const EnumRecordTypeDescriptor *TypeRecords) {
  FieldListRecordBuilder FLRB(TypeTable);
  FLRB.begin();
#ifndef NDEBUG
  uint64 MaxInt = (unsigned int)-1;
  assert(Count <= MaxInt && "There are too many fields inside enum");
#endif
  for (int i = 0; i < (int)Count; ++i) {
    EnumRecordTypeDescriptor record = TypeRecords[i];
    EnumeratorRecord ER(MemberAccess::Public, APSInt::getUnsigned(record.Value),
                        record.Name);
    FLRB.writeMemberType(ER);
  }
  TypeIndex Type = FLRB.end(true);
  return Type.getIndex();
}
Ejemplo n.º 6
0
unsigned UserDefinedCodeViewTypesBuilder::GetClassTypeIndex(
    const ClassTypeDescriptor &ClassDescriptor) {
  TypeRecordKind Kind =
      ClassDescriptor.IsStruct ? TypeRecordKind::Struct : TypeRecordKind::Class;
  ClassOptions CO = ClassOptions::ForwardReference | GetCommonClassOptions();

  TypeIndex FieldListIndex = TypeIndex();
  uint16_t memberCount = 0;

  if (!ClassDescriptor.IsStruct) {
    FieldListRecordBuilder FLBR(TypeTable);
    FLBR.begin();
    memberCount++;
    AddClassVTShape(FLBR);
    FieldListIndex = FLBR.end(true);
  }

  ClassRecord CR(Kind, memberCount, CO, FieldListIndex, TypeIndex(), TypeIndex(), 0,
                 ClassDescriptor.Name, StringRef());
  TypeIndex FwdDeclTI = TypeTable.writeKnownType(CR);
  return FwdDeclTI.getIndex();
}
Ejemplo n.º 7
0
void CodeViewDebug::emitInlineeLinesSubsection() {
  if (InlinedSubprograms.empty())
    return;

  MCSymbol *InlineBegin = MMI->getContext().createTempSymbol(),
           *InlineEnd = MMI->getContext().createTempSymbol();

  OS.AddComment("Inlinee lines subsection");
  OS.EmitIntValue(unsigned(ModuleSubstreamKind::InlineeLines), 4);
  OS.AddComment("Subsection size");
  OS.emitAbsoluteSymbolDiff(InlineEnd, InlineBegin, 4);
  OS.EmitLabel(InlineBegin);

  // We don't provide any extra file info.
  // FIXME: Find out if debuggers use this info.
  OS.AddComment("Inlinee lines signature");
  OS.EmitIntValue(unsigned(InlineeLinesSignature::Normal), 4);

  for (const DISubprogram *SP : InlinedSubprograms) {
    OS.AddBlankLine();
    TypeIndex TypeId = SubprogramToFuncId[SP];
    unsigned FileId = maybeRecordFile(SP->getFile());
    OS.AddComment("Inlined function " + SP->getDisplayName() + " starts at " +
                  SP->getFilename() + Twine(':') + Twine(SP->getLine()));
    OS.AddBlankLine();
    // The filechecksum table uses 8 byte entries for now, and file ids start at
    // 1.
    unsigned FileOffset = (FileId - 1) * 8;
    OS.AddComment("Type index of inlined function");
    OS.EmitIntValue(TypeId.getIndex(), 4);
    OS.AddComment("Offset into filechecksum table");
    OS.EmitIntValue(FileOffset, 4);
    OS.AddComment("Starting line number");
    OS.EmitIntValue(SP->getLine(), 4);
  }

  OS.EmitLabel(InlineEnd);
}
Ejemplo n.º 8
0
unsigned UserDefinedCodeViewTypesBuilder::GetMemberFunctionTypeIndex(const MemberFunctionTypeDescriptor& MemberDescriptor,
    uint32_t const *const ArgumentTypes)
{
    std::vector<TypeIndex> argumentTypes;
    argumentTypes.reserve(MemberDescriptor.NumberOfArguments);
    for (uint16_t iArgument = 0; iArgument < MemberDescriptor.NumberOfArguments; iArgument++)
    {
        argumentTypes.emplace_back(ArgumentTypes[iArgument]);
    }

    ArgListRecord ArgList(TypeRecordKind::ArgList, argumentTypes);
    TypeIndex ArgumentList = TypeTable.writeKnownType(ArgList);

    MemberFunctionRecord MemberFunction(TypeIndex(MemberDescriptor.ReturnType), 
                                        TypeIndex(MemberDescriptor.ContainingClass), 
                                        TypeIndex(MemberDescriptor.TypeIndexOfThisPointer), 
                                        CallingConvention(MemberDescriptor.CallingConvention), 
                                        FunctionOptions::None, MemberDescriptor.NumberOfArguments, 
                                        ArgumentList, 
                                        MemberDescriptor.ThisAdjust);

    TypeIndex MemberFunctionIndex = TypeTable.writeKnownType(MemberFunction);
    return MemberFunctionIndex.getIndex();
}
Ejemplo n.º 9
0
StringRef TypeDatabase::getTypeName(TypeIndex Index) const {
  if (Index.isNoneType())
    return "<no type>";

  if (Index.isSimple()) {
    // This is a simple type.
    for (const auto &SimpleTypeName : SimpleTypeNames) {
      if (SimpleTypeName.Kind == Index.getSimpleKind()) {
        if (Index.getSimpleMode() == SimpleTypeMode::Direct)
          return SimpleTypeName.Name.drop_back(1);
        // Otherwise, this is a pointer type. We gloss over the distinction
        // between near, far, 64, 32, etc, and just give a pointer type.
        return SimpleTypeName.Name;
      }
    }
    return "<unknown simple type>";
  }

  uint32_t I = Index.getIndex() - TypeIndex::FirstNonSimpleIndex;
  if (I < CVUDTNames.size())
    return CVUDTNames[I];

  return "<unknown UDT>";
}
Ejemplo n.º 10
0
void ScalarTraits<TypeIndex>::output(const TypeIndex &S, void *,
                                     llvm::raw_ostream &OS) {
  OS << S.getIndex();
}
Ejemplo n.º 11
0
void TypeRecordBuilder::writeTypeIndex(TypeIndex TypeInd) {
  writeUInt32(TypeInd.getIndex());
}
Ejemplo n.º 12
0
unsigned UserDefinedCodeViewTypesBuilder::GetMemberFunctionId(const MemberFunctionIdTypeDescriptor& MemberIdDescriptor)
{
    MemberFuncIdRecord MemberFuncId(TypeIndex(MemberIdDescriptor.MemberFunction), TypeIndex(MemberIdDescriptor.ParentClass), MemberIdDescriptor.Name);
    TypeIndex MemberFuncIdIndex = TypeTable.writeKnownType(MemberFuncId);
    return MemberFuncIdIndex.getIndex();
}
Ejemplo n.º 13
0
unsigned UserDefinedCodeViewTypesBuilder::GetArrayTypeIndex(
    const ClassTypeDescriptor &ClassDescriptor,
    const ArrayTypeDescriptor &ArrayDescriptor) {
  FieldListRecordBuilder FLBR(TypeTable);
  FLBR.begin();

  unsigned Offset = 0;
  unsigned FieldsCount = 0;

  assert(ClassDescriptor.BaseClassId != 0);

  AddClassVTShape(FLBR);
  FieldsCount++;
  AddBaseClass(FLBR, ClassDescriptor.BaseClassId);
  FieldsCount++;
  Offset += TargetPointerSize;

  MemberAccess Access = MemberAccess::Public;
  TypeIndex IndexType = TypeIndex(SimpleTypeKind::Int32);
  DataMemberRecord CountDMR(Access, IndexType, Offset, "count");
  FLBR.writeMemberType(CountDMR);
  FieldsCount++;
  Offset += TargetPointerSize;

  if (ArrayDescriptor.IsMultiDimensional == 1) {
    for (unsigned i = 0; i < ArrayDescriptor.Rank; ++i) {
      DataMemberRecord LengthDMR(Access, TypeIndex(SimpleTypeKind::Int32),
                                 Offset, ArrayDimentions.GetLengthName(i));
      FLBR.writeMemberType(LengthDMR);
      FieldsCount++;
      Offset += 4;
    }

    for (unsigned i = 0; i < ArrayDescriptor.Rank; ++i) {
      DataMemberRecord BoundsDMR(Access, TypeIndex(SimpleTypeKind::Int32),
                                 Offset, ArrayDimentions.GetBoundsName(i));
      FLBR.writeMemberType(BoundsDMR);
      FieldsCount++;
      Offset += 4;
    }
  }

  TypeIndex ElementTypeIndex = TypeIndex(ArrayDescriptor.ElementType);
  ArrayRecord AR(ElementTypeIndex, IndexType, ArrayDescriptor.Size, "");
  TypeIndex ArrayIndex = TypeTable.writeKnownType(AR);
  DataMemberRecord ArrayDMR(Access, ArrayIndex, Offset, "values");
  FLBR.writeMemberType(ArrayDMR);
  FieldsCount++;

  TypeIndex FieldListIndex = FLBR.end(true);

  assert(ClassDescriptor.IsStruct == false);
  TypeRecordKind Kind = TypeRecordKind::Class;
  ClassOptions CO = GetCommonClassOptions();
  ClassRecord CR(Kind, FieldsCount, CO, FieldListIndex, TypeIndex(),
                 TypeIndex(), ArrayDescriptor.Size, ClassDescriptor.Name,
                 StringRef());
  TypeIndex ClassIndex = TypeTable.writeKnownType(CR);

  UserDefinedTypes.push_back(std::make_pair(ClassDescriptor.Name, ClassIndex.getIndex()));

  return ClassIndex.getIndex();
}
Ejemplo n.º 14
0
bool TypeDatabase::containsTypeIndex(TypeIndex Index) const {
  uint32_t I = Index.getIndex() - TypeIndex::FirstNonSimpleIndex;
  return I < CVUDTNames.size();
}
Ejemplo n.º 15
0
void CodeViewDebug::emitTypeInformation() {
  // Start the .debug$T section with 0x4.
  OS.SwitchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection());
  OS.AddComment("Debug section magic");
  OS.EmitIntValue(COFF::DEBUG_SECTION_MAGIC, 4);

  NamedMDNode *CU_Nodes =
      MMI->getModule()->getNamedMetadata("llvm.dbg.cu");
  if (!CU_Nodes)
    return;

  // This type info currently only holds function ids for use with inline call
  // frame info. All functions are assigned a simple 'void ()' type. Emit that
  // type here.
  TypeIndex ArgListIdx = getNextTypeIndex();
  OS.AddComment("Type record length");
  OS.EmitIntValue(2 + sizeof(ArgList), 2);
  OS.AddComment("Leaf type: LF_ARGLIST");
  OS.EmitIntValue(LF_ARGLIST, 2);
  OS.AddComment("Number of arguments");
  OS.EmitIntValue(0, 4);

  TypeIndex VoidProcIdx = getNextTypeIndex();
  OS.AddComment("Type record length");
  OS.EmitIntValue(2 + sizeof(ProcedureType), 2);
  OS.AddComment("Leaf type: LF_PROCEDURE");
  OS.EmitIntValue(LF_PROCEDURE, 2);
  OS.AddComment("Return type index");
  OS.EmitIntValue(TypeIndex::Void().getIndex(), 4);
  OS.AddComment("Calling convention");
  OS.EmitIntValue(char(CallingConvention::NearC), 1);
  OS.AddComment("Function options");
  OS.EmitIntValue(char(FunctionOptions::None), 1);
  OS.AddComment("# of parameters");
  OS.EmitIntValue(0, 2);
  OS.AddComment("Argument list type index");
  OS.EmitIntValue(ArgListIdx.getIndex(), 4);

  for (MDNode *N : CU_Nodes->operands()) {
    auto *CUNode = cast<DICompileUnit>(N);
    for (auto *SP : CUNode->getSubprograms()) {
      StringRef DisplayName = SP->getDisplayName();
      OS.AddComment("Type record length");
      MCSymbol *FuncBegin = MMI->getContext().createTempSymbol(),
               *FuncEnd = MMI->getContext().createTempSymbol();
      OS.emitAbsoluteSymbolDiff(FuncEnd, FuncBegin, 2);
      OS.EmitLabel(FuncBegin);
      OS.AddComment("Leaf type: LF_FUNC_ID");
      OS.EmitIntValue(LF_FUNC_ID, 2);

      OS.AddComment("Scope type index");
      OS.EmitIntValue(TypeIndex().getIndex(), 4);
      OS.AddComment("Function type");
      OS.EmitIntValue(VoidProcIdx.getIndex(), 4);
      {
        OS.AddComment("Function name");
        emitNullTerminatedSymbolName(OS, DisplayName);
      }
      OS.EmitLabel(FuncEnd);

      TypeIndex FuncIdIdx = getNextTypeIndex();
      SubprogramToFuncId.insert(std::make_pair(SP, FuncIdIdx));
    }
  }
}