Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit c132cb0

Browse files
committed
Changing representation of .cv_def_range directives in Codeview debug info assembly format for better readability
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367867 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 79dc0bc commit c132cb0

20 files changed

+369
-66
lines changed

include/llvm/DebugInfo/CodeView/SymbolRecord.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,10 @@ class DefRangeFramePointerRelSym : public SymbolRecord {
520520
static constexpr uint32_t RelocationOffset = 8;
521521

522522
public:
523+
struct Header {
524+
little32_t Offset;
525+
};
526+
523527
explicit DefRangeFramePointerRelSym(SymbolRecordKind Kind)
524528
: SymbolRecord(Kind) {}
525529
DefRangeFramePointerRelSym(uint32_t RecordOffset)
@@ -530,7 +534,7 @@ class DefRangeFramePointerRelSym : public SymbolRecord {
530534
return RecordOffset + RelocationOffset;
531535
}
532536

533-
int32_t Offset;
537+
Header Hdr;
534538
LocalVariableAddrRange Range;
535539
std::vector<LocalVariableAddrGap> Gaps;
536540

include/llvm/MC/MCStreamer.h

+17
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "llvm/ADT/Optional.h"
1919
#include "llvm/ADT/SmallVector.h"
2020
#include "llvm/ADT/StringRef.h"
21+
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
2122
#include "llvm/MC/MCDirectives.h"
2223
#include "llvm/MC/MCLinkerOptimizationHint.h"
2324
#include "llvm/MC/MCSymbol.h"
@@ -860,6 +861,22 @@ class MCStreamer {
860861
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
861862
StringRef FixedSizePortion);
862863

864+
virtual void EmitCVDefRangeDirective(
865+
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
866+
codeview::DefRangeRegisterRelSym::Header DRHdr);
867+
868+
virtual void EmitCVDefRangeDirective(
869+
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
870+
codeview::DefRangeSubfieldRegisterSym::Header DRHdr);
871+
872+
virtual void EmitCVDefRangeDirective(
873+
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
874+
codeview::DefRangeRegisterSym::Header DRHdr);
875+
876+
virtual void EmitCVDefRangeDirective(
877+
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
878+
codeview::DefRangeFramePointerRelSym::Header DRHdr);
879+
863880
/// This implements the CodeView '.cv_stringtable' assembler directive.
864881
virtual void EmitCVStringTableDirective() {}
865882

lib/CodeGen/AsmPrinter/CodeViewDebug.cpp

+6-17
Original file line numberDiff line numberDiff line change
@@ -2633,17 +2633,6 @@ void CodeViewDebug::emitLocalVariableList(const FunctionInfo &FI,
26332633
emitLocalVariable(FI, L);
26342634
}
26352635

2636-
/// Only call this on endian-specific types like ulittle16_t and little32_t, or
2637-
/// structs composed of them.
2638-
template <typename T>
2639-
static void copyBytesForDefRange(SmallString<20> &BytePrefix,
2640-
SymbolKind SymKind, const T &DefRangeHeader) {
2641-
BytePrefix.resize(2 + sizeof(T));
2642-
ulittle16_t SymKindLE = ulittle16_t(SymKind);
2643-
memcpy(&BytePrefix[0], &SymKindLE, 2);
2644-
memcpy(&BytePrefix[2], &DefRangeHeader, sizeof(T));
2645-
}
2646-
26472636
void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,
26482637
const LocalVariable &Var) {
26492638
// LocalSym record, see SymbolRecord.h for more info.
@@ -2692,8 +2681,9 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,
26922681
(bool(Flags & LocalSymFlags::IsParameter)
26932682
? (EncFP == FI.EncodedParamFramePtrReg)
26942683
: (EncFP == FI.EncodedLocalFramePtrReg))) {
2695-
little32_t FPOffset = little32_t(Offset);
2696-
copyBytesForDefRange(BytePrefix, S_DEFRANGE_FRAMEPOINTER_REL, FPOffset);
2684+
DefRangeFramePointerRelSym::Header DRHdr;
2685+
DRHdr.Offset = Offset;
2686+
OS.EmitCVDefRangeDirective(DefRange.Ranges, DRHdr);
26972687
} else {
26982688
uint16_t RegRelFlags = 0;
26992689
if (DefRange.IsSubfield) {
@@ -2705,7 +2695,7 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,
27052695
DRHdr.Register = Reg;
27062696
DRHdr.Flags = RegRelFlags;
27072697
DRHdr.BasePointerOffset = Offset;
2708-
copyBytesForDefRange(BytePrefix, S_DEFRANGE_REGISTER_REL, DRHdr);
2698+
OS.EmitCVDefRangeDirective(DefRange.Ranges, DRHdr);
27092699
}
27102700
} else {
27112701
assert(DefRange.DataOffset == 0 && "unexpected offset into register");
@@ -2714,15 +2704,14 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,
27142704
DRHdr.Register = DefRange.CVRegister;
27152705
DRHdr.MayHaveNoName = 0;
27162706
DRHdr.OffsetInParent = DefRange.StructOffset;
2717-
copyBytesForDefRange(BytePrefix, S_DEFRANGE_SUBFIELD_REGISTER, DRHdr);
2707+
OS.EmitCVDefRangeDirective(DefRange.Ranges, DRHdr);
27182708
} else {
27192709
DefRangeRegisterSym::Header DRHdr;
27202710
DRHdr.Register = DefRange.CVRegister;
27212711
DRHdr.MayHaveNoName = 0;
2722-
copyBytesForDefRange(BytePrefix, S_DEFRANGE_REGISTER, DRHdr);
2712+
OS.EmitCVDefRangeDirective(DefRange.Ranges, DRHdr);
27232713
}
27242714
}
2725-
OS.EmitCVDefRangeDirective(DefRange.Ranges, BytePrefix);
27262715
}
27272716
}
27282717

