[llvm] f8170d8 - [NativeSession] Implement findLineNumbersByAddress in NativeSession,
Amy Huang via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 15 17:06:29 PDT 2020
Author: Amy Huang
Date: 2020-06-15T17:05:39-07:00
New Revision: f8170d87159bdd71835c5e21346f699c1c327ce8
URL: https://github.com/llvm/llvm-project/commit/f8170d87159bdd71835c5e21346f699c1c327ce8
DIFF: https://github.com/llvm/llvm-project/commit/f8170d87159bdd71835c5e21346f699c1c327ce8.diff
LOG: [NativeSession] Implement findLineNumbersByAddress in NativeSession,
which takes an address and a length and returns all lines within that
address range.
Added:
llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h
llvm/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h
llvm/include/llvm/DebugInfo/PDB/Native/NativeSourceFile.h
llvm/lib/DebugInfo/PDB/Native/NativeEnumLineNumbers.cpp
llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
llvm/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
Modified:
llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
llvm/lib/DebugInfo/PDB/CMakeLists.txt
llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp
llvm/lib/DebugInfo/PDB/PDB.cpp
llvm/test/tools/llvm-symbolizer/pdb/pdb-native.test
llvm/utils/gn/secondary/llvm/lib/DebugInfo/PDB/BUILD.gn
Removed:
################################################################################
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h
new file mode 100644
index 000000000000..32a4515d557e
--- /dev/null
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h
@@ -0,0 +1,39 @@
+//==- 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
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h
new file mode 100644
index 000000000000..f105526adf56
--- /dev/null
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h
@@ -0,0 +1,49 @@
+//===- 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
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeSourceFile.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeSourceFile.h
new file mode 100644
index 000000000000..eb6336f268e8
--- /dev/null
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/NativeSourceFile.h
@@ -0,0 +1,40 @@
+//===- 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
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h b/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
index 33428bfbf427..e14ef3209916 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
@@ -11,11 +11,14 @@
#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>
@@ -50,6 +53,10 @@ class SymbolCache {
/// 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;
@@ -63,6 +70,18 @@ class SymbolCache {
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);
@@ -94,10 +113,6 @@ class SymbolCache {
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);
@@ -151,6 +166,9 @@ class SymbolCache {
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;
@@ -162,6 +180,13 @@ class SymbolCache {
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
diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
index 1eda97a06a53..9088bc86f668 100644
--- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
@@ -52,12 +52,15 @@ add_pdb_impl_folder(Native
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
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeEnumLineNumbers.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeEnumLineNumbers.cpp
new file mode 100644
index 000000000000..1e4b07646335
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeEnumLineNumbers.cpp
@@ -0,0 +1,42 @@
+//==- 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; }
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
new file mode 100644
index 000000000000..f493c1807942
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
@@ -0,0 +1,49 @@
+//===- 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(); }
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
index dcae2e99d936..ac8449df44ff 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
@@ -43,7 +43,6 @@
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();
@@ -181,6 +180,12 @@ NativeSession::searchForPdb(const PdbSearchOptions &Opts) {
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();
@@ -262,18 +267,19 @@ NativeSession::findLineNumbers(const PDBSymbolCompiland &Compiland,
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>
@@ -313,7 +319,7 @@ std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getSourceFilesForCompiland(
std::unique_ptr<IPDBSourceFile>
NativeSession::getSourceFileById(uint32_t FileId) const {
- return nullptr;
+ return Cache.getSourceFileById(FileId);
}
std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const {
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
new file mode 100644
index 000000000000..6473207e058a
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
@@ -0,0 +1,47 @@
+//===- 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;
+}
diff --git a/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp b/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp
index 554eea06dc68..83cf77aae862 100644
--- a/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/SymbolCache.cpp
@@ -7,9 +7,9 @@
#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"
@@ -71,6 +71,7 @@ SymbolCache::SymbolCache(NativeSession &Session, DbiStream *Dbi)
: 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());
@@ -287,6 +288,26 @@ SymIndexId SymbolCache::getOrCreateGlobalSymbolByOffset(uint32_t Offset) {
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) {
@@ -318,23 +339,18 @@ SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
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;
@@ -342,6 +358,7 @@ SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
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);
}
@@ -392,6 +409,8 @@ SymbolCache::findPublicSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
} else
Count = Half;
}
+ if (It == AddrMap.begin())
+ return nullptr;
--It;
Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It);
@@ -401,9 +420,165 @@ SymbolCache::findPublicSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
}
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)
@@ -421,6 +596,31 @@ SymbolCache::getOrCreateCompiland(uint32_t Index) {
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;
@@ -451,9 +651,8 @@ void SymbolCache::parseSectionContribs() {
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();
diff --git a/llvm/lib/DebugInfo/PDB/PDB.cpp b/llvm/lib/DebugInfo/PDB/PDB.cpp
index a0d015c7839e..e5b7731f6f4a 100644
--- a/llvm/lib/DebugInfo/PDB/PDB.cpp
+++ b/llvm/lib/DebugInfo/PDB/PDB.cpp
@@ -37,15 +37,10 @@ Error llvm::pdb::loadDataForEXE(PDB_ReaderType Type, StringRef Path,
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
diff --git a/llvm/test/tools/llvm-symbolizer/pdb/pdb-native.test b/llvm/test/tools/llvm-symbolizer/pdb/pdb-native.test
index 29a770e402ee..d132dbfc0460 100644
--- a/llvm/test/tools/llvm-symbolizer/pdb/pdb-native.test
+++ b/llvm/test/tools/llvm-symbolizer/pdb/pdb-native.test
@@ -21,19 +21,27 @@ RUN: | FileCheck %s --check-prefix=CHECK-NO-DEMANGLE
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 at 0
CHECK-NO-DEMANGLE: @foo_fastcall at 0
CHECK-NO-DEMANGLE: foo_vectorcall@@0
CHECK-NO-DEMANGLE: ?bar at Foo@NS@@QAEXXZ
+CHECK-NO-DEMANGLE-NEXT: test.cpp:6
diff --git a/llvm/utils/gn/secondary/llvm/lib/DebugInfo/PDB/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/DebugInfo/PDB/BUILD.gn
index a11ace501518..8d8990bd0bea 100644
--- a/llvm/utils/gn/secondary/llvm/lib/DebugInfo/PDB/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/DebugInfo/PDB/BUILD.gn
@@ -30,13 +30,16 @@ static_library("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/NativeSession.cpp",
+ "Native/NativeSourceFile.cpp",
"Native/NativeSymbolEnumerator.cpp",
"Native/NativeTypeArray.cpp",
"Native/NativeTypeBuiltin.cpp",
More information about the llvm-commits
mailing list