aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
commit145449b1e420787bb99721a429341fa6be3adfb6 (patch)
tree1d56ae694a6de602e348dd80165cf881a36600ed /llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
parentecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff)
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp123
1 files changed, 59 insertions, 64 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 52c74713551c..701c0affdfa6 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -11,7 +11,6 @@
//===----------------------------------------------------------------------===//
#include "CodeViewDebug.h"
-#include "DwarfExpression.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
@@ -29,7 +28,6 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
@@ -41,7 +39,6 @@
#include "llvm/DebugInfo/CodeView/EnumTables.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeTableCollection.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
@@ -58,11 +55,8 @@
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Support/BinaryByteStream.h"
-#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
@@ -230,7 +224,7 @@ unsigned CodeViewDebug::maybeRecordFile(const DIFile *F) {
break;
}
}
- bool Success = OS.EmitCVFileDirective(NextId, FullPath, ChecksumAsBytes,
+ bool Success = OS.emitCVFileDirective(NextId, FullPath, ChecksumAsBytes,
static_cast<unsigned>(CSKind));
(void)Success;
assert(Success && ".cv_file directive failed");
@@ -251,7 +245,7 @@ CodeViewDebug::getInlineSite(const DILocation *InlinedAt,
.SiteFuncId;
Site->SiteFuncId = NextFuncId++;
- OS.EmitCVInlineSiteIdDirective(
+ OS.emitCVInlineSiteIdDirective(
Site->SiteFuncId, ParentFuncId, maybeRecordFile(InlinedAt->getFile()),
InlinedAt->getLine(), InlinedAt->getColumn(), SMLoc());
Site->Inlinee = Inlinee;
@@ -515,7 +509,7 @@ void CodeViewDebug::maybeRecordLocation(const DebugLoc &DL,
if (!DL || DL == PrevInstLoc)
return;
- const DIScope *Scope = DL.get()->getScope();
+ const DIScope *Scope = DL->getScope();
if (!Scope)
return;
@@ -614,18 +608,16 @@ static SourceLanguage MapDWLangToCVLang(unsigned DWLang) {
void CodeViewDebug::beginModule(Module *M) {
// If module doesn't have named metadata anchors or COFF debug section
// is not available, skip any debug info related stuff.
- NamedMDNode *CUs = M->getNamedMetadata("llvm.dbg.cu");
- if (!CUs || !Asm->getObjFileLowering().getCOFFDebugSymbolsSection()) {
+ if (!MMI->hasDebugInfo() ||
+ !Asm->getObjFileLowering().getCOFFDebugSymbolsSection()) {
Asm = nullptr;
return;
}
- // Tell MMI that we have and need debug info.
- MMI->setDebugInfoAvailability(true);
TheCPU = mapArchToCVCPUType(Triple(M->getTargetTriple()).getArch());
// Get the current source language.
- const MDNode *Node = *CUs->operands().begin();
+ const MDNode *Node = *M->debug_compile_units_begin();
const auto *CU = cast<DICompileUnit>(Node);
CurrentSourceLanguage = MapDWLangToCVLang(CU->getSourceLanguage());
@@ -727,7 +719,7 @@ void CodeViewDebug::emitTypeInformation() {
return;
// Start the .debug$T or .debug$P section with 0x4.
- OS.SwitchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection());
+ OS.switchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection());
emitCodeViewMagicVersion();
TypeTableCollection Table(TypeTable.records());
@@ -760,7 +752,7 @@ void CodeViewDebug::emitTypeGlobalHashes() {
// Start the .debug$H section with the version and hash algorithm, currently
// hardcoded to version 0, SHA1.
- OS.SwitchSection(Asm->getObjFileLowering().getCOFFGlobalTypeHashesSection());
+ OS.switchSection(Asm->getObjFileLowering().getCOFFGlobalTypeHashesSection());
OS.emitValueToAlignment(4);
OS.AddComment("Magic");
@@ -826,6 +818,8 @@ static Version parseVersion(StringRef Name) {
if (isdigit(C)) {
V.Part[N] *= 10;
V.Part[N] += C - '0';
+ V.Part[N] =
+ std::min<int>(V.Part[N], std::numeric_limits<uint16_t>::max());
} else if (C == '.') {
++N;
if (N >= 4)
@@ -867,7 +861,6 @@ void CodeViewDebug::emitCompilerInformation() {
Version FrontVer = parseVersion(CompilerVersion);
OS.AddComment("Frontend version");
for (int N : FrontVer.Part) {
- N = std::min<int>(N, std::numeric_limits<uint16_t>::max());
OS.emitInt16(N);
}
@@ -985,11 +978,11 @@ void CodeViewDebug::emitInlineeLinesSubsection() {
assert(TypeIndices.count({SP, nullptr}));
TypeIndex InlineeIdx = TypeIndices[{SP, nullptr}];
- OS.AddBlankLine();
+ OS.addBlankLine();
unsigned FileId = maybeRecordFile(SP->getFile());
OS.AddComment("Inlined function " + SP->getName() + " starts at " +
SP->getFilename() + Twine(':') + Twine(SP->getLine()));
- OS.AddBlankLine();
+ OS.addBlankLine();
OS.AddComment("Type index of inlined function");
OS.emitInt32(InlineeIdx.getIndex());
OS.AddComment("Offset into filechecksum table");
@@ -1051,7 +1044,7 @@ void CodeViewDebug::switchToDebugSectionForSymbol(const MCSymbol *GVSym) {
Asm->getObjFileLowering().getCOFFDebugSymbolsSection());
DebugSec = OS.getContext().getAssociativeCOFFSection(DebugSec, KeySym);
- OS.SwitchSection(DebugSec);
+ OS.switchSection(DebugSec);
// Emit the magic version number if this is the first time we've switched to
// this section.
@@ -1080,9 +1073,9 @@ void CodeViewDebug::emitDebugInfoForThunk(const Function *GV,
OS.AddComment("PtrNext");
OS.emitInt32(0);
OS.AddComment("Thunk section relative address");
- OS.EmitCOFFSecRel32(Fn, /*Offset=*/0);
+ OS.emitCOFFSecRel32(Fn, /*Offset=*/0);
OS.AddComment("Thunk section index");
- OS.EmitCOFFSectionIndex(Fn);
+ OS.emitCOFFSectionIndex(Fn);
OS.AddComment("Code size");
OS.emitAbsoluteSymbolDiff(FI.End, Fn, 2);
OS.AddComment("Ordinal");
@@ -1132,7 +1125,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
// Emit FPO data, but only on 32-bit x86. No other platforms use it.
if (Triple(MMI->getModule()->getTargetTriple()).getArch() == Triple::x86)
- OS.EmitCVFPOData(Fn);
+ OS.emitCVFPOData(Fn);
// Emit a symbol subsection, required by VS2012+ to find function boundaries.
OS.AddComment("Symbol subsection for " + Twine(FuncName));
@@ -1160,9 +1153,9 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
OS.AddComment("Function type index");
OS.emitInt32(getFuncIdForSubprogram(GV->getSubprogram()).getIndex());
OS.AddComment("Function section relative address");
- OS.EmitCOFFSecRel32(Fn, /*Offset=*/0);
+ OS.emitCOFFSecRel32(Fn, /*Offset=*/0);
OS.AddComment("Function section index");
- OS.EmitCOFFSectionIndex(Fn);
+ OS.emitCOFFSectionIndex(Fn);
OS.AddComment("Flags");
OS.emitInt8(0);
// Emit the function display name as a null-terminated string.
@@ -1207,9 +1200,9 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
MCSymbol *Label = Annot.first;
MDTuple *Strs = cast<MDTuple>(Annot.second);
MCSymbol *AnnotEnd = beginSymbolRecord(SymbolKind::S_ANNOTATION);
- OS.EmitCOFFSecRel32(Label, /*Offset=*/0);
+ OS.emitCOFFSecRel32(Label, /*Offset=*/0);
// FIXME: Make sure we don't overflow the max record size.
- OS.EmitCOFFSectionIndex(Label);
+ OS.emitCOFFSectionIndex(Label);
OS.emitInt16(Strs->getNumOperands());
for (Metadata *MD : Strs->operands()) {
// MDStrings are null terminated, so we can do EmitBytes and get the
@@ -1227,9 +1220,9 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
const DIType *DITy = std::get<2>(HeapAllocSite);
MCSymbol *HeapAllocEnd = beginSymbolRecord(SymbolKind::S_HEAPALLOCSITE);
OS.AddComment("Call site offset");
- OS.EmitCOFFSecRel32(BeginLabel, /*Offset=*/0);
+ OS.emitCOFFSecRel32(BeginLabel, /*Offset=*/0);
OS.AddComment("Call site section index");
- OS.EmitCOFFSectionIndex(BeginLabel);
+ OS.emitCOFFSectionIndex(BeginLabel);
OS.AddComment("Call instruction length");
OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 2);
OS.AddComment("Type index");
@@ -1249,9 +1242,9 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
OS.emitCVLinetableDirective(FI.FuncId, Fn, FI.End);
}
-CodeViewDebug::LocalVarDefRange
+CodeViewDebug::LocalVarDef
CodeViewDebug::createDefRangeMem(uint16_t CVRegister, int Offset) {
- LocalVarDefRange DR;
+ LocalVarDef DR;
DR.InMemory = -1;
DR.DataOffset = Offset;
assert(DR.DataOffset == Offset && "truncation");
@@ -1303,19 +1296,19 @@ void CodeViewDebug::collectVariableInfoFromMFTable(
"Frame offsets with a scalable component are not supported");
// Calculate the label ranges.
- LocalVarDefRange DefRange =
+ LocalVarDef DefRange =
createDefRangeMem(CVReg, FrameOffset.getFixed() + ExprOffset);
+ LocalVariable Var;
+ Var.DIVar = VI.Var;
+
for (const InsnRange &Range : Scope->getRanges()) {
const MCSymbol *Begin = getLabelBeforeInsn(Range.first);
const MCSymbol *End = getLabelAfterInsn(Range.second);
End = End ? End : Asm->getFunctionEnd();
- DefRange.Ranges.emplace_back(Begin, End);
+ Var.DefRanges[DefRange].emplace_back(Begin, End);
}
- LocalVariable Var;
- Var.DIVar = VI.Var;
- Var.DefRanges.emplace_back(std::move(DefRange));
if (Deref)
Var.UseReferenceType = true;
@@ -1374,24 +1367,18 @@ void CodeViewDebug::calculateRanges(
// We can only handle a register or an offseted load of a register.
if (Location->Register == 0 || Location->LoadChain.size() > 1)
continue;
- {
- LocalVarDefRange DR;
- DR.CVRegister = TRI->getCodeViewRegNum(Location->Register);
- DR.InMemory = !Location->LoadChain.empty();
- DR.DataOffset =
- !Location->LoadChain.empty() ? Location->LoadChain.back() : 0;
- if (Location->FragmentInfo) {
- DR.IsSubfield = true;
- DR.StructOffset = Location->FragmentInfo->OffsetInBits / 8;
- } else {
- DR.IsSubfield = false;
- DR.StructOffset = 0;
- }
- if (Var.DefRanges.empty() ||
- Var.DefRanges.back().isDifferentLocation(DR)) {
- Var.DefRanges.emplace_back(std::move(DR));
- }
+ LocalVarDef DR;
+ DR.CVRegister = TRI->getCodeViewRegNum(Location->Register);
+ DR.InMemory = !Location->LoadChain.empty();
+ DR.DataOffset =
+ !Location->LoadChain.empty() ? Location->LoadChain.back() : 0;
+ if (Location->FragmentInfo) {
+ DR.IsSubfield = true;
+ DR.StructOffset = Location->FragmentInfo->OffsetInBits / 8;
+ } else {
+ DR.IsSubfield = false;
+ DR.StructOffset = 0;
}
// Compute the label range.
@@ -1408,7 +1395,7 @@ void CodeViewDebug::calculateRanges(
// If the last range end is our begin, just extend the last range.
// Otherwise make a new range.
SmallVectorImpl<std::pair<const MCSymbol *, const MCSymbol *>> &R =
- Var.DefRanges.back().Ranges;
+ Var.DefRanges[DR];
if (!R.empty() && R.back().second == Begin)
R.back().second = End;
else
@@ -1525,7 +1512,7 @@ void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) {
// FIXME: Set GuardCfg when it is implemented.
CurFn->FrameProcOpts = FPO;
- OS.EmitCVFuncIdDirective(CurFn->FuncId);
+ OS.emitCVFuncIdDirective(CurFn->FuncId);
// Find the end of the function prolog. First known non-DBG_VALUE and
// non-frame setup location marks the beginning of the function body.
@@ -1825,6 +1812,7 @@ TypeIndex CodeViewDebug::lowerTypeBasic(const DIBasicType *Ty) {
break;
case dwarf::DW_ATE_UTF:
switch (ByteSize) {
+ case 1: STK = SimpleTypeKind::Character8; break;
case 2: STK = SimpleTypeKind::Character16; break;
case 4: STK = SimpleTypeKind::Character32; break;
}
@@ -2820,7 +2808,9 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,
// records and on disk formats are described in SymbolRecords.h. BytePrefix
// should be big enough to hold all forms without memory allocation.
SmallString<20> BytePrefix;
- for (const LocalVarDefRange &DefRange : Var.DefRanges) {
+ for (const auto &Pair : Var.DefRanges) {
+ LocalVarDef DefRange = Pair.first;
+ const auto &Ranges = Pair.second;
BytePrefix.clear();
if (DefRange.InMemory) {
int Offset = DefRange.DataOffset;
@@ -2844,7 +2834,7 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,
: (EncFP == FI.EncodedLocalFramePtrReg))) {
DefRangeFramePointerRelHeader DRHdr;
DRHdr.Offset = Offset;
- OS.emitCVDefRangeDirective(DefRange.Ranges, DRHdr);
+ OS.emitCVDefRangeDirective(Ranges, DRHdr);
} else {
uint16_t RegRelFlags = 0;
if (DefRange.IsSubfield) {
@@ -2856,7 +2846,7 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,
DRHdr.Register = Reg;
DRHdr.Flags = RegRelFlags;
DRHdr.BasePointerOffset = Offset;
- OS.emitCVDefRangeDirective(DefRange.Ranges, DRHdr);
+ OS.emitCVDefRangeDirective(Ranges, DRHdr);
}
} else {
assert(DefRange.DataOffset == 0 && "unexpected offset into register");
@@ -2865,12 +2855,12 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,
DRHdr.Register = DefRange.CVRegister;
DRHdr.MayHaveNoName = 0;
DRHdr.OffsetInParent = DefRange.StructOffset;
- OS.emitCVDefRangeDirective(DefRange.Ranges, DRHdr);
+ OS.emitCVDefRangeDirective(Ranges, DRHdr);
} else {
DefRangeRegisterHeader DRHdr;
DRHdr.Register = DefRange.CVRegister;
DRHdr.MayHaveNoName = 0;
- OS.emitCVDefRangeDirective(DefRange.Ranges, DRHdr);
+ OS.emitCVDefRangeDirective(Ranges, DRHdr);
}
}
}
@@ -2894,9 +2884,9 @@ void CodeViewDebug::emitLexicalBlock(const LexicalBlock &Block,
OS.AddComment("Code size");
OS.emitAbsoluteSymbolDiff(Block.End, Block.Begin, 4); // Code Size
OS.AddComment("Function section relative address");
- OS.EmitCOFFSecRel32(Block.Begin, /*Offset=*/0); // Func Offset
+ OS.emitCOFFSecRel32(Block.Begin, /*Offset=*/0); // Func Offset
OS.AddComment("Function section index");
- OS.EmitCOFFSectionIndex(FI.Begin); // Func Symbol
+ OS.emitCOFFSectionIndex(FI.Begin); // Func Symbol
OS.AddComment("Lexical block name");
emitNullTerminatedSymbolName(OS, Block.Name); // Name
endSymbolRecord(RecordEnd);
@@ -3181,6 +3171,11 @@ void CodeViewDebug::collectGlobalVariableInfo() {
for (const auto *GVE : CU->getGlobalVariables()) {
const DIGlobalVariable *DIGV = GVE->getVariable();
const DIExpression *DIE = GVE->getExpression();
+ // Don't emit string literals in CodeView, as the only useful parts are
+ // generally the filename and line number, which isn't possible to output
+ // in CodeView. String literals should be the only unnamed GlobalVariable
+ // with debug info.
+ if (DIGV->getName().empty()) continue;
if ((DIE->getNumElements() == 2) &&
(DIE->getElement(0) == dwarf::DW_OP_plus_uconst))
@@ -3380,10 +3375,10 @@ void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) {
if (CVGlobalVariableOffsets.find(DIGV) != CVGlobalVariableOffsets.end())
// Use the offset seen while collecting info on globals.
Offset = CVGlobalVariableOffsets[DIGV];
- OS.EmitCOFFSecRel32(GVSym, Offset);
+ OS.emitCOFFSecRel32(GVSym, Offset);
OS.AddComment("Segment");
- OS.EmitCOFFSectionIndex(GVSym);
+ OS.emitCOFFSectionIndex(GVSym);
OS.AddComment("Name");
const unsigned LengthOfDataRecord = 12;
emitNullTerminatedSymbolName(OS, QualifiedName, LengthOfDataRecord);