mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-03 17:02:03 +00:00
[NativeSession] Implement findLineNumbersByAddress in NativeSession,
which takes an address and a length and returns all lines within that address range.
This commit is contained in:
parent
c56408467a
commit
bced012cc6
39
include/llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h
Normal file
39
include/llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h
Normal file
@ -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
|
49
include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h
Normal file
49
include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h
Normal file
@ -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
|
40
include/llvm/DebugInfo/PDB/Native/NativeSourceFile.h
Normal file
40
include/llvm/DebugInfo/PDB/Native/NativeSourceFile.h
Normal file
@ -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
|
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
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
|
||||
|
@ -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
|
||||
|
42
lib/DebugInfo/PDB/Native/NativeEnumLineNumbers.cpp
Normal file
42
lib/DebugInfo/PDB/Native/NativeEnumLineNumbers.cpp
Normal file
@ -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; }
|
49
lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
Normal file
49
lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
Normal file
@ -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(); }
|
@ -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 {
|
||||
|
47
lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
Normal file
47
lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
Normal file
@ -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;
|
||||
}
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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@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
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user