mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[pdb] Use MappedBlockStream to parse the PDB directory.
In order to efficiently write PDBs, we need to be able to make a StreamWriter class similar to a StreamReader, which can transparently deal with writing to discontiguous streams, and we need to use this for all writing, similar to how we use StreamReader for all reading. Most discontiguous streams are the typical numbered streams that appear in a PDB file and are described by the directory, but the exception to this, that until now has been parsed by hand, is the directory itself. MappedBlockStream works by querying the directory to find out which blocks a stream occupies and various other things, so naturally the same logic could not possibly work to describe the blocks that the directory itself resided on. To solve this, I've introduced an abstraction IPDBStreamData, which allows the client to query for the list of blocks occupied by the stream, as well as the stream length. I provide two implementations of this: one which queries the directory (for indexed streams), and one which queries the super block (for the directory stream). This has the side benefit of vastly simplifying the code to parse the directory. Whereas before a mini state machine was rolled by hand, now we simply use FixedStreamArray to read out the stream sizes, then build a vector of FixedStreamArrays for the stream map, all in just a few lines of code. Reviewed By: ruiu Differential Revision: http://reviews.llvm.org/D21046 llvm-svn: 271982
This commit is contained in:
parent
7c363e3401
commit
df1bab5ad7
@ -224,6 +224,8 @@ public:
|
|||||||
return FixedStreamArrayIterator<T>(*this, size());
|
return FixedStreamArrayIterator<T>(*this, size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StreamRef getUnderlyingStream() const { return Stream; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StreamRef Stream;
|
StreamRef Stream;
|
||||||
};
|
};
|
||||||
|
@ -52,6 +52,20 @@ public:
|
|||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Error readArray(ArrayRef<T> &Array, uint32_t NumElements) {
|
||||||
|
ArrayRef<uint8_t> Bytes;
|
||||||
|
if (NumElements == 0) {
|
||||||
|
Array = ArrayRef<T>();
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto EC = readBytes(Bytes, NumElements * sizeof(T)))
|
||||||
|
return EC;
|
||||||
|
Array = ArrayRef<T>(reinterpret_cast<const T *>(Bytes.data()), NumElements);
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) {
|
Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) {
|
||||||
StreamRef S;
|
StreamRef S;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/DebugInfo/CodeView/StreamArray.h"
|
||||||
#include "llvm/Support/Endian.h"
|
#include "llvm/Support/Endian.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -28,7 +29,8 @@ public:
|
|||||||
|
|
||||||
virtual uint32_t getNumStreams() const = 0;
|
virtual uint32_t getNumStreams() const = 0;
|
||||||
virtual uint32_t getStreamByteSize(uint32_t StreamIndex) const = 0;
|
virtual uint32_t getStreamByteSize(uint32_t StreamIndex) const = 0;
|
||||||
virtual ArrayRef<uint32_t> getStreamBlockList(uint32_t StreamIndex) const = 0;
|
virtual ArrayRef<support::ulittle32_t>
|
||||||
|
getStreamBlockList(uint32_t StreamIndex) const = 0;
|
||||||
|
|
||||||
virtual StringRef getBlockData(uint32_t BlockIndex,
|
virtual StringRef getBlockData(uint32_t BlockIndex,
|
||||||
uint32_t NumBytes) const = 0;
|
uint32_t NumBytes) const = 0;
|
||||||
|
38
include/llvm/DebugInfo/PDB/Raw/IPDBStreamData.h
Normal file
38
include/llvm/DebugInfo/PDB/Raw/IPDBStreamData.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//===- IPDBStreamData.h - Base interface for PDB Stream Data ----*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_DEBUGINFO_PDB_RAW_IPDBSTREAMDATA_H
|
||||||
|
#define LLVM_DEBUGINFO_PDB_RAW_IPDBSTREAMDATA_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
|
#include "llvm/Support/Endian.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
namespace pdb {
|
||||||
|
/// IPDBStream abstracts the notion of PDB stream data. Although we already
|
||||||
|
/// have another stream abstraction (namely in the form of StreamInterface
|
||||||
|
/// and MappedBlockStream), they assume that the stream data is referenced
|
||||||
|
/// the same way. Namely, by looking in the directory to get the list of
|
||||||
|
/// stream blocks, and by looking in the array of stream lengths to get the
|
||||||
|
/// length. This breaks down for the directory itself, however, since its
|
||||||
|
/// length and list of blocks are stored elsewhere. By abstracting the
|
||||||
|
/// notion of stream data further, we can use a MappedBlockStream to read
|
||||||
|
/// from the directory itself, or from an indexed stream which references
|
||||||
|
/// the directory.
|
||||||
|
class IPDBStreamData {
|
||||||
|
public:
|
||||||
|
virtual ~IPDBStreamData() {}
|
||||||
|
|
||||||
|
virtual uint32_t getLength() = 0;
|
||||||
|
virtual ArrayRef<support::ulittle32_t> getStreamBlocks() = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
34
include/llvm/DebugInfo/PDB/Raw/IndexedStreamData.h
Normal file
34
include/llvm/DebugInfo/PDB/Raw/IndexedStreamData.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
//===- IndexedStreamData.h - Standard PDB Stream Data -----------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_DEBUGINFO_PDB_RAW_INDEXEDSTREAMDATA_H
|
||||||
|
#define LLVM_DEBUGINFO_PDB_RAW_INDEXEDSTREAMDATA_H
|
||||||
|
|
||||||
|
#include "llvm/DebugInfo/PDB/Raw/IPDBStreamData.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
namespace pdb {
|
||||||
|
class IPDBFile;
|
||||||
|
|
||||||
|
class IndexedStreamData : public IPDBStreamData {
|
||||||
|
public:
|
||||||
|
IndexedStreamData(uint32_t StreamIdx, const IPDBFile &File);
|
||||||
|
virtual ~IndexedStreamData() {}
|
||||||
|
|
||||||
|
uint32_t getLength() override;
|
||||||
|
ArrayRef<support::ulittle32_t> getStreamBlocks() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t StreamIdx;
|
||||||
|
const IPDBFile &File;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -24,7 +24,7 @@ namespace pdb {
|
|||||||
class PDBFile;
|
class PDBFile;
|
||||||
class InfoStream {
|
class InfoStream {
|
||||||
public:
|
public:
|
||||||
InfoStream(PDBFile &File);
|
InfoStream(const PDBFile &File);
|
||||||
|
|
||||||
Error reload();
|
Error reload();
|
||||||
|
|
||||||
@ -36,10 +36,7 @@ public:
|
|||||||
uint32_t getNamedStreamIndex(llvm::StringRef Name) const;
|
uint32_t getNamedStreamIndex(llvm::StringRef Name) const;
|
||||||
iterator_range<StringMapConstIterator<uint32_t>> named_streams() const;
|
iterator_range<StringMapConstIterator<uint32_t>> named_streams() const;
|
||||||
|
|
||||||
PDBFile &getFile() { return Pdb; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PDBFile &Pdb;
|
|
||||||
MappedBlockStream Stream;
|
MappedBlockStream Stream;
|
||||||
|
|
||||||
// PDB file format version. We only support VC70. See the enumeration
|
// PDB file format version. We only support VC70. See the enumeration
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/DebugInfo/CodeView/StreamInterface.h"
|
#include "llvm/DebugInfo/CodeView/StreamInterface.h"
|
||||||
#include "llvm/Support/Allocator.h"
|
#include "llvm/Support/Allocator.h"
|
||||||
|
#include "llvm/Support/Endian.h"
|
||||||
#include "llvm/Support/Error.h"
|
#include "llvm/Support/Error.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -22,15 +23,16 @@ namespace llvm {
|
|||||||
namespace pdb {
|
namespace pdb {
|
||||||
|
|
||||||
class IPDBFile;
|
class IPDBFile;
|
||||||
|
class IPDBStreamData;
|
||||||
|
|
||||||
class MappedBlockStream : public codeview::StreamInterface {
|
class MappedBlockStream : public codeview::StreamInterface {
|
||||||
public:
|
public:
|
||||||
MappedBlockStream(uint32_t StreamIdx, const IPDBFile &File);
|
MappedBlockStream(std::unique_ptr<IPDBStreamData> Data, const IPDBFile &File);
|
||||||
|
|
||||||
Error readBytes(uint32_t Offset, uint32_t Size,
|
Error readBytes(uint32_t Offset, uint32_t Size,
|
||||||
ArrayRef<uint8_t> &Buffer) const override;
|
ArrayRef<uint8_t> &Buffer) const override;
|
||||||
|
|
||||||
uint32_t getLength() const override { return StreamLength; }
|
uint32_t getLength() const override;
|
||||||
|
|
||||||
uint32_t getNumBytesCopied() const;
|
uint32_t getNumBytesCopied() const;
|
||||||
|
|
||||||
@ -39,11 +41,11 @@ private:
|
|||||||
bool tryReadContiguously(uint32_t Offset, uint32_t Size,
|
bool tryReadContiguously(uint32_t Offset, uint32_t Size,
|
||||||
ArrayRef<uint8_t> &Buffer) const;
|
ArrayRef<uint8_t> &Buffer) const;
|
||||||
|
|
||||||
uint32_t StreamLength;
|
const IPDBFile &Pdb;
|
||||||
std::vector<uint32_t> BlockList;
|
std::unique_ptr<IPDBStreamData> Data;
|
||||||
|
|
||||||
mutable llvm::BumpPtrAllocator Pool;
|
mutable llvm::BumpPtrAllocator Pool;
|
||||||
mutable DenseMap<uint32_t, uint8_t *> CacheMap;
|
mutable DenseMap<uint32_t, uint8_t *> CacheMap;
|
||||||
const IPDBFile &Pdb;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace pdb
|
} // end namespace pdb
|
||||||
|
@ -26,7 +26,7 @@ class ModInfo;
|
|||||||
|
|
||||||
class ModStream {
|
class ModStream {
|
||||||
public:
|
public:
|
||||||
ModStream(PDBFile &File, const ModInfo &Module);
|
ModStream(const PDBFile &File, const ModInfo &Module);
|
||||||
~ModStream();
|
~ModStream();
|
||||||
|
|
||||||
Error reload();
|
Error reload();
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#define LLVM_DEBUGINFO_PDB_RAW_PDBFILE_H
|
#define LLVM_DEBUGINFO_PDB_RAW_PDBFILE_H
|
||||||
|
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
#include "llvm/DebugInfo/CodeView/StreamArray.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/IPDBFile.h"
|
#include "llvm/DebugInfo/PDB/Raw/IPDBFile.h"
|
||||||
#include "llvm/Support/Endian.h"
|
#include "llvm/Support/Endian.h"
|
||||||
#include "llvm/Support/Error.h"
|
#include "llvm/Support/Error.h"
|
||||||
@ -48,11 +49,12 @@ public:
|
|||||||
|
|
||||||
uint32_t getNumStreams() const override;
|
uint32_t getNumStreams() const override;
|
||||||
uint32_t getStreamByteSize(uint32_t StreamIndex) const override;
|
uint32_t getStreamByteSize(uint32_t StreamIndex) const override;
|
||||||
ArrayRef<uint32_t> getStreamBlockList(uint32_t StreamIndex) const override;
|
ArrayRef<support::ulittle32_t>
|
||||||
|
getStreamBlockList(uint32_t StreamIndex) const override;
|
||||||
|
|
||||||
StringRef getBlockData(uint32_t BlockIndex, uint32_t NumBytes) const override;
|
StringRef getBlockData(uint32_t BlockIndex, uint32_t NumBytes) const override;
|
||||||
|
|
||||||
ArrayRef<support::ulittle32_t> getDirectoryBlockArray();
|
ArrayRef<support::ulittle32_t> getDirectoryBlockArray() const;
|
||||||
|
|
||||||
Error parseFileHeaders();
|
Error parseFileHeaders();
|
||||||
Error parseStreamData();
|
Error parseStreamData();
|
||||||
@ -81,6 +83,7 @@ private:
|
|||||||
std::unique_ptr<TpiStream> Ipi;
|
std::unique_ptr<TpiStream> Ipi;
|
||||||
std::unique_ptr<PublicsStream> Publics;
|
std::unique_ptr<PublicsStream> Publics;
|
||||||
std::unique_ptr<SymbolStream> Symbols;
|
std::unique_ptr<SymbolStream> Symbols;
|
||||||
|
std::unique_ptr<MappedBlockStream> DirectoryStream;
|
||||||
std::unique_ptr<MappedBlockStream> StringTableStream;
|
std::unique_ptr<MappedBlockStream> StringTableStream;
|
||||||
std::unique_ptr<NameHashTable> StringTable;
|
std::unique_ptr<NameHashTable> StringTable;
|
||||||
};
|
};
|
||||||
|
@ -22,7 +22,7 @@ class PDBFile;
|
|||||||
|
|
||||||
class SymbolStream {
|
class SymbolStream {
|
||||||
public:
|
public:
|
||||||
SymbolStream(PDBFile &File, uint32_t StreamNum);
|
SymbolStream(const PDBFile &File, uint32_t StreamNum);
|
||||||
~SymbolStream();
|
~SymbolStream();
|
||||||
Error reload();
|
Error reload();
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class TpiStream {
|
|||||||
struct HeaderInfo;
|
struct HeaderInfo;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TpiStream(PDBFile &File, uint32_t StreamIdx);
|
TpiStream(const PDBFile &File, uint32_t StreamIdx);
|
||||||
~TpiStream();
|
~TpiStream();
|
||||||
Error reload();
|
Error reload();
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ public:
|
|||||||
iterator_range<codeview::CVTypeArray::Iterator> types(bool *HadError) const;
|
iterator_range<codeview::CVTypeArray::Iterator> types(bool *HadError) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PDBFile &Pdb;
|
const PDBFile &Pdb;
|
||||||
MappedBlockStream Stream;
|
MappedBlockStream Stream;
|
||||||
HashFunctionType HashFunction;
|
HashFunctionType HashFunction;
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ endif()
|
|||||||
add_pdb_impl_folder(Raw
|
add_pdb_impl_folder(Raw
|
||||||
Raw/DbiStream.cpp
|
Raw/DbiStream.cpp
|
||||||
Raw/EnumTables.cpp
|
Raw/EnumTables.cpp
|
||||||
|
Raw/IndexedStreamData.cpp
|
||||||
Raw/InfoStream.cpp
|
Raw/InfoStream.cpp
|
||||||
Raw/MappedBlockStream.cpp
|
Raw/MappedBlockStream.cpp
|
||||||
Raw/ModInfo.cpp
|
Raw/ModInfo.cpp
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "llvm/DebugInfo/CodeView/StreamArray.h"
|
#include "llvm/DebugInfo/CodeView/StreamArray.h"
|
||||||
#include "llvm/DebugInfo/CodeView/StreamReader.h"
|
#include "llvm/DebugInfo/CodeView/StreamReader.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h"
|
#include "llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h"
|
||||||
|
#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
|
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
|
#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
|
#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
|
||||||
@ -93,7 +94,9 @@ Error loadSectionContribs(FixedStreamArray<ContribType> &Output,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DbiStream::DbiStream(PDBFile &File)
|
DbiStream::DbiStream(PDBFile &File)
|
||||||
: Pdb(File), Stream(StreamDBI, File), Header(nullptr) {
|
: Pdb(File),
|
||||||
|
Stream(llvm::make_unique<IndexedStreamData>(StreamDBI, File), File),
|
||||||
|
Header(nullptr) {
|
||||||
static_assert(sizeof(HeaderInfo) == 64, "Invalid HeaderInfo size!");
|
static_assert(sizeof(HeaderInfo) == 64, "Invalid HeaderInfo size!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,7 +293,8 @@ Error DbiStream::initializeSectionContributionData() {
|
|||||||
// Initializes this->SectionHeaders.
|
// Initializes this->SectionHeaders.
|
||||||
Error DbiStream::initializeSectionHeadersData() {
|
Error DbiStream::initializeSectionHeadersData() {
|
||||||
uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::SectionHdr);
|
uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::SectionHdr);
|
||||||
SectionHeaderStream.reset(new MappedBlockStream(StreamNum, Pdb));
|
SectionHeaderStream.reset(new MappedBlockStream(
|
||||||
|
llvm::make_unique<IndexedStreamData>(StreamNum, Pdb), Pdb));
|
||||||
|
|
||||||
size_t StreamLen = SectionHeaderStream->getLength();
|
size_t StreamLen = SectionHeaderStream->getLength();
|
||||||
if (StreamLen % sizeof(object::coff_section))
|
if (StreamLen % sizeof(object::coff_section))
|
||||||
@ -308,7 +312,8 @@ Error DbiStream::initializeSectionHeadersData() {
|
|||||||
// Initializes this->Fpos.
|
// Initializes this->Fpos.
|
||||||
Error DbiStream::initializeFpoRecords() {
|
Error DbiStream::initializeFpoRecords() {
|
||||||
uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::NewFPO);
|
uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::NewFPO);
|
||||||
FpoStream.reset(new MappedBlockStream(StreamNum, Pdb));
|
FpoStream.reset(new MappedBlockStream(
|
||||||
|
llvm::make_unique<IndexedStreamData>(StreamNum, Pdb), Pdb));
|
||||||
|
|
||||||
size_t StreamLen = FpoStream->getLength();
|
size_t StreamLen = FpoStream->getLength();
|
||||||
if (StreamLen % sizeof(object::FpoData))
|
if (StreamLen % sizeof(object::FpoData))
|
||||||
|
25
lib/DebugInfo/PDB/Raw/IndexedStreamData.cpp
Normal file
25
lib/DebugInfo/PDB/Raw/IndexedStreamData.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//===- IndexedStreamData.cpp - Standard PDB Stream Data ---------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
|
||||||
|
#include "llvm/DebugInfo/PDB/Raw/IPDBFile.h"
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
using namespace llvm::pdb;
|
||||||
|
|
||||||
|
IndexedStreamData::IndexedStreamData(uint32_t StreamIdx, const IPDBFile &File)
|
||||||
|
: StreamIdx(StreamIdx), File(File) {}
|
||||||
|
|
||||||
|
uint32_t IndexedStreamData::getLength() {
|
||||||
|
return File.getStreamByteSize(StreamIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayRef<support::ulittle32_t> IndexedStreamData::getStreamBlocks() {
|
||||||
|
return File.getStreamBlockList(StreamIdx);
|
||||||
|
}
|
@ -11,6 +11,7 @@
|
|||||||
#include "llvm/ADT/BitVector.h"
|
#include "llvm/ADT/BitVector.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/DebugInfo/CodeView/StreamReader.h"
|
#include "llvm/DebugInfo/CodeView/StreamReader.h"
|
||||||
|
#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
|
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
|
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
|
||||||
@ -18,7 +19,8 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::pdb;
|
using namespace llvm::pdb;
|
||||||
|
|
||||||
InfoStream::InfoStream(PDBFile &File) : Pdb(File), Stream(StreamPDB, File) {}
|
InfoStream::InfoStream(const PDBFile &File)
|
||||||
|
: Stream(llvm::make_unique<IndexedStreamData>(StreamPDB, File), File) {}
|
||||||
|
|
||||||
Error InfoStream::reload() {
|
Error InfoStream::reload() {
|
||||||
codeview::StreamReader Reader(Stream);
|
codeview::StreamReader Reader(Stream);
|
||||||
|
@ -8,28 +8,23 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
|
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
|
||||||
|
#include "llvm/DebugInfo/PDB/Raw/IPDBStreamData.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
|
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::pdb;
|
using namespace llvm::pdb;
|
||||||
|
|
||||||
MappedBlockStream::MappedBlockStream(uint32_t StreamIdx, const IPDBFile &File)
|
MappedBlockStream::MappedBlockStream(std::unique_ptr<IPDBStreamData> Data,
|
||||||
: Pdb(File) {
|
const IPDBFile &Pdb)
|
||||||
if (StreamIdx >= Pdb.getNumStreams()) {
|
: Pdb(Pdb), Data(std::move(Data)) {}
|
||||||
StreamLength = 0;
|
|
||||||
} else {
|
|
||||||
StreamLength = Pdb.getStreamByteSize(StreamIdx);
|
|
||||||
BlockList = Pdb.getStreamBlockList(StreamIdx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Error MappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,
|
Error MappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,
|
||||||
ArrayRef<uint8_t> &Buffer) const {
|
ArrayRef<uint8_t> &Buffer) const {
|
||||||
// Make sure we aren't trying to read beyond the end of the stream.
|
// Make sure we aren't trying to read beyond the end of the stream.
|
||||||
if (Size > StreamLength)
|
if (Size > Data->getLength())
|
||||||
return make_error<RawError>(raw_error_code::insufficient_buffer);
|
return make_error<RawError>(raw_error_code::insufficient_buffer);
|
||||||
if (Offset > StreamLength - Size)
|
if (Offset > Data->getLength() - Size)
|
||||||
return make_error<RawError>(raw_error_code::insufficient_buffer);
|
return make_error<RawError>(raw_error_code::insufficient_buffer);
|
||||||
|
|
||||||
if (tryReadContiguously(Offset, Size, Buffer))
|
if (tryReadContiguously(Offset, Size, Buffer))
|
||||||
@ -57,6 +52,8 @@ Error MappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,
|
|||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t MappedBlockStream::getLength() const { return Data->getLength(); }
|
||||||
|
|
||||||
bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size,
|
bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size,
|
||||||
ArrayRef<uint8_t> &Buffer) const {
|
ArrayRef<uint8_t> &Buffer) const {
|
||||||
// Attempt to fulfill the request with a reference directly into the stream.
|
// Attempt to fulfill the request with a reference directly into the stream.
|
||||||
@ -72,6 +69,7 @@ bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size,
|
|||||||
llvm::alignTo(Size - BytesFromFirstBlock, Pdb.getBlockSize()) /
|
llvm::alignTo(Size - BytesFromFirstBlock, Pdb.getBlockSize()) /
|
||||||
Pdb.getBlockSize();
|
Pdb.getBlockSize();
|
||||||
|
|
||||||
|
auto BlockList = Data->getStreamBlocks();
|
||||||
uint32_t RequiredContiguousBlocks = NumAdditionalBlocks + 1;
|
uint32_t RequiredContiguousBlocks = NumAdditionalBlocks + 1;
|
||||||
uint32_t E = BlockList[BlockNum];
|
uint32_t E = BlockList[BlockNum];
|
||||||
for (uint32_t I = 0; I < RequiredContiguousBlocks; ++I, ++E) {
|
for (uint32_t I = 0; I < RequiredContiguousBlocks; ++I, ++E) {
|
||||||
@ -93,14 +91,15 @@ Error MappedBlockStream::readBytes(uint32_t Offset,
|
|||||||
uint32_t OffsetInBlock = Offset % Pdb.getBlockSize();
|
uint32_t OffsetInBlock = Offset % Pdb.getBlockSize();
|
||||||
|
|
||||||
// Make sure we aren't trying to read beyond the end of the stream.
|
// Make sure we aren't trying to read beyond the end of the stream.
|
||||||
if (Buffer.size() > StreamLength)
|
if (Buffer.size() > Data->getLength())
|
||||||
return make_error<RawError>(raw_error_code::insufficient_buffer);
|
return make_error<RawError>(raw_error_code::insufficient_buffer);
|
||||||
if (Offset > StreamLength - Buffer.size())
|
if (Offset > Data->getLength() - Buffer.size())
|
||||||
return make_error<RawError>(raw_error_code::insufficient_buffer);
|
return make_error<RawError>(raw_error_code::insufficient_buffer);
|
||||||
|
|
||||||
uint32_t BytesLeft = Buffer.size();
|
uint32_t BytesLeft = Buffer.size();
|
||||||
uint32_t BytesWritten = 0;
|
uint32_t BytesWritten = 0;
|
||||||
uint8_t *WriteBuffer = Buffer.data();
|
uint8_t *WriteBuffer = Buffer.data();
|
||||||
|
auto BlockList = Data->getStreamBlocks();
|
||||||
while (BytesLeft > 0) {
|
while (BytesLeft > 0) {
|
||||||
uint32_t StreamBlockAddr = BlockList[BlockNum];
|
uint32_t StreamBlockAddr = BlockList[BlockNum];
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "llvm/DebugInfo/PDB/Raw/ModStream.h"
|
#include "llvm/DebugInfo/PDB/Raw/ModStream.h"
|
||||||
|
|
||||||
#include "llvm/DebugInfo/CodeView/StreamReader.h"
|
#include "llvm/DebugInfo/CodeView/StreamReader.h"
|
||||||
|
#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
|
#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
|
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
|
||||||
@ -18,8 +19,10 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::pdb;
|
using namespace llvm::pdb;
|
||||||
|
|
||||||
ModStream::ModStream(PDBFile &File, const ModInfo &Module)
|
ModStream::ModStream(const PDBFile &File, const ModInfo &Module)
|
||||||
: Mod(Module), Stream(Module.getModuleStreamIndex(), File) {}
|
: Mod(Module), Stream(llvm::make_unique<IndexedStreamData>(
|
||||||
|
Module.getModuleStreamIndex(), File),
|
||||||
|
File) {}
|
||||||
|
|
||||||
ModStream::~ModStream() {}
|
ModStream::~ModStream() {}
|
||||||
|
|
||||||
|
@ -8,8 +8,12 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
||||||
|
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
|
#include "llvm/DebugInfo/CodeView/StreamArray.h"
|
||||||
|
#include "llvm/DebugInfo/CodeView/StreamReader.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
|
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
|
||||||
|
#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
|
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
|
#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/PublicsStream.h"
|
#include "llvm/DebugInfo/PDB/Raw/PublicsStream.h"
|
||||||
@ -49,13 +53,28 @@ struct SuperBlock {
|
|||||||
// This contains the block # of the block map.
|
// This contains the block # of the block map.
|
||||||
support::ulittle32_t BlockMapAddr;
|
support::ulittle32_t BlockMapAddr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DirectoryStreamData : public IPDBStreamData {
|
||||||
|
public:
|
||||||
|
DirectoryStreamData(const PDBFile &File) : File(File) {}
|
||||||
|
|
||||||
|
virtual uint32_t getLength() { return File.getNumDirectoryBytes(); }
|
||||||
|
virtual llvm::ArrayRef<llvm::support::ulittle32_t> getStreamBlocks() {
|
||||||
|
return File.getDirectoryBlockArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const PDBFile &File;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef codeview::FixedStreamArray<support::ulittle32_t> ulittle_array;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct llvm::pdb::PDBFileContext {
|
struct llvm::pdb::PDBFileContext {
|
||||||
std::unique_ptr<MemoryBuffer> Buffer;
|
std::unique_ptr<MemoryBuffer> Buffer;
|
||||||
const SuperBlock *SB;
|
const SuperBlock *SB;
|
||||||
std::vector<uint32_t> StreamSizes;
|
ArrayRef<support::ulittle32_t> StreamSizes;
|
||||||
DenseMap<uint32_t, std::vector<uint32_t>> StreamMap;
|
std::vector<ulittle_array> StreamMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
static Error checkOffset(MemoryBufferRef M, uintptr_t Addr,
|
static Error checkOffset(MemoryBufferRef M, uintptr_t Addr,
|
||||||
@ -109,10 +128,14 @@ uint32_t PDBFile::getStreamByteSize(uint32_t StreamIndex) const {
|
|||||||
return Context->StreamSizes[StreamIndex];
|
return Context->StreamSizes[StreamIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::ArrayRef<uint32_t>
|
ArrayRef<support::ulittle32_t>
|
||||||
PDBFile::getStreamBlockList(uint32_t StreamIndex) const {
|
PDBFile::getStreamBlockList(uint32_t StreamIndex) const {
|
||||||
auto &Data = Context->StreamMap[StreamIndex];
|
auto Result = Context->StreamMap[StreamIndex];
|
||||||
return llvm::ArrayRef<uint32_t>(Data);
|
codeview::StreamReader Reader(Result.getUnderlyingStream());
|
||||||
|
ArrayRef<support::ulittle32_t> Array;
|
||||||
|
if (auto EC = Reader.readArray(Array, Result.size()))
|
||||||
|
return ArrayRef<support::ulittle32_t>();
|
||||||
|
return Array;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef PDBFile::getBlockData(uint32_t BlockIndex, uint32_t NumBytes) const {
|
StringRef PDBFile::getBlockData(uint32_t BlockIndex, uint32_t NumBytes) const {
|
||||||
@ -184,113 +207,44 @@ Error PDBFile::parseFileHeaders() {
|
|||||||
|
|
||||||
Error PDBFile::parseStreamData() {
|
Error PDBFile::parseStreamData() {
|
||||||
assert(Context && Context->SB);
|
assert(Context && Context->SB);
|
||||||
|
if (DirectoryStream)
|
||||||
|
return Error::success();
|
||||||
|
|
||||||
bool SeenNumStreams = false;
|
// bool SeenNumStreams = false;
|
||||||
uint32_t NumStreams = 0;
|
uint32_t NumStreams = 0;
|
||||||
uint32_t StreamIdx = 0;
|
// uint32_t StreamIdx = 0;
|
||||||
uint64_t DirectoryBytesRead = 0;
|
// uint64_t DirectoryBytesRead = 0;
|
||||||
|
|
||||||
MemoryBufferRef M = *Context->Buffer;
|
|
||||||
const SuperBlock *SB = Context->SB;
|
const SuperBlock *SB = Context->SB;
|
||||||
|
|
||||||
auto DirectoryBlocks = getDirectoryBlockArray();
|
// Normally you can't use a MappedBlockStream without having fully parsed the
|
||||||
|
// PDB file, because it accesses the directory and various other things, which
|
||||||
// The structure of the directory is as follows:
|
// is exactly what we are attempting to parse. By specifying a custom
|
||||||
// struct PDBDirectory {
|
// subclass of IPDBStreamData which only accesses the fields that have already
|
||||||
// uint32_t NumStreams;
|
// been parsed, we can avoid this and reuse MappedBlockStream.
|
||||||
// uint32_t StreamSizes[NumStreams];
|
auto SD = llvm::make_unique<DirectoryStreamData>(*this);
|
||||||
// uint32_t StreamMap[NumStreams][];
|
DirectoryStream = llvm::make_unique<MappedBlockStream>(std::move(SD), *this);
|
||||||
// };
|
codeview::StreamReader Reader(*DirectoryStream);
|
||||||
//
|
if (auto EC = Reader.readInteger(NumStreams))
|
||||||
// Empty streams don't consume entries in the StreamMap.
|
|
||||||
for (uint32_t DirectoryBlockAddr : DirectoryBlocks) {
|
|
||||||
uint64_t DirectoryBlockOffset =
|
|
||||||
blockToOffset(DirectoryBlockAddr, SB->BlockSize);
|
|
||||||
auto DirectoryBlock =
|
|
||||||
makeArrayRef(reinterpret_cast<const support::ulittle32_t *>(
|
|
||||||
M.getBufferStart() + DirectoryBlockOffset),
|
|
||||||
SB->BlockSize / sizeof(support::ulittle32_t));
|
|
||||||
if (auto EC = checkOffset(M, DirectoryBlock))
|
|
||||||
return EC;
|
return EC;
|
||||||
|
|
||||||
// We read data out of the directory four bytes at a time. Depending on
|
if (auto EC = Reader.readArray(Context->StreamSizes, NumStreams))
|
||||||
// where we are in the directory, the contents may be: the number of streams
|
return EC;
|
||||||
// in the directory, a stream's size, or a block in the stream map.
|
for (uint32_t I = 0; I < NumStreams; ++I) {
|
||||||
for (uint32_t Data : DirectoryBlock) {
|
|
||||||
// Don't read beyond the end of the directory.
|
|
||||||
if (DirectoryBytesRead == SB->NumDirectoryBytes)
|
|
||||||
break;
|
|
||||||
|
|
||||||
DirectoryBytesRead += sizeof(Data);
|
|
||||||
|
|
||||||
// This data must be the number of streams if we haven't seen it yet.
|
|
||||||
if (!SeenNumStreams) {
|
|
||||||
NumStreams = Data;
|
|
||||||
SeenNumStreams = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// This data must be a stream size if we have not seen them all yet.
|
|
||||||
if (Context->StreamSizes.size() < NumStreams) {
|
|
||||||
// It seems like some streams have their set to -1 when their contents
|
|
||||||
// are not present. Treat them like empty streams for now.
|
|
||||||
if (Data == UINT32_MAX)
|
|
||||||
Context->StreamSizes.push_back(0);
|
|
||||||
else
|
|
||||||
Context->StreamSizes.push_back(Data);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This data must be a stream block number if we have seen all of the
|
|
||||||
// stream sizes.
|
|
||||||
std::vector<uint32_t> *StreamBlocks = nullptr;
|
|
||||||
// Figure out which stream this block number belongs to.
|
|
||||||
while (StreamIdx < NumStreams) {
|
|
||||||
uint64_t NumExpectedStreamBlocks =
|
uint64_t NumExpectedStreamBlocks =
|
||||||
bytesToBlocks(Context->StreamSizes[StreamIdx], SB->BlockSize);
|
bytesToBlocks(getStreamByteSize(I), SB->BlockSize);
|
||||||
StreamBlocks = &Context->StreamMap[StreamIdx];
|
ulittle_array Blocks;
|
||||||
if (NumExpectedStreamBlocks > StreamBlocks->size())
|
if (auto EC = Reader.readArray(Blocks, NumExpectedStreamBlocks))
|
||||||
break;
|
return EC;
|
||||||
++StreamIdx;
|
Context->StreamMap.push_back(Blocks);
|
||||||
}
|
|
||||||
// It seems this block doesn't belong to any stream? The stream is either
|
|
||||||
// corrupt or something more mysterious is going on.
|
|
||||||
if (StreamIdx == NumStreams)
|
|
||||||
return make_error<RawError>(raw_error_code::corrupt_file,
|
|
||||||
"Orphaned block found?");
|
|
||||||
|
|
||||||
uint64_t BlockOffset = blockToOffset(Data, getBlockSize());
|
|
||||||
if (BlockOffset + getBlockSize() < BlockOffset)
|
|
||||||
return make_error<RawError>(raw_error_code::corrupt_file,
|
|
||||||
"Bogus stream block number");
|
|
||||||
if (BlockOffset + getBlockSize() > M.getBufferSize())
|
|
||||||
return make_error<RawError>(raw_error_code::corrupt_file,
|
|
||||||
"Stream block number is out of bounds");
|
|
||||||
|
|
||||||
StreamBlocks->push_back(Data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Context->StreamSizes.size() != NumStreams)
|
|
||||||
return make_error<RawError>(
|
|
||||||
raw_error_code::corrupt_file,
|
|
||||||
"The directory has fewer streams then expected");
|
|
||||||
|
|
||||||
for (uint32_t I = 0; I != NumStreams; ++I) {
|
|
||||||
uint64_t NumExpectedStreamBlocks =
|
|
||||||
bytesToBlocks(getStreamByteSize(I), getBlockSize());
|
|
||||||
size_t NumStreamBlocks = getStreamBlockList(I).size();
|
|
||||||
if (NumExpectedStreamBlocks != NumStreamBlocks)
|
|
||||||
return make_error<RawError>(raw_error_code::corrupt_file,
|
|
||||||
"The number of stream blocks is not "
|
|
||||||
"sufficient for the size of this stream");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We should have read exactly SB->NumDirectoryBytes bytes.
|
// We should have read exactly SB->NumDirectoryBytes bytes.
|
||||||
assert(DirectoryBytesRead == SB->NumDirectoryBytes);
|
assert(Reader.bytesRemaining() == 0);
|
||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() {
|
llvm::ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() const {
|
||||||
return makeArrayRef(
|
return makeArrayRef(
|
||||||
reinterpret_cast<const support::ulittle32_t *>(
|
reinterpret_cast<const support::ulittle32_t *>(
|
||||||
Context->Buffer->getBufferStart() + getBlockMapOffset()),
|
Context->Buffer->getBufferStart() + getBlockMapOffset()),
|
||||||
@ -371,7 +325,8 @@ Expected<NameHashTable &> PDBFile::getStringTable() {
|
|||||||
|
|
||||||
if (NameStreamIndex == 0)
|
if (NameStreamIndex == 0)
|
||||||
return make_error<RawError>(raw_error_code::no_stream);
|
return make_error<RawError>(raw_error_code::no_stream);
|
||||||
auto S = llvm::make_unique<MappedBlockStream>(NameStreamIndex, *this);
|
auto SD = llvm::make_unique<IndexedStreamData>(NameStreamIndex, *this);
|
||||||
|
auto S = llvm::make_unique<MappedBlockStream>(std::move(SD), *this);
|
||||||
codeview::StreamReader Reader(*S);
|
codeview::StreamReader Reader(*S);
|
||||||
auto N = llvm::make_unique<NameHashTable>();
|
auto N = llvm::make_unique<NameHashTable>();
|
||||||
if (auto EC = N->load(Reader))
|
if (auto EC = N->load(Reader))
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "llvm/DebugInfo/CodeView/CodeView.h"
|
#include "llvm/DebugInfo/CodeView/CodeView.h"
|
||||||
#include "llvm/DebugInfo/CodeView/StreamReader.h"
|
#include "llvm/DebugInfo/CodeView/StreamReader.h"
|
||||||
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
||||||
|
#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
|
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
|
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
|
||||||
@ -71,7 +72,8 @@ struct PublicsStream::GSIHashHeader {
|
|||||||
};
|
};
|
||||||
|
|
||||||
PublicsStream::PublicsStream(PDBFile &File, uint32_t StreamNum)
|
PublicsStream::PublicsStream(PDBFile &File, uint32_t StreamNum)
|
||||||
: Pdb(File), StreamNum(StreamNum), Stream(StreamNum, File) {}
|
: Pdb(File), StreamNum(StreamNum),
|
||||||
|
Stream(llvm::make_unique<IndexedStreamData>(StreamNum, File), File) {}
|
||||||
|
|
||||||
PublicsStream::~PublicsStream() {}
|
PublicsStream::~PublicsStream() {}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "llvm/DebugInfo/CodeView/CodeView.h"
|
#include "llvm/DebugInfo/CodeView/CodeView.h"
|
||||||
#include "llvm/DebugInfo/CodeView/StreamReader.h"
|
#include "llvm/DebugInfo/CodeView/StreamReader.h"
|
||||||
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
||||||
|
#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
|
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
|
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
|
||||||
@ -23,8 +24,9 @@ using namespace llvm;
|
|||||||
using namespace llvm::support;
|
using namespace llvm::support;
|
||||||
using namespace llvm::pdb;
|
using namespace llvm::pdb;
|
||||||
|
|
||||||
SymbolStream::SymbolStream(PDBFile &File, uint32_t StreamNum)
|
SymbolStream::SymbolStream(const PDBFile &File, uint32_t StreamNum)
|
||||||
: MappedStream(StreamNum, File) {}
|
: MappedStream(llvm::make_unique<IndexedStreamData>(StreamNum, File),
|
||||||
|
File) {}
|
||||||
|
|
||||||
SymbolStream::~SymbolStream() {}
|
SymbolStream::~SymbolStream() {}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "llvm/DebugInfo/CodeView/StreamReader.h"
|
#include "llvm/DebugInfo/CodeView/StreamReader.h"
|
||||||
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
|
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
|
||||||
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
||||||
|
#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
|
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
|
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
|
||||||
@ -61,8 +62,10 @@ struct TpiStream::HeaderInfo {
|
|||||||
EmbeddedBuf HashAdjBuffer;
|
EmbeddedBuf HashAdjBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
TpiStream::TpiStream(PDBFile &File, uint32_t StreamIdx)
|
TpiStream::TpiStream(const PDBFile &File, uint32_t StreamIdx)
|
||||||
: Pdb(File), Stream(StreamIdx, File), HashFunction(nullptr) {}
|
: Pdb(File),
|
||||||
|
Stream(llvm::make_unique<IndexedStreamData>(StreamIdx, File), File),
|
||||||
|
HashFunction(nullptr) {}
|
||||||
|
|
||||||
TpiStream::~TpiStream() {}
|
TpiStream::~TpiStream() {}
|
||||||
|
|
||||||
@ -101,7 +104,8 @@ Error TpiStream::reload() {
|
|||||||
return EC;
|
return EC;
|
||||||
|
|
||||||
// Hash indices, hash values, etc come from the hash stream.
|
// Hash indices, hash values, etc come from the hash stream.
|
||||||
HashStream.reset(new MappedBlockStream(Header->HashStreamIndex, Pdb));
|
HashStream.reset(new MappedBlockStream(
|
||||||
|
llvm::make_unique<IndexedStreamData>(Header->HashStreamIndex, Pdb), Pdb));
|
||||||
codeview::StreamReader HSR(*HashStream);
|
codeview::StreamReader HSR(*HashStream);
|
||||||
|
|
||||||
uint32_t NumHashValues = Header->HashValueBuffer.Length / sizeof(ulittle32_t);
|
uint32_t NumHashValues = Header->HashValueBuffer.Length / sizeof(ulittle32_t);
|
||||||
|
11
lib/DebugInfo/PDB/Raw/TpiStream.cpp.rej
Normal file
11
lib/DebugInfo/PDB/Raw/TpiStream.cpp.rej
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
diff a/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/lib/DebugInfo/PDB/Raw/TpiStream.cpp (rejected hunks)
|
||||||
|
@@ -101,7 +104,8 @@
|
||||||
|
return EC;
|
||||||
|
|
||||||
|
// Hash indices, hash values, etc come from the hash stream.
|
||||||
|
- HashStream.reset(new MappedBlockStream(Header->HashStreamIndex, Pdb));
|
||||||
|
+ HashStream.reset(new MappedBlockStream(
|
||||||
|
+ llvm::make_unique<IndexedStreamData>(Header->HashStreamIndex, Pdb), Pdb));
|
||||||
|
codeview::StreamReader HSR(*HashStream);
|
||||||
|
uint32_t NumHashValues = Header->HashValueBuffer.Length / sizeof(ulittle32_t);
|
||||||
|
HSR.setOffset(Header->HashValueBuffer.Off);
|
@ -17,6 +17,7 @@
|
|||||||
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
|
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/EnumTables.h"
|
#include "llvm/DebugInfo/PDB/Raw/EnumTables.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h"
|
#include "llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h"
|
||||||
|
#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
|
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
|
#include "llvm/DebugInfo/PDB/Raw/ModInfo.h"
|
||||||
#include "llvm/DebugInfo/PDB/Raw/ModStream.h"
|
#include "llvm/DebugInfo/PDB/Raw/ModStream.h"
|
||||||
@ -194,7 +195,8 @@ Error LLVMOutputStyle::dumpStreamData() {
|
|||||||
DumpStreamNum >= StreamCount)
|
DumpStreamNum >= StreamCount)
|
||||||
return Error::success();
|
return Error::success();
|
||||||
|
|
||||||
MappedBlockStream S(DumpStreamNum, File);
|
MappedBlockStream S(llvm::make_unique<IndexedStreamData>(DumpStreamNum, File),
|
||||||
|
File);
|
||||||
codeview::StreamReader R(S);
|
codeview::StreamReader R(S);
|
||||||
while (R.bytesRemaining() > 0) {
|
while (R.bytesRemaining() > 0) {
|
||||||
ArrayRef<uint8_t> Data;
|
ArrayRef<uint8_t> Data;
|
||||||
@ -244,7 +246,8 @@ Error LLVMOutputStyle::dumpNamedStream() {
|
|||||||
DictScope D(P, Name);
|
DictScope D(P, Name);
|
||||||
P.printNumber("Index", NameStreamIndex);
|
P.printNumber("Index", NameStreamIndex);
|
||||||
|
|
||||||
MappedBlockStream NameStream(NameStreamIndex, File);
|
MappedBlockStream NameStream(
|
||||||
|
llvm::make_unique<IndexedStreamData>(NameStreamIndex, File), File);
|
||||||
codeview::StreamReader Reader(NameStream);
|
codeview::StreamReader Reader(NameStream);
|
||||||
|
|
||||||
NameHashTable NameTable;
|
NameHashTable NameTable;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user