LLVM  16.0.0git
NativeInlineSiteSymbol.cpp
Go to the documentation of this file.
1 //===- NativeInlineSiteSymbol.cpp - info about inline sites -----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
23 
24 using namespace llvm;
25 using namespace llvm::codeview;
26 using namespace llvm::pdb;
27 
28 NativeInlineSiteSymbol::NativeInlineSiteSymbol(
29  NativeSession &Session, SymIndexId Id, const codeview::InlineSiteSym &Sym,
30  uint64_t ParentAddr)
31  : NativeRawSymbol(Session, PDB_SymType::InlineSite, Id), Sym(Sym),
32  ParentAddr(ParentAddr) {}
33 
35 
37  PdbSymbolIdField ShowIdFields,
38  PdbSymbolIdField RecurseIdFields) const {
39  NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
40  dumpSymbolField(OS, "name", getName(), Indent);
41 }
42 
45  for (const auto &SS : ModS.getSubsectionsArray()) {
46  if (SS.kind() != DebugSubsectionKind::InlineeLines)
47  continue;
48 
50  BinaryStreamReader Reader(SS.getRecordData());
51  if (auto EC = InlineeLines.initialize(Reader)) {
53  continue;
54  }
55 
56  for (const InlineeSourceLine &Line : InlineeLines)
57  if (Line.Header->Inlinee == Id)
58  return Line;
59  }
60  return None;
61 }
62 
63 std::string NativeInlineSiteSymbol::getName() const {
64  auto Tpi = Session.getPDBFile().getPDBTpiStream();
65  if (!Tpi) {
66  consumeError(Tpi.takeError());
67  return "";
68  }
69  auto Ipi = Session.getPDBFile().getPDBIpiStream();
70  if (!Ipi) {
71  consumeError(Ipi.takeError());
72  return "";
73  }
74 
75  LazyRandomTypeCollection &Types = Tpi->typeCollection();
76  LazyRandomTypeCollection &Ids = Ipi->typeCollection();
77  CVType InlineeType = Ids.getType(Sym.Inlinee);
78  std::string QualifiedName;
79  if (InlineeType.kind() == LF_MFUNC_ID) {
80  MemberFuncIdRecord MFRecord;
81  cantFail(TypeDeserializer::deserializeAs<MemberFuncIdRecord>(InlineeType,
82  MFRecord));
83  TypeIndex ClassTy = MFRecord.getClassType();
84  QualifiedName.append(std::string(Types.getTypeName(ClassTy)));
85  QualifiedName.append("::");
86  } else if (InlineeType.kind() == LF_FUNC_ID) {
87  FuncIdRecord FRecord;
88  cantFail(
89  TypeDeserializer::deserializeAs<FuncIdRecord>(InlineeType, FRecord));
90  TypeIndex ParentScope = FRecord.getParentScope();
91  if (!ParentScope.isNoneType()) {
92  QualifiedName.append(std::string(Ids.getTypeName(ParentScope)));
93  QualifiedName.append("::");
94  }
95  }
96 
97  QualifiedName.append(std::string(Ids.getTypeName(Sym.Inlinee)));
98  return QualifiedName;
99 }
100 
101 void NativeInlineSiteSymbol::getLineOffset(uint32_t OffsetInFunc,
102  uint32_t &LineOffset,
103  uint32_t &FileOffset) const {
104  LineOffset = 0;
105  FileOffset = 0;
106  uint32_t CodeOffset = 0;
107  Optional<uint32_t> CodeOffsetBase;
108  Optional<uint32_t> CodeOffsetEnd;
109  Optional<int32_t> CurLineOffset;
110  Optional<int32_t> NextLineOffset;
111  Optional<uint32_t> NextFileOffset;
112  auto UpdateCodeOffset = [&](uint32_t Delta) {
113  if (!CodeOffsetBase)
114  CodeOffsetBase = CodeOffset;
115  else if (!CodeOffsetEnd)
116  CodeOffsetEnd = *CodeOffsetBase + Delta;
117  };
118  auto UpdateLineOffset = [&](int32_t Delta) {
119  LineOffset += Delta;
120  if (!CodeOffsetBase || !CurLineOffset)
121  CurLineOffset = LineOffset;
122  else
123  NextLineOffset = LineOffset;
124  };
125  auto UpdateFileOffset = [&](uint32_t Offset) {
126  if (!CodeOffsetBase)
127  FileOffset = Offset;
128  else
129  NextFileOffset = Offset;
130  };
131  auto ValidateAndReset = [&]() {
132  // Current range is finished. Check if OffsetInFunc is in the range.
133  if (CodeOffsetBase && CodeOffsetEnd && CurLineOffset) {
134  if (CodeOffsetBase <= OffsetInFunc && OffsetInFunc < CodeOffsetEnd) {
135  LineOffset = *CurLineOffset;
136  return true;
137  }
138  // Set base, end, file offset and line offset for next range.
139  if (NextFileOffset)
140  FileOffset = *NextFileOffset;
141  if (NextLineOffset) {
142  CurLineOffset = NextLineOffset;
143  NextLineOffset = None;
144  }
145  CodeOffsetBase = CodeOffsetEnd;
146  CodeOffsetEnd = NextFileOffset = None;
147  }
148  return false;
149  };
150  for (const auto &Annot : Sym.annotations()) {
151  switch (Annot.OpCode) {
152  case BinaryAnnotationsOpCode::CodeOffset:
153  case BinaryAnnotationsOpCode::ChangeCodeOffset:
154  case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
155  CodeOffset += Annot.U1;
156  UpdateCodeOffset(Annot.U1);
157  break;
158  case BinaryAnnotationsOpCode::ChangeCodeLength:
159  UpdateCodeOffset(Annot.U1);
160  break;
161  case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
162  CodeOffset += Annot.U2;
163  UpdateCodeOffset(Annot.U2);
164  UpdateCodeOffset(Annot.U1);
165  break;
166  case BinaryAnnotationsOpCode::ChangeLineOffset:
167  UpdateLineOffset(Annot.S1);
168  break;
169  case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
170  CodeOffset += Annot.U1;
171  UpdateCodeOffset(Annot.U1);
172  UpdateLineOffset(Annot.S1);
173  break;
174  case BinaryAnnotationsOpCode::ChangeFile:
175  UpdateFileOffset(Annot.U1);
176  break;
177  default:
178  break;
179  }
180 
181  if (ValidateAndReset())
182  return;
183  }
184 }
185 
186 std::unique_ptr<IPDBEnumLineNumbers>
188  uint32_t Length) const {
189  uint16_t Modi;
190  if (!Session.moduleIndexForVA(VA, Modi))
191  return nullptr;
192 
194  if (!ModS) {
195  consumeError(ModS.takeError());
196  return nullptr;
197  }
198 
200  ModS->findChecksumsSubsection();
201  if (!Checksums) {
202  consumeError(Checksums.takeError());
203  return nullptr;
204  }
205 
206  // Get the line number offset and source file offset.
207  uint32_t SrcLineOffset;
208  uint32_t SrcFileOffset;
209  getLineOffset(VA - ParentAddr, SrcLineOffset, SrcFileOffset);
210 
211  // Get line info from inlinee line table.
213  findInlineeByTypeIndex(Sym.Inlinee, ModS.get());
214 
215  if (!Inlinee)
216  return nullptr;
217 
218  uint32_t SrcLine = Inlinee->Header->SourceLineNum + SrcLineOffset;
219  uint32_t SrcCol = 0; // Inline sites don't seem to have column info.
220  uint32_t FileChecksumOffset =
221  (SrcFileOffset == 0) ? Inlinee->Header->FileID : SrcFileOffset;
222 
223  auto ChecksumIter = Checksums->getArray().at(FileChecksumOffset);
224  uint32_t SrcFileId =
226 
227  uint32_t LineSect, LineOff;
228  Session.addressForVA(VA, LineSect, LineOff);
229  NativeLineNumber LineNum(Session, SrcLine, SrcCol, LineSect, LineOff, Length,
230  SrcFileId, Modi);
231  auto SrcFile = Session.getSymbolCache().getSourceFileById(SrcFileId);
232  std::vector<NativeLineNumber> Lines{LineNum};
233 
234  return std::make_unique<NativeEnumLineNumbers>(std::move(Lines));
235 }
llvm::codeview::TypeIndex::isNoneType
bool isNoneType() const
Definition: TypeIndex.h:116
llvm::codeview::InlineeSourceLine
Definition: DebugInlineeLinesSubsection.h:44
llvm::codeview::DebugSubsectionKind::InlineeLines
@ InlineeLines
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::InlineSite
std::tuple< uint64_t, uint32_t > InlineSite
Definition: MCPseudoProbe.h:96
TpiStream.h
llvm::pdb::ModuleDebugStreamRef
Definition: ModuleDebugStream.h:31
llvm::codeview::DebugSubsectionKind::Lines
@ Lines
SymbolRecord.h
llvm::pdb::SymbolCache::getSourceFileById
std::unique_ptr< IPDBSourceFile > getSourceFileById(SymIndexId FileId) const
Definition: SymbolCache.cpp:614
llvm::codeview::Line
Definition: Line.h:90
NativeEnumLineNumbers.h
llvm::pdb::NativeSession::getPDBFile
PDBFile & getPDBFile()
Definition: NativeSession.h:109
llvm::pdb::NativeInlineSiteSymbol::dump
void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, PdbSymbolIdField RecurseIdFields) const override
Definition: NativeInlineSiteSymbol.cpp:36
llvm::Optional
Definition: APInt.h:33
llvm::pdb::NativeLineNumber
Definition: NativeLineNumber.h:20
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::codeview::FuncIdRecord::getParentScope
TypeIndex getParentScope() const
Definition: TypeRecord.h:618
llvm::pdb::NativeSession::getModuleDebugStream
Expected< ModuleDebugStreamRef > getModuleDebugStream(uint32_t Index) const
Definition: NativeSession.cpp:453
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1042
llvm::pdb::PDB_SymType
PDB_SymType
These values correspond to the SymTagEnum enumeration, and are documented here: https://msdn....
Definition: PDBTypes.h:243
llvm::X86AS::SS
@ SS
Definition: X86.h:201
llvm::codeview::LazyRandomTypeCollection::getTypeName
StringRef getTypeName(TypeIndex Index) override
Definition: LazyRandomTypeCollection.cpp:114
llvm::pdb::NativeSession::moduleIndexForVA
bool moduleIndexForVA(uint64_t VA, uint16_t &ModuleIndex) const
Definition: NativeSession.cpp:402
llvm::pdb::PDBFile::getPDBIpiStream
Expected< TpiStream & > getPDBIpiStream()
Definition: PDBFile.cpp:314
NativeInlineSiteSymbol.h
llvm::codeview::InlineSiteSym
Definition: SymbolRecord.h:333
LazyRandomTypeCollection.h
llvm::codeview::LazyRandomTypeCollection
Provides amortized O(1) random access to a CodeView type stream.
Definition: LazyRandomTypeCollection.h:49
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
llvm::codeview::BinaryAnnotationsOpCode::CodeOffset
@ CodeOffset
llvm::pdb::NativeInlineSiteSymbol::findInlineeLinesByVA
std::unique_ptr< IPDBEnumLineNumbers > findInlineeLinesByVA(uint64_t VA, uint32_t Length) const override
Definition: NativeInlineSiteSymbol.cpp:187
llvm::pdb
Definition: ConcreteSymbolEnumerator.h:20
llvm::BinaryStreamReader
Provides read only access to a subclass of BinaryStream.
Definition: BinaryStreamReader.h:29
llvm::pdb::NativeInlineSiteSymbol::~NativeInlineSiteSymbol
~NativeInlineSiteSymbol() override
uint64_t
llvm::pdb::dumpSymbolField
void dumpSymbolField(raw_ostream &OS, StringRef Name, T Value, int Indent)
Definition: PDBExtras.h:47
llvm::codeview::InlineSiteSym::Inlinee
TypeIndex Inlinee
Definition: SymbolRecord.h:347
llvm::codeview::CVRecord::kind
Kind kind() const
Definition: CVRecord.h:42
QualifiedName
Definition: ItaniumDemangle.h:1055
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::pdb::NativeSession::addressForVA
bool addressForVA(uint64_t VA, uint32_t &Section, uint32_t &Offset) const override
Definition: NativeSession.cpp:220
llvm::pdb::NativeSession::getSymbolCache
SymbolCache & getSymbolCache()
Definition: NativeSession.h:113
llvm::codeview::CompileSym2Flags::EC
@ EC
llvm::codeview::FuncIdRecord
Definition: TypeRecord.h:610
llvm::codeview::MemberFuncIdRecord::getClassType
TypeIndex getClassType() const
Definition: TypeRecord.h:226
llvm::codeview::CVRecord< TypeLeafKind >
llvm::Expected::get
reference get()
Returns a reference to the stored T value.
Definition: Error.h:566
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:744
uint32_t
llvm::pdb::PDBFile::getPDBTpiStream
Expected< TpiStream & > getPDBTpiStream()
Definition: PDBFile.cpp:301
DebugInlineeLinesSubsection.h
llvm::pdb::PDB_SymType::Inlinee
@ Inlinee
llvm::None
constexpr std::nullopt_t None
Definition: None.h:27
uint16_t
TypeDeserializer.h
llvm::pdb::NativeRawSymbol::dump
void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields, PdbSymbolIdField RecurseIdFields) const override
Definition: NativeRawSymbol.cpp:21
llvm::codeview::DebugInlineeLinesSubsectionRef
Definition: DebugInlineeLinesSubsection.h:60
ModuleDebugStream.h
llvm::pdb::NativeSession
Definition: NativeSession.h:32
llvm::codeview::MemberFuncIdRecord
Definition: TypeRecord.h:217
llvm::pdb::NativeInlineSiteSymbol::getName
std::string getName() const override
Definition: NativeInlineSiteSymbol.cpp:63
llvm::codeview
Definition: AppendingTypeTableBuilder.h:22
llvm::pdb::PdbSymbolIdField
PdbSymbolIdField
Definition: IPDBRawSymbol.h:24
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:596
PDBFile.h
PDBExtras.h
SymbolCache.h
llvm::codeview::TypeIndex
A 32-bit type reference.
Definition: TypeIndex.h:96
llvm::pdb::ModuleDebugStreamRef::getSubsectionsArray
codeview::DebugSubsectionArray getSubsectionsArray() const
Definition: ModuleDebugStream.h:62
llvm::pdb::NativeRawSymbol::Session
NativeSession & Session
Definition: NativeRawSymbol.h:232
llvm::codeview::LazyRandomTypeCollection::getType
CVType getType(TypeIndex Index) override
Definition: LazyRandomTypeCollection.cpp:91
llvm::pdb::SymbolCache::getOrCreateSourceFile
SymIndexId getOrCreateSourceFile(const codeview::FileChecksumEntry &Checksum) const
Definition: SymbolCache.cpp:626
llvm::AMDGPU::VGPRIndexMode::Id
Id
Definition: SIDefines.h:241
NativeLineNumber.h
llvm::codeview::InlineSiteSym::annotations
iterator_range< BinaryAnnotationIterator > annotations() const
Definition: SymbolRecord.h:340
llvm::pdb::NativeRawSymbol
Definition: NativeRawSymbol.h:21
findInlineeByTypeIndex
static Optional< InlineeSourceLine > findInlineeByTypeIndex(TypeIndex Id, ModuleDebugStreamRef &ModS)
Definition: NativeInlineSiteSymbol.cpp:44
NativeSession.h