lib/DebugInfo/CodeView/SymbolDumper.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ Error CVSymbolDumperImpl::visitKnownRecord(
315315

316316
Error CVSymbolDumperImpl::visitKnownRecord(
317317
CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
318-
W.printNumber("Offset", DefRangeFramePointerRel.Offset);
318+
W.printNumber("Offset", DefRangeFramePointerRel.Hdr.Offset);
319319
printLocalVariableAddrRange(DefRangeFramePointerRel.Range,
320320
DefRangeFramePointerRel.getRelocationOffset());
321321
printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);

lib/DebugInfo/CodeView/SymbolRecordMapping.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, DataSym &Data) {
229229
Error SymbolRecordMapping::visitKnownRecord(
230230
CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
231231

232-
error(IO.mapInteger(DefRangeFramePointerRel.Offset));
232+
error(IO.mapObject(DefRangeFramePointerRel.Hdr.Offset));
233233
error(mapLocalVariableAddrRange(IO, DefRangeFramePointerRel.Range));
234234
error(IO.mapVectorTail(DefRangeFramePointerRel.Gaps, MapGap()));
235235

lib/MC/MCAsmStreamer.cpp

+56-7
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,26 @@ class MCAsmStreamer final : public MCStreamer {
254254
unsigned SourceLineNum,
255255
const MCSymbol *FnStartSym,
256256
const MCSymbol *FnEndSym) override;
257+
258+
void PrintCVDefRangePrefix(
259+
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges);
260+
261+
void EmitCVDefRangeDirective(
262+
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
263+
codeview::DefRangeRegisterRelSym::Header DRHdr) override;
264+
257265
void EmitCVDefRangeDirective(
258266
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
259-
StringRef FixedSizePortion) override;
267+
codeview::DefRangeSubfieldRegisterSym::Header DRHdr) override;
268+
269+
void EmitCVDefRangeDirective(
270+
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
271+
codeview::DefRangeRegisterSym::Header DRHdr) override;
272+
273+
void EmitCVDefRangeDirective(
274+
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
275+
codeview::DefRangeFramePointerRelSym::Header DRHdr) override;
276+
260277
void EmitCVStringTableDirective() override;
261278
void EmitCVFileChecksumsDirective() override;
262279
void EmitCVFileChecksumOffsetDirective(unsigned FileNo) override;
@@ -1376,20 +1393,52 @@ void MCAsmStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
13761393
PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
13771394
}
13781395

