diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
| -rw-r--r-- | contrib/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 120 | 
1 files changed, 47 insertions, 73 deletions
| diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 83440513225c..7d945690e9c3 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -17,19 +17,20 @@  #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"  #include "llvm/DebugInfo/CodeView/CodeView.h"  #include "llvm/DebugInfo/CodeView/Line.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h"  #include "llvm/DebugInfo/CodeView/SymbolRecord.h"  #include "llvm/DebugInfo/CodeView/TypeDatabase.h"  #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"  #include "llvm/DebugInfo/CodeView/TypeIndex.h"  #include "llvm/DebugInfo/CodeView/TypeRecord.h"  #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" -#include "llvm/DebugInfo/MSF/ByteStream.h" -#include "llvm/DebugInfo/MSF/StreamReader.h"  #include "llvm/IR/Constants.h"  #include "llvm/MC/MCAsmInfo.h"  #include "llvm/MC/MCExpr.h"  #include "llvm/MC/MCSectionCOFF.h"  #include "llvm/MC/MCSymbol.h" +#include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamReader.h"  #include "llvm/Support/COFF.h"  #include "llvm/Support/ScopedPrinter.h"  #include "llvm/Target/TargetFrameLowering.h" @@ -38,7 +39,6 @@  using namespace llvm;  using namespace llvm::codeview; -using namespace llvm::msf;  CodeViewDebug::CodeViewDebug(AsmPrinter *AP)      : DebugHandlerBase(AP), OS(*Asm->OutStreamer), Allocator(), @@ -238,7 +238,7 @@ TypeIndex CodeViewDebug::getFuncIdForSubprogram(const DISubprogram *SP) {    // The display name includes function template arguments. Drop them to match    // MSVC. -  StringRef DisplayName = SP->getDisplayName().split('<').first; +  StringRef DisplayName = SP->getName().split('<').first;    const DIScope *Scope = SP->getScope().resolve();    TypeIndex TI; @@ -393,7 +393,7 @@ void CodeViewDebug::endModule() {    // subprograms.    switchToDebugSectionForSymbol(nullptr); -  MCSymbol *CompilerInfo = beginCVSubsection(ModuleSubstreamKind::Symbols); +  MCSymbol *CompilerInfo = beginCVSubsection(ModuleDebugFragmentKind::Symbols);    emitCompilerInformation();    endCVSubsection(CompilerInfo); @@ -417,7 +417,7 @@ void CodeViewDebug::endModule() {    // Emit UDT records for any types used by global variables.    if (!GlobalUDTs.empty()) { -    MCSymbol *SymbolsEnd = beginCVSubsection(ModuleSubstreamKind::Symbols); +    MCSymbol *SymbolsEnd = beginCVSubsection(ModuleDebugFragmentKind::Symbols);      emitDebugInfoForUDTs(GlobalUDTs);      endCVSubsection(SymbolsEnd);    } @@ -469,7 +469,7 @@ void CodeViewDebug::emitTypeInformation() {      CommentPrefix += ' ';    } -  TypeDatabase TypeDB; +  TypeDatabase TypeDB(TypeTable.records().size());    CVTypeDumper CVTD(TypeDB);    TypeTable.ForEachRecord([&](TypeIndex Index, ArrayRef<uint8_t> Record) {      if (OS.isVerboseAsm()) { @@ -495,13 +495,13 @@ void CodeViewDebug::emitTypeInformation() {        // comments. The MSVC linker doesn't do much type record validation,        // so the first link of an invalid type record can succeed while        // subsequent links will fail with LNK1285. -      ByteStream Stream(Record); +      BinaryByteStream Stream(Record, llvm::support::little);        CVTypeArray Types; -      StreamReader Reader(Stream); +      BinaryStreamReader Reader(Stream);        Error E = Reader.readArray(Types, Reader.getLength());        if (!E) {          TypeVisitorCallbacks C; -        E = CVTypeVisitor(C).visitTypeStream(Types); +        E = codeview::visitTypeStream(Types, C);        }        if (E) {          logAllUnhandledErrors(std::move(E), errs(), "error: "); @@ -645,7 +645,8 @@ void CodeViewDebug::emitInlineeLinesSubsection() {      return;    OS.AddComment("Inlinee lines subsection"); -  MCSymbol *InlineEnd = beginCVSubsection(ModuleSubstreamKind::InlineeLines); +  MCSymbol *InlineEnd = +      beginCVSubsection(ModuleDebugFragmentKind::InlineeLines);    // We don't provide any extra file info.    // FIXME: Find out if debuggers use this info. @@ -658,7 +659,7 @@ void CodeViewDebug::emitInlineeLinesSubsection() {      OS.AddBlankLine();      unsigned FileId = maybeRecordFile(SP->getFile()); -    OS.AddComment("Inlined function " + SP->getDisplayName() + " starts at " + +    OS.AddComment("Inlined function " + SP->getName() + " starts at " +                    SP->getFilename() + Twine(':') + Twine(SP->getLine()));      OS.AddBlankLine();      // The filechecksum table uses 8 byte entries for now, and file ids start at @@ -760,17 +761,17 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,    // If we have a display name, build the fully qualified name by walking the    // chain of scopes. -  if (!SP->getDisplayName().empty()) +  if (!SP->getName().empty())      FuncName = -        getFullyQualifiedName(SP->getScope().resolve(), SP->getDisplayName()); +        getFullyQualifiedName(SP->getScope().resolve(), SP->getName());    // If our DISubprogram name is empty, use the mangled name.    if (FuncName.empty()) -    FuncName = GlobalValue::getRealLinkageName(GV->getName()); +    FuncName = GlobalValue::dropLLVMManglingEscape(GV->getName());    // Emit a symbol subsection, required by VS2012+ to find function boundaries.    OS.AddComment("Symbol subsection for " + Twine(FuncName)); -  MCSymbol *SymbolsEnd = beginCVSubsection(ModuleSubstreamKind::Symbols); +  MCSymbol *SymbolsEnd = beginCVSubsection(ModuleDebugFragmentKind::Symbols);    {      MCSymbol *ProcRecordBegin = MMI->getContext().createTempSymbol(),               *ProcRecordEnd = MMI->getContext().createTempSymbol(); @@ -887,13 +888,21 @@ void CodeViewDebug::collectVariableInfoFromMFTable(      if (!Scope)        continue; +    // If the variable has an attached offset expression, extract it. +    // FIXME: Try to handle DW_OP_deref as well. +    int64_t ExprOffset = 0; +    if (VI.Expr) +      if (!VI.Expr->extractIfOffset(ExprOffset)) +        continue; +      // Get the frame register used and the offset.      unsigned FrameReg = 0;      int FrameOffset = TFI->getFrameIndexReference(*Asm->MF, VI.Slot, FrameReg);      uint16_t CVReg = TRI->getCodeViewRegNum(FrameReg);      // Calculate the label ranges. -    LocalVarDefRange DefRange = createDefRangeMem(CVReg, FrameOffset); +    LocalVarDefRange DefRange = +        createDefRangeMem(CVReg, FrameOffset + ExprOffset);      for (const InsnRange &Range : Scope->getRanges()) {        const MCSymbol *Begin = getLabelBeforeInsn(Range.first);        const MCSymbol *End = getLabelAfterInsn(Range.second); @@ -948,10 +957,10 @@ void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {        // Handle fragments.        auto Fragment = DIExpr->getFragmentInfo(); -      if (DIExpr && Fragment) { +      if (Fragment) {          IsSubfield = true;          StructOffset = Fragment->OffsetInBits / 8; -      } else if (DIExpr && DIExpr->getNumElements() > 0) { +      } else if (DIExpr->getNumElements() > 0) {          continue; // Ignore unrecognized exprs.        } @@ -1014,14 +1023,7 @@ void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {    }  } -void CodeViewDebug::beginFunction(const MachineFunction *MF) { -  assert(!CurFn && "Can't process two functions at once!"); - -  if (!Asm || !MMI->hasDebugInfo() || !MF->getFunction()->getSubprogram()) -    return; - -  DebugHandlerBase::beginFunction(MF); - +void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) {    const Function *GV = MF->getFunction();    assert(FnDebugInfo.count(GV) == false);    CurFn = &FnDebugInfo[GV]; @@ -1144,33 +1146,12 @@ TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) {    DITypeRef ElementTypeRef = Ty->getBaseType();    TypeIndex ElementTypeIndex = getTypeIndex(ElementTypeRef);    // IndexType is size_t, which depends on the bitness of the target. -  TypeIndex IndexType = Asm->MAI->getPointerSize() == 8 +  TypeIndex IndexType = Asm->TM.getPointerSize() == 8                              ? TypeIndex(SimpleTypeKind::UInt64Quad)                              : TypeIndex(SimpleTypeKind::UInt32Long);    uint64_t ElementSize = getBaseTypeSize(ElementTypeRef) / 8; - -  // We want to assert that the element type multiplied by the array lengths -  // match the size of the overall array. However, if we don't have complete -  // type information for the base type, we can't make this assertion. This -  // happens if limited debug info is enabled in this case: -  //   struct VTableOptzn { VTableOptzn(); virtual ~VTableOptzn(); }; -  //   VTableOptzn array[3]; -  // The DICompositeType of VTableOptzn will have size zero, and the array will -  // have size 3 * sizeof(void*), and we should avoid asserting. -  // -  // There is a related bug in the front-end where an array of a structure, -  // which was declared as incomplete structure first, ends up not getting a -  // size assigned to it. (PR28303) -  // Example: -  //   struct A(*p)[3]; -  //   struct A { int f; } a[3]; -  bool PartiallyIncomplete = false; -  if (Ty->getSizeInBits() == 0 || ElementSize == 0) { -    PartiallyIncomplete = true; -  } -    // Add subranges to array type.    DINodeArray Elements = Ty->getElements();    for (int i = Elements.size() - 1; i >= 0; --i) { @@ -1185,16 +1166,14 @@ TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) {      // Variable Length Array (VLA) has Count equal to '-1'.      // Replace with Count '1', assume it is the minimum VLA length.      // FIXME: Make front-end support VLA subrange and emit LF_DIMVARLU. -    if (Count == -1) { +    if (Count == -1)        Count = 1; -      PartiallyIncomplete = true; -    }      // Update the element size and element type index for subsequent subranges.      ElementSize *= Count;      // If this is the outermost array, use the size from the array. It will be -    // more accurate if PartiallyIncomplete is true. +    // more accurate if we had a VLA or an incomplete element type size.      uint64_t ArraySize =          (i == 0 && ElementSize == 0) ? Ty->getSizeInBits() / 8 : ElementSize; @@ -1203,9 +1182,6 @@ TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) {      ElementTypeIndex = TypeTable.writeKnownType(AR);    } -  (void)PartiallyIncomplete; -  assert(PartiallyIncomplete || ElementSize == (Ty->getSizeInBits() / 8)); -    return ElementTypeIndex;  } @@ -1376,8 +1352,8 @@ TypeIndex CodeViewDebug::lowerTypeMemberPointer(const DIDerivedType *Ty) {    assert(Ty->getTag() == dwarf::DW_TAG_ptr_to_member_type);    TypeIndex ClassTI = getTypeIndex(Ty->getClassType());    TypeIndex PointeeTI = getTypeIndex(Ty->getBaseType(), Ty->getClassType()); -  PointerKind PK = Asm->MAI->getPointerSize() == 8 ? PointerKind::Near64 -                                                   : PointerKind::Near32; +  PointerKind PK = Asm->TM.getPointerSize() == 8 ? PointerKind::Near64 +                                                 : PointerKind::Near32;    bool IsPMF = isa<DISubroutineType>(Ty->getBaseType());    PointerMode PM = IsPMF ? PointerMode::PointerToMemberFunction                           : PointerMode::PointerToDataMember; @@ -1492,7 +1468,8 @@ TypeIndex CodeViewDebug::lowerTypeMemberFunction(const DISubroutineType *Ty,  }  TypeIndex CodeViewDebug::lowerTypeVFTableShape(const DIDerivedType *Ty) { -  unsigned VSlotCount = Ty->getSizeInBits() / (8 * Asm->MAI->getPointerSize()); +  unsigned VSlotCount = +      Ty->getSizeInBits() / (8 * Asm->MAI->getCodePointerSize());    SmallVector<VFTableSlotKind, 4> Slots(VSlotCount, VFTableSlotKind::Near);    VFTableShapeRecord VFTSR(Slots); @@ -1736,10 +1713,12 @@ TypeIndex CodeViewDebug::lowerCompleteTypeClass(const DICompositeType *Ty) {                   SizeInBytes, FullName, Ty->getIdentifier());    TypeIndex ClassTI = TypeTable.writeKnownType(CR); -  StringIdRecord SIDR(TypeIndex(0x0), getFullFilepath(Ty->getFile())); -  TypeIndex SIDI = TypeTable.writeKnownType(SIDR); -  UdtSourceLineRecord USLR(ClassTI, SIDI, Ty->getLine()); -  TypeTable.writeKnownType(USLR); +  if (const auto *File = Ty->getFile()) { +    StringIdRecord SIDR(TypeIndex(0x0), getFullFilepath(File)); +    TypeIndex SIDI = TypeTable.writeKnownType(SIDR); +    UdtSourceLineRecord USLR(ClassTI, SIDI, Ty->getLine()); +    TypeTable.writeKnownType(USLR); +  }    addToUDTs(Ty, ClassTI); @@ -2115,18 +2094,13 @@ void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) {    }  } -void CodeViewDebug::endFunction(const MachineFunction *MF) { -  if (!Asm || !CurFn)  // We haven't created any debug info for this function. -    return; - +void CodeViewDebug::endFunctionImpl(const MachineFunction *MF) {    const Function *GV = MF->getFunction();    assert(FnDebugInfo.count(GV));    assert(CurFn == &FnDebugInfo[GV]);    collectVariableInfo(GV->getSubprogram()); -  DebugHandlerBase::endFunction(MF); -    // Don't emit anything if we don't have any line tables.    if (!CurFn->HaveLineInfo) {      FnDebugInfo.erase(GV); @@ -2152,7 +2126,7 @@ void CodeViewDebug::beginInstruction(const MachineInstr *MI) {    maybeRecordLocation(DL, Asm->MF);  } -MCSymbol *CodeViewDebug::beginCVSubsection(ModuleSubstreamKind Kind) { +MCSymbol *CodeViewDebug::beginCVSubsection(ModuleDebugFragmentKind Kind) {    MCSymbol *BeginLabel = MMI->getContext().createTempSymbol(),             *EndLabel = MMI->getContext().createTempSymbol();    OS.EmitIntValue(unsigned(Kind), 4); @@ -2212,7 +2186,7 @@ void CodeViewDebug::emitDebugInfoForGlobals() {          if (!GV->hasComdat() && !GV->isDeclarationForLinker()) {            if (!EndLabel) {              OS.AddComment("Symbol subsection for globals"); -            EndLabel = beginCVSubsection(ModuleSubstreamKind::Symbols); +            EndLabel = beginCVSubsection(ModuleDebugFragmentKind::Symbols);            }            // FIXME: emitDebugInfoForGlobal() doesn't handle DIExpressions.            emitDebugInfoForGlobal(GVE->getVariable(), GV, Asm->getSymbol(GV)); @@ -2228,9 +2202,9 @@ void CodeViewDebug::emitDebugInfoForGlobals() {          if (GV->hasComdat()) {            MCSymbol *GVSym = Asm->getSymbol(GV);            OS.AddComment("Symbol subsection for " + -                        Twine(GlobalValue::getRealLinkageName(GV->getName()))); +                        Twine(GlobalValue::dropLLVMManglingEscape(GV->getName())));            switchToDebugSectionForSymbol(GVSym); -          EndLabel = beginCVSubsection(ModuleSubstreamKind::Symbols); +          EndLabel = beginCVSubsection(ModuleDebugFragmentKind::Symbols);            // FIXME: emitDebugInfoForGlobal() doesn't handle DIExpressions.            emitDebugInfoForGlobal(GVE->getVariable(), GV, GVSym);            endCVSubsection(EndLabel); | 
