summaryrefslogtreecommitdiff
path: root/lib/MC/MCCodeView.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC/MCCodeView.cpp')
-rw-r--r--lib/MC/MCCodeView.cpp86
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