--- /dev/null
+//==- NativeEnumLineNumbers.h - Native Line Number Enumerator ------------*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMLINENUMBERS_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMLINENUMBERS_H
+
+#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
+#include "llvm/DebugInfo/PDB/Native/NativeLineNumber.h"
+
+namespace llvm {
+namespace pdb {
+class IPDBLineNumber;
+
+class NativeEnumLineNumbers : public IPDBEnumChildren<IPDBLineNumber> {
+public:
+ explicit NativeEnumLineNumbers(std::vector<NativeLineNumber> LineNums);
+
+ uint32_t getChildCount() const override;
+ ChildTypePtr getChildAtIndex(uint32_t Index) const override;
+ ChildTypePtr getNext() override;
+ void reset() override;
+
+private:
+ std::vector<NativeLineNumber> Lines;
+ uint32_t Index;
+};
+} // namespace pdb
+} // namespace llvm
+
+#endif
--- /dev/null
+//===- NativeLineNumber.h - Native line number implementation ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVELINENUMBER_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVELINENUMBER_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+
+namespace llvm {
+namespace pdb {
+class NativeLineNumber : public IPDBLineNumber {
+public:
+ explicit NativeLineNumber(const NativeSession &Session,
+ const codeview::LineInfo Line, uint32_t Length,
+ uint32_t Section, uint32_t Offset,
+ uint32_t SrcFileId);
+
+ uint32_t getLineNumber() const override;
+ uint32_t getLineNumberEnd() const override;
+ uint32_t getColumnNumber() const override;
+ uint32_t getColumnNumberEnd() const override;
+ uint32_t getAddressSection() const override;
+ uint32_t getAddressOffset() const override;
+ uint32_t getRelativeVirtualAddress() const override;
+ uint64_t getVirtualAddress() const override;
+ uint32_t getLength() const override;
+ uint32_t getSourceFileId() const override;
+ uint32_t getCompilandId() const override;
+ bool isStatement() const override;
+
+private:
+ const NativeSession &Session;
+ const codeview::LineInfo Line;
+ uint32_t Section;
+ uint32_t Offset;
+ uint32_t Length;
+ uint32_t SrcFileId;
+};
+} // namespace pdb
+} // namespace llvm
+#endif
--- /dev/null
+//===- NativeSourceFile.h - Native source file implementation ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVESOURCEFILE_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVESOURCEFILE_H
+
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
+
+namespace llvm {
+namespace pdb {
+class NativeSession;
+
+class NativeSourceFile : public IPDBSourceFile {
+public:
+ explicit NativeSourceFile(NativeSession &Session, uint32_t FileId,
+ const codeview::FileChecksumEntry &Checksum);
+
+ std::string getFileName() const override;
+ uint32_t getUniqueId() const override;
+ std::string getChecksum() const override;
+ PDB_Checksum getChecksumType() const override;
+ std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
+ getCompilands() const override;
+
+private:
+ NativeSession &Session;
+ uint32_t FileId;
+ const codeview::FileChecksumEntry Checksum;
+};
+} // namespace pdb
+} // namespace llvm
+#endif
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntervalMap.h"
+#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSourceFile.h"
#include <memory>
#include <vector>
/// appear in the PDB file.
std::vector<SymIndexId> Compilands;
+ /// List of source files, indexed by unique source file index.
+ mutable std::vector<std::unique_ptr<NativeSourceFile>> SourceFiles;
+ mutable DenseMap<uint32_t, SymIndexId> FileNameOffsetToId;
+
/// Map from global symbol offset to SymIndexId.
DenseMap<uint32_t, SymIndexId> GlobalOffsetToSymbolId;
IMap::Allocator IMapAllocator;
IMap AddrToModuleIndex;
+ Expected<ModuleDebugStreamRef> getModuleDebugStream(uint32_t Index) const;
+
+ struct LineTableEntry {
+ uint64_t Addr;
+ codeview::LineInfo Line;
+ uint32_t FileNameIndex;
+ bool IsTerminalEntry;
+ };
+
+ std::vector<LineTableEntry> findLineTable(uint16_t Modi) const;
+ mutable DenseMap<uint16_t, std::vector<LineTableEntry>> LineTable;
+
SymIndexId createSymbolPlaceholder() {
SymIndexId Id = Cache.size();
Cache.push_back(nullptr);
std::unique_ptr<PDBSymbol> findPublicSymbolBySectOffset(uint32_t Sect,
uint32_t Offset);
- void parseSectionContribs();
- Optional<uint16_t> getModuleIndexForAddr(uint32_t Sect,
- uint32_t Offset) const;
-
public:
SymbolCache(NativeSession &Session, DbiStream *Dbi);
std::unique_ptr<PDBSymbol>
findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, PDB_SymType Type);
+ std::unique_ptr<IPDBEnumLineNumbers>
+ findLineNumbersByVA(uint64_t VA, uint32_t Length) const;
+
std::unique_ptr<PDBSymbolCompiland> getOrCreateCompiland(uint32_t Index);
uint32_t getNumCompilands() const;
ConcreteT &getNativeSymbolById(SymIndexId SymbolId) const {
return static_cast<ConcreteT &>(getNativeSymbolById(SymbolId));
}
+
+ std::unique_ptr<IPDBSourceFile> getSourceFileById(SymIndexId FileId) const;
+ SymIndexId
+ getOrCreateSourceFile(const codeview::FileChecksumEntry &Checksum) const;
+
+ void parseSectionContribs();
+ Optional<uint16_t> getModuleIndexForAddr(uint64_t Addr) const;
};
} // namespace pdb
Native/NativeCompilandSymbol.cpp
Native/NativeEnumGlobals.cpp
Native/NativeEnumInjectedSources.cpp
+ Native/NativeEnumLineNumbers.cpp
Native/NativeEnumModules.cpp
Native/NativeEnumTypes.cpp
Native/NativeExeSymbol.cpp
Native/NativeFunctionSymbol.cpp
+ Native/NativeLineNumber.cpp
Native/NativePublicSymbol.cpp
Native/NativeRawSymbol.cpp
+ Native/NativeSourceFile.cpp
Native/NativeSymbolEnumerator.cpp
Native/NativeTypeArray.cpp
Native/NativeTypeBuiltin.cpp
--- /dev/null
+//==- NativeEnumLineNumbers.cpp - Native Type Enumerator impl ----*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/Native/NativeLineNumber.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSourceFile.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeEnumLineNumbers::NativeEnumLineNumbers(
+ std::vector<NativeLineNumber> LineNums)
+ : Lines(std::move(LineNums)), Index(0) {}
+
+uint32_t NativeEnumLineNumbers::getChildCount() const {
+ return static_cast<uint32_t>(Lines.size());
+}
+
+std::unique_ptr<IPDBLineNumber>
+NativeEnumLineNumbers::getChildAtIndex(uint32_t N) const {
+ if (N >= getChildCount())
+ return nullptr;
+ return std::make_unique<NativeLineNumber>(Lines[N]);
+}
+
+std::unique_ptr<IPDBLineNumber> NativeEnumLineNumbers::getNext() {
+ return getChildAtIndex(Index++);
+}
+
+void NativeEnumLineNumbers::reset() { Index = 0; }
--- /dev/null
+//===- NativeLineNumber.cpp - Native line number implementation -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeLineNumber.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+NativeLineNumber::NativeLineNumber(const NativeSession &Session,
+ const codeview::LineInfo Line,
+ uint32_t Section, uint32_t Offset,
+ uint32_t Length, uint32_t SrcFileId)
+ : Session(Session), Line(Line), Section(Section), Offset(Offset),
+ Length(Length), SrcFileId(SrcFileId) {}
+
+uint32_t NativeLineNumber::getLineNumber() const { return Line.getStartLine(); }
+
+uint32_t NativeLineNumber::getLineNumberEnd() const {
+ return Line.getEndLine();
+}
+
+uint32_t NativeLineNumber::getColumnNumber() const { return 0; }
+
+uint32_t NativeLineNumber::getColumnNumberEnd() const { return 0; }
+
+uint32_t NativeLineNumber::getAddressSection() const { return Section; }
+
+uint32_t NativeLineNumber::getAddressOffset() const { return Offset; }
+
+uint32_t NativeLineNumber::getRelativeVirtualAddress() const {
+ return Session.getRVAFromSectOffset(Section, Offset);
+}
+
+uint64_t NativeLineNumber::getVirtualAddress() const {
+ return Session.getVAFromSectOffset(Section, Offset);
+}
+
+uint32_t NativeLineNumber::getLength() const { return Length; }
+
+uint32_t NativeLineNumber::getSourceFileId() const { return SrcFileId; }
+
+uint32_t NativeLineNumber::getCompilandId() const { return 0; }
+
+bool NativeLineNumber::isStatement() const { return Line.isStatement(); }
using namespace llvm;
using namespace llvm::msf;
using namespace llvm::pdb;
-using namespace llvm::codeview;
static DbiStream *getDbiStreamPtr(PDBFile &File) {
Expected<DbiStream &> DbiS = File.getPDBDbiStream();
if (auto File = loadPdbFile(PdbPath, Allocator))
return std::string(PdbPath);
else
+ consumeError(File.takeError());
+
+ // Check path that was in the executable.
+ if (auto File = loadPdbFile(PathFromExe, Allocator))
+ return std::string(PathFromExe);
+ else
return File.takeError();
return make_error<RawError>("PDB not found");
std::unique_ptr<IPDBEnumLineNumbers>
NativeSession::findLineNumbersByAddress(uint64_t Address,
uint32_t Length) const {
- return nullptr;
+ return Cache.findLineNumbersByVA(Address, Length);
}
std::unique_ptr<IPDBEnumLineNumbers>
NativeSession::findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const {
- return nullptr;
+ return findLineNumbersByAddress(getLoadAddress() + RVA, Length);
}
std::unique_ptr<IPDBEnumLineNumbers>
NativeSession::findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset,
uint32_t Length) const {
- return nullptr;
+ uint64_t VA = getVAFromSectOffset(Section, Offset);
+ return findLineNumbersByAddress(VA, Length);
}
std::unique_ptr<IPDBEnumSourceFiles>
std::unique_ptr<IPDBSourceFile>
NativeSession::getSourceFileById(uint32_t FileId) const {
- return nullptr;
+ return Cache.getSourceFileById(FileId);
}
std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const {
--- /dev/null
+//===- NativeSourceFile.cpp - Native line number implementaiton -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeSourceFile.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+NativeSourceFile::NativeSourceFile(NativeSession &Session, uint32_t FileId,
+ const codeview::FileChecksumEntry &Checksum)
+ : Session(Session), FileId(FileId), Checksum(Checksum) {}
+
+std::string NativeSourceFile::getFileName() const {
+ auto ST = Session.getPDBFile().getStringTable();
+ if (!ST) {
+ consumeError(ST.takeError());
+ return "";
+ }
+ auto FileName = ST->getStringTable().getString(Checksum.FileNameOffset);
+ if (!FileName) {
+ consumeError(FileName.takeError());
+ return "";
+ }
+
+ return std::string(FileName.get());
+}
+
+uint32_t NativeSourceFile::getUniqueId() const { return FileId; }
+
+std::string NativeSourceFile::getChecksum() const {
+ return toStringRef(Checksum.Checksum).str();
+}
+
+PDB_Checksum NativeSourceFile::getChecksumType() const {
+ return static_cast<PDB_Checksum>(Checksum.Kind);
+}
+
+std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
+NativeSourceFile::getCompilands() const {
+ return nullptr;
+}
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
-#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
#include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativePublicSymbol.h"
: Session(Session), Dbi(Dbi), AddrToModuleIndex(IMapAllocator) {
// Id 0 is reserved for the invalid symbol.
Cache.push_back(nullptr);
+ SourceFiles.push_back(nullptr);
if (Dbi)
Compilands.resize(Dbi->modules().getModuleCount());
return Id;
}
+Expected<ModuleDebugStreamRef>
+SymbolCache::getModuleDebugStream(uint32_t Index) const {
+ assert(Dbi && "Dbi stream not present");
+
+ DbiModuleDescriptor Modi = Dbi->modules().getModuleDescriptor(Index);
+
+ uint16_t ModiStream = Modi.getModuleStreamIndex();
+ if (ModiStream == kInvalidStreamIndex)
+ return make_error<RawError>("Module stream not present");
+
+ std::unique_ptr<msf::MappedBlockStream> ModStreamData =
+ Session.getPDBFile().createIndexedStream(ModiStream);
+
+ ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
+ if (auto EC = ModS.reload())
+ return std::move(EC);
+
+ return std::move(ModS);
+}
+
std::unique_ptr<PDBSymbol>
SymbolCache::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
PDB_SymType Type) {
if (!Dbi)
return nullptr;
- auto Modi = getModuleIndexForAddr(Sect, Offset);
+ auto Modi = getModuleIndexForAddr(Session.getVAFromSectOffset(Sect, Offset));
if (!Modi)
return nullptr;
- DbiModuleDescriptor ModDesc = Dbi->modules().getModuleDescriptor(*Modi);
- uint16_t StreamIndex = ModDesc.getModuleStreamIndex();
- if (StreamIndex == kInvalidStreamIndex)
- return nullptr;
- auto ModStreamData = Session.getPDBFile().createIndexedStream(StreamIndex);
- ModuleDebugStreamRef ModS(ModDesc, std::move(ModStreamData));
- if (auto EC = ModS.reload()) {
- consumeError(std::move(EC));
+ auto ExpectedModS = getModuleDebugStream(*Modi);
+ if (!ExpectedModS) {
+ consumeError(ExpectedModS.takeError());
return nullptr;
}
+ CVSymbolArray Syms = ExpectedModS->getSymbolArray();
// Search for the symbol in this module.
- CVSymbolArray Syms = ModS.getSymbolArray();
for (auto I = Syms.begin(), E = Syms.end(); I != E; ++I) {
if (I->kind() != S_LPROC32 && I->kind() != S_GPROC32)
continue;
if (Sect == PS.Segment && Offset >= PS.CodeOffset &&
Offset < PS.CodeOffset + PS.CodeSize) {
SymIndexId Id = createSymbol<NativeFunctionSymbol>(PS);
+ AddressToFunctionSymId.insert({{Sect, Offset}, Id});
return getSymbolById(Id);
}
} else
Count = Half;
}
+ if (It == AddrMap.begin())
+ return nullptr;
--It;
Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It);
}
auto PS = cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get()));
SymIndexId Id = createSymbol<NativePublicSymbol>(PS);
+ AddressToPublicSymId.insert({{Sect, Offset}, Id});
return getSymbolById(Id);
}
+std::vector<SymbolCache::LineTableEntry>
+SymbolCache::findLineTable(uint16_t Modi) const {
+ // Check if this module has already been added.
+ auto LineTableIter = LineTable.find(Modi);
+ if (LineTableIter != LineTable.end())
+ return LineTableIter->second;
+
+ std::vector<LineTableEntry> &ModuleLineTable = LineTable[Modi];
+
+ // If there is an error or there are no lines, just return the
+ // empty vector.
+ Expected<ModuleDebugStreamRef> ExpectedModS = getModuleDebugStream(Modi);
+ if (!ExpectedModS) {
+ consumeError(ExpectedModS.takeError());
+ return ModuleLineTable;
+ }
+
+ std::vector<std::vector<LineTableEntry>> EntryList;
+ for (const auto &SS : ExpectedModS->getSubsectionsArray()) {
+ if (SS.kind() != DebugSubsectionKind::Lines)
+ continue;
+
+ DebugLinesSubsectionRef Lines;
+ BinaryStreamReader Reader(SS.getRecordData());
+ if (auto EC = Lines.initialize(Reader)) {
+ consumeError(std::move(EC));
+ continue;
+ }
+
+ uint32_t RelocSegment = Lines.header()->RelocSegment;
+ uint32_t RelocOffset = Lines.header()->RelocOffset;
+ for (const LineColumnEntry &Group : Lines) {
+ if (Group.LineNumbers.empty())
+ continue;
+
+ std::vector<LineTableEntry> Entries;
+ for (const LineNumberEntry &LN : Group.LineNumbers) {
+ LineInfo Line(LN.Flags);
+ uint64_t VA =
+ Session.getVAFromSectOffset(RelocSegment, RelocOffset + LN.Offset);
+ Entries.push_back({VA, Line, Group.NameIndex, false});
+ }
+
+ // Add a terminal entry line to mark the end of this subsection.
+ LineInfo LastLine(Group.LineNumbers.back().Flags);
+ uint64_t VA = Session.getVAFromSectOffset(
+ RelocSegment, RelocOffset + Lines.header()->CodeSize);
+ Entries.push_back({VA, LastLine, Group.NameIndex, true});
+ EntryList.push_back(Entries);
+ }
+ }
+
+ // Sort EntryList, and add flattened contents to the line table.
+ std::sort(EntryList.begin(), EntryList.end(),
+ [](const std::vector<LineTableEntry> &LHS,
+ const std::vector<LineTableEntry> &RHS) {
+ return LHS[0].Addr < RHS[0].Addr;
+ });
+ for (size_t I = 0; I < EntryList.size(); ++I)
+ ModuleLineTable.insert(ModuleLineTable.end(), EntryList[I].begin(),
+ EntryList[I].end());
+
+ return ModuleLineTable;
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const {
+ Optional<uint16_t> MaybeModi = getModuleIndexForAddr(VA);
+ if (!MaybeModi)
+ return nullptr;
+ uint16_t Modi = *MaybeModi;
+
+ std::vector<LineTableEntry> Lines = findLineTable(Modi);
+ if (Lines.empty())
+ return nullptr;
+
+ // Find the first line in the line table whose address is not greater than
+ // the one we are searching for.
+ auto LineIter = llvm::partition_point(Lines, [&](const LineTableEntry &E) {
+ return (E.Addr < VA || (E.Addr == VA && E.IsTerminalEntry));
+ });
+
+ // Try to back up if we've gone too far.
+ if (LineIter == Lines.end() || LineIter->Addr > VA) {
+ if (LineIter == Lines.begin() || std::prev(LineIter)->IsTerminalEntry)
+ return nullptr;
+ --LineIter;
+ }
+
+ Expected<ModuleDebugStreamRef> ExpectedModS = getModuleDebugStream(Modi);
+ if (!ExpectedModS) {
+ consumeError(ExpectedModS.takeError());
+ return nullptr;
+ }
+ Expected<DebugChecksumsSubsectionRef> ExpectedChecksums =
+ ExpectedModS->findChecksumsSubsection();
+ if (!ExpectedChecksums) {
+ consumeError(ExpectedChecksums.takeError());
+ return nullptr;
+ }
+
+ // Populate a vector of NativeLineNumbers that have addresses in the given
+ // address range.
+ Optional<uint16_t> EndModi = getModuleIndexForAddr(VA + Length);
+ if (!EndModi)
+ return nullptr;
+ std::vector<NativeLineNumber> LineNumbers;
+ while (Modi <= *EndModi) {
+ // If we reached the end of the current module, increment Modi and get the
+ // new line table and checksums array.
+ if (LineIter == Lines.end()) {
+ ++Modi;
+
+ ExpectedModS = getModuleDebugStream(Modi);
+ if (!ExpectedModS) {
+ consumeError(ExpectedModS.takeError());
+ break;
+ }
+ ExpectedChecksums = ExpectedModS->findChecksumsSubsection();
+ if (!ExpectedChecksums) {
+ consumeError(ExpectedChecksums.takeError());
+ break;
+ }
+
+ Lines = findLineTable(Modi);
+ LineIter = Lines.begin();
+
+ if (Lines.empty())
+ continue;
+ }
+
+ if (LineIter->IsTerminalEntry) {
+ ++LineIter;
+ continue;
+ }
+
+ // If the line is still within the address range, create a NativeLineNumber
+ // and add to the list.
+ if (LineIter->Addr > VA + Length)
+ break;
+
+ uint32_t LineSect, LineOff;
+ Session.addressForVA(LineIter->Addr, LineSect, LineOff);
+ uint32_t LineLength = std::next(LineIter)->Addr - LineIter->Addr;
+ auto ChecksumIter =
+ ExpectedChecksums->getArray().at(LineIter->FileNameIndex);
+ uint32_t SrcFileId = getOrCreateSourceFile(*ChecksumIter);
+ NativeLineNumber LineNum(Session, LineIter->Line, LineSect, LineOff,
+ LineLength, SrcFileId);
+ LineNumbers.push_back(LineNum);
+ ++LineIter;
+ }
+ return std::make_unique<NativeEnumLineNumbers>(std::move(LineNumbers));
+}
+
std::unique_ptr<PDBSymbolCompiland>
SymbolCache::getOrCreateCompiland(uint32_t Index) {
if (!Dbi)
return Session.getConcreteSymbolById<PDBSymbolCompiland>(Compilands[Index]);
}
+std::unique_ptr<IPDBSourceFile>
+SymbolCache::getSourceFileById(SymIndexId FileId) const {
+ assert(FileId < SourceFiles.size());
+
+ // Id 0 is reserved.
+ if (FileId == 0)
+ return nullptr;
+
+ return std::unique_ptr<NativeSourceFile>(
+ new NativeSourceFile(*SourceFiles[FileId].get()));
+}
+
+SymIndexId
+SymbolCache::getOrCreateSourceFile(const FileChecksumEntry &Checksums) const {
+ auto Iter = FileNameOffsetToId.find(Checksums.FileNameOffset);
+ if (Iter != FileNameOffsetToId.end())
+ return Iter->second;
+
+ SymIndexId Id = SourceFiles.size();
+ auto SrcFile = std::make_unique<NativeSourceFile>(Session, Id, Checksums);
+ SourceFiles.push_back(std::move(SrcFile));
+ FileNameOffsetToId[Checksums.FileNameOffset] = Id;
+ return Id;
+}
+
void SymbolCache::parseSectionContribs() {
if (!Dbi)
return;
Dbi->visitSectionContributions(V);
}
-Optional<uint16_t> SymbolCache::getModuleIndexForAddr(uint32_t Sect,
- uint32_t Offset) const {
- auto Iter = AddrToModuleIndex.find(Session.getVAFromSectOffset(Sect, Offset));
+Optional<uint16_t> SymbolCache::getModuleIndexForAddr(uint64_t Addr) const {
+ auto Iter = AddrToModuleIndex.find(Addr);
if (Iter == AddrToModuleIndex.end())
return None;
return Iter.value();
std::unique_ptr<IPDBSession> &Session) {
// Create the correct concrete instance type based on the value of Type.
if (Type == PDB_ReaderType::Native) {
- if (auto Err = NativeSession::createFromExe(Path, Session)) {
- consumeError(std::move(Err));
-
- Expected<std::string> PdbPath = NativeSession::searchForPdb({Path});
- if (!PdbPath)
- return PdbPath.takeError();
- return NativeSession::createFromPdbPath(PdbPath.get(), Session);
- }
- return Error::success();
+ Expected<std::string> PdbPath = NativeSession::searchForPdb({Path});
+ if (!PdbPath)
+ return PdbPath.takeError();
+ return NativeSession::createFromPdbPath(PdbPath.get(), Session);
}
#if LLVM_ENABLE_DIA_SDK
Currently only finding function/public symbol names is implemented.
CHECK: foo(void)
+CHECK-NEXT: test.cpp:10
CHECK: {{^private_symbol$}}
+CHECK-NEXT: test.cpp:13:0
CHECK: {{^main}}
+CHECK-NEXT: test.cpp:16:0
CHECK: {{^foo_cdecl$}}
CHECK: {{^foo_stdcall$}}
CHECK: {{^foo_fastcall$}}
CHECK: {{^foo_vectorcall$}}
CHECK: NS::Foo::bar(void)
+CHECK-NEXT: test.cpp:6:0
CHECK-NO-DEMANGLE: ?foo@@YAXXZ
+CHECK-NO-DEMANGLE-NEXT: test.cpp:10
CHECK-NO-DEMANGLE: private_symbol
+CHECK-NO-DEMANGLE-NEXT: test.cpp:13
CHECK-NO-DEMANGLE: _main
+CHECK-NO-DEMANGLE-NEXT: test.cpp:16
CHECK-NO-DEMANGLE: _foo_cdecl
CHECK-NO-DEMANGLE: _foo_stdcall@0
CHECK-NO-DEMANGLE: @foo_fastcall@0
CHECK-NO-DEMANGLE: foo_vectorcall@@0
CHECK-NO-DEMANGLE: ?bar@Foo@NS@@QAEXXZ
+CHECK-NO-DEMANGLE-NEXT: test.cpp:6
"Native/NativeCompilandSymbol.cpp",
"Native/NativeEnumGlobals.cpp",
"Native/NativeEnumInjectedSources.cpp",
+ "Native/NativeEnumLineNumbers.cpp",
"Native/NativeEnumModules.cpp",
"Native/NativeEnumTypes.cpp",
"Native/NativeExeSymbol.cpp",
"Native/NativeFunctionSymbol.cpp",
+ "Native/NativeLineNumber.cpp",
"Native/NativePublicSymbol.cpp",
"Native/NativeRawSymbol.cpp",
"Native/NativeSession.cpp",
+ "Native/NativeSourceFile.cpp",
"Native/NativeSymbolEnumerator.cpp",
"Native/NativeTypeArray.cpp",
"Native/NativeTypeBuiltin.cpp",