diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 23 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 63 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 114 | ||||
-rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 46 | ||||
-rw-r--r-- | llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp | 2 |
7 files changed, 218 insertions, 34 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index b3dabca0a8a..ea836469771 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -2633,17 +2633,6 @@ void CodeViewDebug::emitLocalVariableList(const FunctionInfo &FI, emitLocalVariable(FI, L); } -/// Only call this on endian-specific types like ulittle16_t and little32_t, or -/// structs composed of them. -template <typename T> -static void copyBytesForDefRange(SmallString<20> &BytePrefix, - SymbolKind SymKind, const T &DefRangeHeader) { - BytePrefix.resize(2 + sizeof(T)); - ulittle16_t SymKindLE = ulittle16_t(SymKind); - memcpy(&BytePrefix[0], &SymKindLE, 2); - memcpy(&BytePrefix[2], &DefRangeHeader, sizeof(T)); -} - void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI, const LocalVariable &Var) { // LocalSym record, see SymbolRecord.h for more info. @@ -2692,8 +2681,9 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI, (bool(Flags & LocalSymFlags::IsParameter) ? (EncFP == FI.EncodedParamFramePtrReg) : (EncFP == FI.EncodedLocalFramePtrReg))) { - little32_t FPOffset = little32_t(Offset); - copyBytesForDefRange(BytePrefix, S_DEFRANGE_FRAMEPOINTER_REL, FPOffset); + DefRangeFramePointerRelSym::Header DRHdr; + DRHdr.Offset = Offset; + OS.EmitCVDefRangeDirective(DefRange.Ranges, DRHdr); } else { uint16_t RegRelFlags = 0; if (DefRange.IsSubfield) { @@ -2705,7 +2695,7 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI, DRHdr.Register = Reg; DRHdr.Flags = RegRelFlags; DRHdr.BasePointerOffset = Offset; - copyBytesForDefRange(BytePrefix, S_DEFRANGE_REGISTER_REL, DRHdr); + OS.EmitCVDefRangeDirective(DefRange.Ranges, DRHdr); } } else { assert(DefRange.DataOffset == 0 && "unexpected offset into register"); @@ -2714,15 +2704,14 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI, DRHdr.Register = DefRange.CVRegister; DRHdr.MayHaveNoName = 0; DRHdr.OffsetInParent = DefRange.StructOffset; - copyBytesForDefRange(BytePrefix, S_DEFRANGE_SUBFIELD_REGISTER, DRHdr); + OS.EmitCVDefRangeDirective(DefRange.Ranges, DRHdr); } else { DefRangeRegisterSym::Header DRHdr; DRHdr.Register = DefRange.CVRegister; DRHdr.MayHaveNoName = 0; - copyBytesForDefRange(BytePrefix, S_DEFRANGE_REGISTER, DRHdr); + OS.EmitCVDefRangeDirective(DefRange.Ranges, DRHdr); } } - OS.EmitCVDefRangeDirective(DefRange.Ranges, BytePrefix); } } diff --git a/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp b/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp index 27cb7e35234..45b63983beb 100644 --- a/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp +++ b/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp @@ -315,7 +315,7 @@ Error CVSymbolDumperImpl::visitKnownRecord( Error CVSymbolDumperImpl::visitKnownRecord( CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) { - W.printNumber("Offset", DefRangeFramePointerRel.Offset); + W.printNumber("Offset", DefRangeFramePointerRel.Hdr.Offset); printLocalVariableAddrRange(DefRangeFramePointerRel.Range, DefRangeFramePointerRel.getRelocationOffset()); printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps); diff --git a/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp b/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp index 70889839ef4..469e3fcbad6 100644 --- a/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp +++ b/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp @@ -229,7 +229,7 @@ Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, DataSym &Data) { Error SymbolRecordMapping::visitKnownRecord( CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) { - error(IO.mapInteger(DefRangeFramePointerRel.Offset)); + error(IO.mapInteger(DefRangeFramePointerRel.Hdr.Offset)); error(mapLocalVariableAddrRange(IO, DefRangeFramePointerRel.Range)); error(IO.mapVectorTail(DefRangeFramePointerRel.Gaps, MapGap())); diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 7a2b0b8a122..c0890b59fe3 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -254,9 +254,26 @@ public: unsigned SourceLineNum, const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) override; + + void PrintCVDefRangePrefix( + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges); + + void EmitCVDefRangeDirective( + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, + codeview::DefRangeRegisterRelSym::Header DRHdr) override; + void EmitCVDefRangeDirective( ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, - StringRef FixedSizePortion) override; + codeview::DefRangeSubfieldRegisterSym::Header DRHdr) override; + + void EmitCVDefRangeDirective( + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, + codeview::DefRangeRegisterSym::Header DRHdr) override; + + void EmitCVDefRangeDirective( + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, + codeview::DefRangeFramePointerRelSym::Header DRHdr) override; + void EmitCVStringTableDirective() override; void EmitCVFileChecksumsDirective() override; void EmitCVFileChecksumOffsetDirective(unsigned FileNo) override; @@ -1376,9 +1393,8 @@ void MCAsmStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym); } -void MCAsmStreamer::EmitCVDefRangeDirective( - ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, - StringRef FixedSizePortion) { +void MCAsmStreamer::PrintCVDefRangePrefix( + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges) { OS << "\t.cv_def_range\t"; for (std::pair<const MCSymbol *, const MCSymbol *> Range : Ranges) { OS << ' '; @@ -1386,10 +1402,43 @@ void MCAsmStreamer::EmitCVDefRangeDirective( OS << ' '; Range.second->print(OS, MAI); } - OS << ", "; - PrintQuotedString(FixedSizePortion, OS); +} + +void MCAsmStreamer::EmitCVDefRangeDirective( + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, + codeview::DefRangeRegisterRelSym::Header DRHdr) { + PrintCVDefRangePrefix(Ranges); + OS << ", reg_rel, "; + OS << DRHdr.Register << ", " << DRHdr.Flags << ", " + << DRHdr.BasePointerOffset; + EmitEOL(); +} + +void MCAsmStreamer::EmitCVDefRangeDirective( + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, + codeview::DefRangeSubfieldRegisterSym::Header DRHdr) { + PrintCVDefRangePrefix(Ranges); + OS << ", subfield_reg, "; + OS << DRHdr.Register << ", " << DRHdr.OffsetInParent; + EmitEOL(); +} + +void MCAsmStreamer::EmitCVDefRangeDirective( + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, + codeview::DefRangeRegisterSym::Header DRHdr) { + PrintCVDefRangePrefix(Ranges); + OS << ", reg, "; + OS << DRHdr.Register; + EmitEOL(); +} + +void MCAsmStreamer::EmitCVDefRangeDirective( + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, + codeview::DefRangeFramePointerRelSym::Header DRHdr) { + PrintCVDefRangePrefix(Ranges); + OS << ", frame_ptr_rel, "; + OS << DRHdr.Offset; EmitEOL(); - this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion); } void MCAsmStreamer::EmitCVStringTableDirective() { diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 084f6a7a2e1..2740a6875f6 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -524,6 +524,19 @@ private: /// directives parsed by this class. StringMap<DirectiveKind> DirectiveKindMap; + // Codeview def_range type parsing. + enum CVDefRangeType { + CVDR_DEFRANGE = 0, // Placeholder + CVDR_DEFRANGE_REGISTER, + CVDR_DEFRANGE_FRAMEPOINTER_REL, + CVDR_DEFRANGE_SUBFIELD_REGISTER, + CVDR_DEFRANGE_REGISTER_REL + }; + + /// Maps Codeview def_range types --> CVDefRangeType enum, for + /// Codeview def_range types parsed by this class. + StringMap<CVDefRangeType> CVDefRangeTypeMap; + // ".ascii", ".asciz", ".string" bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated); bool parseDirectiveReloc(SMLoc DirectiveLoc); // ".reloc" @@ -671,6 +684,7 @@ private: bool parseDirectiveAddrsigSym(); void initializeDirectiveKindMap(); + void initializeCVDefRangeTypeMap(); }; } // end anonymous namespace @@ -720,6 +734,7 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, PlatformParser->Initialize(*this); initializeDirectiveKindMap(); + initializeCVDefRangeTypeMap(); NumOfMacroInstantiations = 0; } @@ -1737,6 +1752,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, StringMap<DirectiveKind>::const_iterator DirKindIt = DirectiveKindMap.find(IDVal); DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end()) + ? DK_NO_DIRECTIVE : DirKindIt->getValue(); switch (DirKind) { @@ -3825,6 +3841,13 @@ bool AsmParser::parseDirectiveCVInlineLinetable() { return false; } +void AsmParser::initializeCVDefRangeTypeMap() { + CVDefRangeTypeMap["reg"] = CVDR_DEFRANGE_REGISTER; + CVDefRangeTypeMap["frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL; + CVDefRangeTypeMap["subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER; + CVDefRangeTypeMap["reg_rel"] = CVDR_DEFRANGE_REGISTER_REL; +} + /// parseDirectiveCVDefRange /// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes* bool AsmParser::parseDirectiveCVDefRange() { @@ -3846,13 +3869,90 @@ bool AsmParser::parseDirectiveCVDefRange() { Ranges.push_back({GapStartSym, GapEndSym}); } - std::string FixedSizePortion; - if (parseToken(AsmToken::Comma, "unexpected token in directive") || - parseEscapedString(FixedSizePortion)) - return true; - - getStreamer().EmitCVDefRangeDirective(Ranges, FixedSizePortion); - return false; + StringRef CVDefRangeTypeStr; + if (parseToken( + AsmToken::Comma, + "expected comma before def_range type in .cv_def_range directive") || + parseIdentifier(CVDefRangeTypeStr)) + return Error(Loc, "expected def_range type in directive"); + + StringMap<CVDefRangeType>::const_iterator CVTypeIt = + CVDefRangeTypeMap.find(CVDefRangeTypeStr); + CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end()) + ? CVDR_DEFRANGE + : CVTypeIt->getValue(); + switch (CVDRType) { + case CVDR_DEFRANGE_REGISTER: { + int64_t DRRegister; + if (parseToken(AsmToken::Comma, "expected comma before register number in " + ".cv_def_range directive") || + parseAbsoluteExpression(DRRegister)) + return Error(Loc, "expected register number"); + + codeview::DefRangeRegisterSym::Header DRHdr; + DRHdr.Register = DRRegister; + getStreamer().EmitCVDefRangeDirective(Ranges, DRHdr); + break; + } + case CVDR_DEFRANGE_FRAMEPOINTER_REL: { + int64_t DROffset; + if (parseToken(AsmToken::Comma, + "expected comma before offset in .cv_def_range directive") || + parseAbsoluteExpression(DROffset)) + return Error(Loc, "expected offset value"); + + codeview::DefRangeFramePointerRelSym::Header DRHdr; + DRHdr.Offset = DROffset; + getStreamer().EmitCVDefRangeDirective(Ranges, DRHdr); + break; + } + case CVDR_DEFRANGE_SUBFIELD_REGISTER: { + int64_t DRRegister; + int64_t DROffsetInParent; + if (parseToken(AsmToken::Comma, "expected comma before register number in " + ".cv_def_range directive") || + parseAbsoluteExpression(DRRegister)) + return Error(Loc, "expected register number"); + if (parseToken(AsmToken::Comma, + "expected comma before offset in .cv_def_range directive") || + parseAbsoluteExpression(DROffsetInParent)) + return Error(Loc, "expected offset value"); + + codeview::DefRangeSubfieldRegisterSym::Header DRHdr; + DRHdr.Register = DRRegister; + DRHdr.OffsetInParent = DROffsetInParent; + getStreamer().EmitCVDefRangeDirective(Ranges, DRHdr); + break; + } + case CVDR_DEFRANGE_REGISTER_REL: { + int64_t DRRegister; + int64_t DRFlags; + int64_t DRBasePointerOffset; + if (parseToken(AsmToken::Comma, "expected comma before register number in " + ".cv_def_range directive") || + parseAbsoluteExpression(DRRegister)) + return Error(Loc, "expected register value"); + if (parseToken( + AsmToken::Comma, + "expected comma before flag value in .cv_def_range directive") || + parseAbsoluteExpression(DRFlags)) + return Error(Loc, "expected flag value"); + if (parseToken(AsmToken::Comma, "expected comma before base pointer offset " + "in .cv_def_range directive") || + parseAbsoluteExpression(DRBasePointerOffset)) + return Error(Loc, "expected base pointer offset value"); + + codeview::DefRangeRegisterRelSym::Header DRHdr; + DRHdr.Register = DRRegister; + DRHdr.Flags = DRFlags; + DRHdr.BasePointerOffset = DRBasePointerOffset; + getStreamer().EmitCVDefRangeDirective(Ranges, DRHdr); + break; + } + default: + return Error(Loc, "unexpected def_range type in .cv_def_range directive"); + } + return true; } /// parseDirectiveCVString diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index decbb96817e..254eb2cd7b6 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -327,10 +327,56 @@ void MCStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId, const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) {} +/// Only call this on endian-specific types like ulittle16_t and little32_t, or +/// structs composed of them. +template <typename T> +static void copyBytesForDefRange(SmallString<20> &BytePrefix, + codeview::SymbolKind SymKind, + const T &DefRangeHeader) { + BytePrefix.resize(2 + sizeof(T)); + codeview::ulittle16_t SymKindLE = codeview::ulittle16_t(SymKind); + memcpy(&BytePrefix[0], &SymKindLE, 2); + memcpy(&BytePrefix[2], &DefRangeHeader, sizeof(T)); +} + void MCStreamer::EmitCVDefRangeDirective( ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, StringRef FixedSizePortion) {} +void MCStreamer::EmitCVDefRangeDirective( + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, + codeview::DefRangeRegisterRelSym::Header DRHdr) { + SmallString<20> BytePrefix; + copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER_REL, DRHdr); + EmitCVDefRangeDirective(Ranges, BytePrefix); +} + +void MCStreamer::EmitCVDefRangeDirective( + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, + codeview::DefRangeSubfieldRegisterSym::Header DRHdr) { + SmallString<20> BytePrefix; + copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_SUBFIELD_REGISTER, + DRHdr); + EmitCVDefRangeDirective(Ranges, BytePrefix); +} + +void MCStreamer::EmitCVDefRangeDirective( + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, + codeview::DefRangeRegisterSym::Header DRHdr) { + SmallString<20> BytePrefix; + copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER, DRHdr); + EmitCVDefRangeDirective(Ranges, BytePrefix); +} + +void MCStreamer::EmitCVDefRangeDirective( + ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges, + codeview::DefRangeFramePointerRelSym::Header DRHdr) { + SmallString<20> BytePrefix; + copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_FRAMEPOINTER_REL, + DRHdr); + EmitCVDefRangeDirective(Ranges, BytePrefix); +} + void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) { } diff --git a/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp b/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp index 227107c051d..95409fdc330 100644 --- a/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp +++ b/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp @@ -391,7 +391,7 @@ template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) { } template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) { - IO.mapRequired("Offset", Symbol.Offset); + IO.mapRequired("Offset", Symbol.Hdr.Offset); IO.mapRequired("Range", Symbol.Range); IO.mapRequired("Gaps", Symbol.Gaps); } |