diff options
Diffstat (limited to 'lib/MC/MCCodeView.cpp')
-rw-r--r-- | lib/MC/MCCodeView.cpp | 86 |
1 files changed, 84 insertions, 2 deletions
diff --git a/lib/MC/MCCodeView.cpp b/lib/MC/MCCodeView.cpp index 82b81ccc24da..155fd7eeb576 100644 --- a/lib/MC/MCCodeView.cpp +++ b/lib/MC/MCCodeView.cpp @@ -76,6 +76,14 @@ bool CodeViewContext::addFile(MCStreamer &OS, unsigned FileNumber, return true; } +MCCVFunctionInfo *CodeViewContext::getCVFunctionInfo(unsigned FuncId) { + if (FuncId >= Functions.size()) + return nullptr; + if (Functions[FuncId].isUnallocatedFunctionInfo()) + return nullptr; + return &Functions[FuncId]; +} + bool CodeViewContext::recordFunctionId(unsigned FuncId) { if (FuncId >= Functions.size()) Functions.resize(FuncId + 1); @@ -247,6 +255,67 @@ void CodeViewContext::emitFileChecksumOffset(MCObjectStreamer &OS, OS.EmitValueImpl(SRE, 4); } +void CodeViewContext::addLineEntry(const MCCVLineEntry &LineEntry) { + size_t Offset = MCCVLines.size(); + auto I = MCCVLineStartStop.insert( + {LineEntry.getFunctionId(), {Offset, Offset + 1}}); + if (!I.second) + I.first->second.second = Offset + 1; + MCCVLines.push_back(LineEntry); +} + +std::vector<MCCVLineEntry> +CodeViewContext::getFunctionLineEntries(unsigned FuncId) { + std::vector<MCCVLineEntry> FilteredLines; + auto I = MCCVLineStartStop.find(FuncId); + if (I != MCCVLineStartStop.end()) { + MCCVFunctionInfo *SiteInfo = getCVFunctionInfo(FuncId); + for (size_t Idx = I->second.first, End = I->second.second; Idx != End; + ++Idx) { + unsigned LocationFuncId = MCCVLines[Idx].getFunctionId(); + if (LocationFuncId == FuncId) { + // This was a .cv_loc directly for FuncId, so record it. + FilteredLines.push_back(MCCVLines[Idx]); + } else { + // Check if the current location is inlined in this function. If it is, + // synthesize a statement .cv_loc at the original inlined call site. + auto I = SiteInfo->InlinedAtMap.find(LocationFuncId); + if (I != SiteInfo->InlinedAtMap.end()) { + MCCVFunctionInfo::LineInfo &IA = I->second; + // Only add the location if it differs from the previous location. + // Large inlined calls will have many .cv_loc entries and we only need + // one line table entry in the parent function. + if (FilteredLines.empty() || + FilteredLines.back().getFileNum() != IA.File || + FilteredLines.back().getLine() != IA.Line || + FilteredLines.back().getColumn() != IA.Col) { + FilteredLines.push_back(MCCVLineEntry( + MCCVLines[Idx].getLabel(), + MCCVLoc(FuncId, IA.File, IA.Line, IA.Col, false, false))); + } + } + } + } + } + return FilteredLines; +} + +std::pair<size_t, size_t> CodeViewContext::getLineExtent(unsigned FuncId) { + auto I = MCCVLineStartStop.find(FuncId); + // Return an empty extent if there are no cv_locs for this function id. + if (I == MCCVLineStartStop.end()) + return {~0ULL, 0}; + return I->second; +} + +ArrayRef<MCCVLineEntry> CodeViewContext::getLinesForExtent(size_t L, size_t R) { + if (R <= L) + return None; + if (L >= MCCVLines.size()) + return None; + return makeArrayRef(&MCCVLines[L], R - L); +} + void CodeViewContext::emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId, const MCSymbol *FuncBegin, @@ -403,6 +472,19 @@ void CodeViewContext::encodeInlineLineTable(MCAsmLayout &Layout, if (Locs.empty()) return; + // Check that the locations are all in the same section. +#ifndef NDEBUG + const MCSection *FirstSec = &Locs.front().getLabel()->getSection(); + for (const MCCVLineEntry &Loc : Locs) { + if (&Loc.getLabel()->getSection() != FirstSec) { + errs() << ".cv_loc " << Loc.getFunctionId() << ' ' << Loc.getFileNum() + << ' ' << Loc.getLine() << ' ' << Loc.getColumn() + << " is in the wrong section\n"; + llvm_unreachable(".cv_loc crosses sections"); + } + } +#endif + // Make an artificial start location using the function start and the inlinee // lines start location information. All deltas start relative to this // location. @@ -507,7 +589,7 @@ void CodeViewContext::encodeInlineLineTable(MCAsmLayout &Layout, if (!LocAfter.empty()) { // Only try to compute this difference if we're in the same section. const MCCVLineEntry &Loc = LocAfter[0]; - if (&Loc.getLabel()->getSection(false) == &LastLabel->getSection(false)) + if (&Loc.getLabel()->getSection() == &LastLabel->getSection()) LocAfterLength = computeLabelDiff(Layout, LastLabel, Loc.getLabel()); } @@ -550,7 +632,7 @@ void CodeViewContext::encodeDefRange(MCAsmLayout &Layout, } unsigned NumGaps = J - I - 1; - support::endian::Writer<support::little> LEWriter(OS); + support::endian::Writer LEWriter(OS, support::little); unsigned Bias = 0; // We must split the range into chunks of MaxDefRange, this is a fundamental |