1379-
void MCAsmStreamer::EmitCVDefRangeDirective(
1380-
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1381-
StringRef FixedSizePortion) {
1396+
void MCAsmStreamer::PrintCVDefRangePrefix(
1397+
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges) {
13821398
OS << "\t.cv_def_range\t";
13831399
for (std::pair<const MCSymbol *, const MCSymbol *> Range : Ranges) {
13841400
OS << ' ';
13851401
Range.first->print(OS, MAI);
13861402
OS << ' ';
13871403
Range.second->print(OS, MAI);
13881404
}
1389-
OS << ", ";
1390-
PrintQuotedString(FixedSizePortion, OS);
1405+
}
1406+
1407+
void MCAsmStreamer::EmitCVDefRangeDirective(
1408+
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1409+
codeview::DefRangeRegisterRelSym::Header DRHdr) {
1410+
PrintCVDefRangePrefix(Ranges);
1411+
OS << ", reg_rel, ";
1412+
OS << DRHdr.Register << ", " << DRHdr.Flags << ", "
1413+
<< DRHdr.BasePointerOffset;
1414+
EmitEOL();
1415+
}
1416+
1417+
void MCAsmStreamer::EmitCVDefRangeDirective(
1418+
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1419+
codeview::DefRangeSubfieldRegisterSym::Header DRHdr) {
1420+
PrintCVDefRangePrefix(Ranges);
1421+
OS << ", subfield_reg, ";
1422+
OS << DRHdr.Register << ", " << DRHdr.OffsetInParent;
1423+
EmitEOL();
1424+
}
1425+
1426+
void MCAsmStreamer::EmitCVDefRangeDirective(
1427+
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1428+
codeview::DefRangeRegisterSym::Header DRHdr) {
1429+
PrintCVDefRangePrefix(Ranges);
1430+
OS << ", reg, ";
1431+
OS << DRHdr.Register;
1432+
EmitEOL();
1433+
}
1434+
1435+
void MCAsmStreamer::EmitCVDefRangeDirective(
1436+
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1437+
codeview::DefRangeFramePointerRelSym::Header DRHdr) {
1438+
PrintCVDefRangePrefix(Ranges);
1439+
OS << ", frame_ptr_rel, ";
1440+
OS << DRHdr.Offset;
13911441
EmitEOL();
1392-
this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);
13931442
}
13941443

13951444
void MCAsmStreamer::EmitCVStringTableDirective() {

lib/MC/MCParser/AsmParser.cpp

+109-7
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,19 @@ class AsmParser : public MCAsmParser {
524524
/// directives parsed by this class.
525525
StringMap<DirectiveKind> DirectiveKindMap;
526526

527+
// Codeview def_range type parsing.
528+
enum CVDefRangeType {
529+
CVDR_DEFRANGE = 0, // Placeholder
530+
CVDR_DEFRANGE_REGISTER,
531+
CVDR_DEFRANGE_FRAMEPOINTER_REL,
532+
CVDR_DEFRANGE_SUBFIELD_REGISTER,
533+
CVDR_DEFRANGE_REGISTER_REL
534+
};
535+
536+
/// Maps Codeview def_range types --> CVDefRangeType enum, for
537+
/// Codeview def_range types parsed by this class.
538+
StringMap<CVDefRangeType> CVDefRangeTypeMap;
539+
527540
// ".ascii", ".asciz", ".string"
528541
bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
529542
bool parseDirectiveReloc(SMLoc DirectiveLoc); // ".reloc"
@@ -671,6 +684,7 @@ class AsmParser : public MCAsmParser {
671684
bool parseDirectiveAddrsigSym();
672685

673686
void initializeDirectiveKindMap();
687+
void initializeCVDefRangeTypeMap();
674688
};
675689

676690
} // end anonymous namespace
@@ -720,6 +734,7 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
720734

721735
PlatformParser->Initialize(*this);
722736
initializeDirectiveKindMap();
737+
initializeCVDefRangeTypeMap();
723738

724739
NumOfMacroInstantiations = 0;
725740
}
@@ -1737,6 +1752,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
17371752
StringMap<DirectiveKind>::const_iterator DirKindIt =
17381753
DirectiveKindMap.find(IDVal);
17391754
DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
1755+
17401756
? DK_NO_DIRECTIVE
17411757
: DirKindIt->getValue();
17421758
switch (DirKind) {
@@ -3825,6 +3841,13 @@ bool AsmParser::parseDirectiveCVInlineLinetable() {
38253841
return false;
38263842
}
38273843

3844+
void AsmParser::initializeCVDefRangeTypeMap() {
3845+
CVDefRangeTypeMap["reg"] = CVDR_DEFRANGE_REGISTER;
3846+
CVDefRangeTypeMap["frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
3847+
CVDefRangeTypeMap["subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
3848+
CVDefRangeTypeMap["reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
3849+
}
3850+
38283851
/// parseDirectiveCVDefRange
38293852
/// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes*
38303853
bool AsmParser::parseDirectiveCVDefRange() {
@@ -3846,13 +3869,92 @@ bool AsmParser::parseDirectiveCVDefRange() {
38463869
Ranges.push_back({GapStartSym, GapEndSym});
38473870
}
38483871

3849-
std::string FixedSizePortion;
3850-
if (parseToken(AsmToken::Comma, "unexpected token in directive") ||
3851-
parseEscapedString(FixedSizePortion))
3852-
return true;
3853-
3854-
getStreamer().EmitCVDefRangeDirective(Ranges, FixedSizePortion);
3855-
return false;
3872+
StringRef CVDefRangeTypeStr;
3873+
if (parseToken(
3874+
AsmToken::Comma,
3875+
"expected comma before def_range type in .cv_def_range directive") ||
3876+
parseIdentifier(CVDefRangeTypeStr))
3877+
return Error(Loc, "expected def_range type in directive");
3878+
3879+
StringMap<CVDefRangeType>::const_iterator CVTypeIt =
3880+
CVDefRangeTypeMap.find(CVDefRangeTypeStr);
3881+
CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
3882+
? CVDR_DEFRANGE
3883+
: CVTypeIt->getValue();
3884+
switch (CVDRType) {
3885+
case CVDR_DEFRANGE_REGISTER: {
3886+
int64_t DRRegister;
3887+
if (parseToken(AsmToken::Comma, "expected comma before register number in "
3888+
".cv_def_range directive") ||
3889+
parseAbsoluteExpression(DRRegister))
3890+
return Error(Loc, "expected register number");
3891+
3892+
codeview::DefRangeRegisterSym::Header DRHdr;
3893+
DRHdr.Register = DRRegister;
3894+
DRHdr.MayHaveNoName = 0;
3895+
getStreamer().EmitCVDefRangeDirective(Ranges, DRHdr);
3896+
break;
3897+
}
3898+
case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
3899+
int64_t DROffset;
3900+
if (parseToken(AsmToken::Comma,
3901+
"expected comma before offset in .cv_def_range directive") ||
3902+
parseAbsoluteExpression(DROffset))
3903+
return Error(Loc, "expected offset value");
3904+
3905+
codeview::DefRangeFramePointerRelSym::Header DRHdr;
3906+
DRHdr.Offset = DROffset;
3907+
getStreamer().EmitCVDefRangeDirective(Ranges, DRHdr);
3908+
break;
3909+
}
3910+
case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
3911+
int64_t DRRegister;
3912+
int64_t DROffsetInParent;
3913+
if (parseToken(AsmToken::Comma, "expected comma before register number in "
3914+
".cv_def_range directive") ||
3915+
parseAbsoluteExpression(DRRegister))
3916+
return Error(Loc, "expected register number");
3917+
if (parseToken(AsmToken::Comma,
3918+
"expected comma before offset in .cv_def_range directive") ||
3919+
parseAbsoluteExpression(DROffsetInParent))
3920+
return Error(Loc, "expected offset value");
3921+
3922+
codeview::DefRangeSubfieldRegisterSym::Header DRHdr;
3923+
DRHdr.Register = DRRegister;
3924+
DRHdr.MayHaveNoName = 0;
3925+
DRHdr.OffsetInParent = DROffsetInParent;
3926+
getStreamer().EmitCVDefRangeDirective(Ranges, DRHdr);
3927+
break;
3928+
}
3929+
case CVDR_DEFRANGE_REGISTER_REL: {
3930+
int64_t DRRegister;
3931+
int64_t DRFlags;
3932+
int64_t DRBasePointerOffset;
3933+
if (parseToken(AsmToken::Comma, "expected comma before register number in "
3934+
".cv_def_range directive") ||
3935+
parseAbsoluteExpression(DRRegister))
3936+
return Error(Loc, "expected register value");
3937+
if (parseToken(
3938+
AsmToken::Comma,
3939+
"expected comma before flag value in .cv_def_range directive") ||
3940+
parseAbsoluteExpression(DRFlags))
3941+
return Error(Loc, "expected flag value");
3942+
if (parseToken(AsmToken::Comma, "expected comma before base pointer offset "
3943+
"in .cv_def_range directive") ||
3944+
parseAbsoluteExpression(DRBasePointerOffset))
3945+
return Error(Loc, "expected base pointer offset value");
3946+
3947+
codeview::DefRangeRegisterRelSym::Header DRHdr;
3948+
DRHdr.Register = DRRegister;
3949+
DRHdr.Flags = DRFlags;
3950+
DRHdr.BasePointerOffset = DRBasePointerOffset;
3951+
getStreamer().EmitCVDefRangeDirective(Ranges, DRHdr);
3952+
break;
3953+
}
3954+
default:
3955+
return Error(Loc, "unexpected def_range type in .cv_def_range directive");
3956+
}
3957+
return true;
38563958
}
38573959

38583960
/// parseDirectiveCVString

0 commit comments

Comments
 (0)