[llvm] r268343 - Parse the TPI (type information) stream of PDB files.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Tue May 3 20:15:17 PDT 2016


See D19897 :)

On Tue, May 3, 2016 at 7:43 PM David Majnemer <david.majnemer at gmail.com>
wrote:

> On Mon, May 2, 2016 at 5:28 PM, Zachary Turner via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>> Author: zturner
>> Date: Mon May  2 19:28:21 2016
>> New Revision: 268343
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=268343&view=rev
>> Log:
>> Parse the TPI (type information) stream of PDB files.
>>
>> This parses the TPI stream (stream 2) from the PDB file. This stream
>> contains some header information followed by a series of codeview records.
>> There is some additional complexity here in that alongside this stream of
>> codeview records is a serialized hash table in order to efficiently query
>> the types. We parse the necessary bookkeeping information to allow us to
>> reconstruct the hash table, but we do not actually construct it yet as
>> there are still a few things that need to be understood first.
>>
>> Differential Revision: http://reviews.llvm.org/D19840
>> Reviewed By: ruiu, rnk
>>
>> Added:
>>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h
>>     llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp
>> Modified:
>>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ByteStream.h
>>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h
>>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
>>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawConstants.h
>>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/StreamInterface.h
>>     llvm/trunk/include/llvm/DebugInfo/PDB/Raw/StreamReader.h
>>     llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt
>>     llvm/trunk/lib/DebugInfo/PDB/Raw/ByteStream.cpp
>>     llvm/trunk/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp
>>     llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp
>>     llvm/trunk/lib/DebugInfo/PDB/Raw/StreamReader.cpp
>>     llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test
>>     llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
>>
>> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ByteStream.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ByteStream.h?rev=268343&r1=268342&r2=268343&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ByteStream.h (original)
>> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/ByteStream.h Mon May  2
>> 19:28:21 2016
>> @@ -35,6 +35,10 @@ public:
>>
>>    std::error_code readBytes(uint32_t Offset,
>>                              MutableArrayRef<uint8_t> Buffer) const
>> override;
>> +
>> +  std::error_code getArrayRef(uint32_t Offset, ArrayRef<uint8_t> &Buffer,
>> +                              uint32_t Length) const override;
>> +
>>    uint32_t getLength() const override;
>>
>>    ArrayRef<uint8_t> data() const { return Data; }
>>
>> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h?rev=268343&r1=268342&r2=268343&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h
>> (original)
>> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h Mon
>> May  2 19:28:21 2016
>> @@ -27,6 +27,9 @@ public:
>>
>>    std::error_code readBytes(uint32_t Offset,
>>                              MutableArrayRef<uint8_t> Buffer) const
>> override;
>> +  std::error_code getArrayRef(uint32_t Offset, ArrayRef<uint8_t> &Buffer,
>> +                              uint32_t Length) const override;
>> +
>>    uint32_t getLength() const override { return StreamLength; }
>>
>>  private:
>>
>> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h?rev=268343&r1=268342&r2=268343&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h (original)
>> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h Mon May  2
>> 19:28:21 2016
>> @@ -23,6 +23,7 @@ namespace pdb {
>>  struct PDBFileContext;
>>  class DbiStream;
>>  class InfoStream;
>> +class TpiStream;
>>
>>  class PDBFile {
>>  public:
>> @@ -59,11 +60,13 @@ public:
>>
>>    InfoStream &getPDBInfoStream();
>>    DbiStream &getPDBDbiStream();
>> +  TpiStream &getPDBTpiStream();
>>
>>  private:
>>    std::unique_ptr<PDBFileContext> Context;
>>    std::unique_ptr<InfoStream> Info;
>>    std::unique_ptr<DbiStream> Dbi;
>> +  std::unique_ptr<TpiStream> Tpi;
>>  };
>>  }
>>  }
>>
>> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawConstants.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawConstants.h?rev=268343&r1=268342&r2=268343&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawConstants.h (original)
>> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/RawConstants.h Mon May  2
>> 19:28:21 2016
>> @@ -35,6 +35,14 @@ enum PdbRaw_DbiVer : uint32_t {
>>    PdbDbiV110 = 20091201
>>  };
>>
>> +enum PdbRaw_TpiVer : uint32_t {
>> +  PdbTpiV40 = 19950410,
>> +  PdbTpiV41 = 19951122,
>> +  PdbTpiV50 = 19961031,
>> +  PdbTpiV70 = 19990903,
>> +  PdbTpiV80 = 20040203,
>> +};
>> +
>>  enum SpecialStream : uint32_t {
>>    StreamPDB = 1,
>>    StreamTPI = 2,
>>
>> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/StreamInterface.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/StreamInterface.h?rev=268343&r1=268342&r2=268343&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/StreamInterface.h (original)
>> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/StreamInterface.h Mon May
>> 2 19:28:21 2016
>> @@ -23,6 +23,10 @@ public:
>>
>>    virtual std::error_code readBytes(uint32_t Offset,
>>                                      MutableArrayRef<uint8_t> Buffer)
>> const = 0;
>> +  virtual std::error_code getArrayRef(uint32_t Offset,
>> +                                      ArrayRef<uint8_t> &Buffer,
>> +                                      uint32_t Length) const = 0;
>> +
>>    virtual uint32_t getLength() const = 0;
>>  };
>>  }
>>
>> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/StreamReader.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/StreamReader.h?rev=268343&r1=268342&r2=268343&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/StreamReader.h (original)
>> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/StreamReader.h Mon May  2
>> 19:28:21 2016
>> @@ -39,6 +39,8 @@ public:
>>      return readBytes(Casted);
>>    }
>>
>> +  std::error_code getArrayRef(ArrayRef<uint8_t> &Array, uint32_t Length);
>> +
>>    void setOffset(uint32_t Off) { Offset = Off; }
>>    uint32_t getOffset() const { return Offset; }
>>    uint32_t getLength() const { return Stream.getLength(); }
>>
>> Added: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h?rev=268343&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h (added)
>> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStream.h Mon May  2
>> 19:28:21 2016
>> @@ -0,0 +1,62 @@
>> +//===- TpiStream.cpp - PDB Type Info (TPI) Stream 2 Access ------*- 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_PDBTPISTREAM_H
>> +#define LLVM_DEBUGINFO_PDB_RAW_PDBTPISTREAM_H
>> +
>> +#include "llvm/DebugInfo/PDB/PDBTypes.h"
>> +#include "llvm/DebugInfo/PDB/Raw/ByteStream.h"
>> +#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
>> +#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
>> +
>> +namespace llvm {
>> +namespace pdb {
>> +class PDBFile;
>> +
>> +typedef uint32_t (*HashFunctionType)(uint8_t *, uint32_t);
>> +
>> +class TpiStream {
>> +  struct HeaderInfo;
>> +
>> +public:
>> +  struct HashedTypeRecord {
>> +    uint32_t Hash;
>> +    codeview::TypeLeafKind Kind;
>> +    ArrayRef<uint8_t> Record;
>> +  };
>> +
>> +  TpiStream(PDBFile &File);
>> +  ~TpiStream();
>> +  std::error_code reload();
>> +
>> +  PdbRaw_TpiVer getTpiVersion() const;
>> +
>> +  uint32_t TypeIndexBegin() const;
>> +  uint32_t TypeIndexEnd() const;
>> +  uint32_t NumTypeRecords() const;
>> +
>> +  ArrayRef<HashedTypeRecord> records() const;
>> +
>> +private:
>> +  PDBFile &Pdb;
>> +  MappedBlockStream Stream;
>> +  HashFunctionType HashFunction;
>> +
>> +  ByteStream RecordsBuffer;
>> +  ByteStream TypeIndexOffsetBuffer;
>> +  ByteStream HashValuesBuffer;
>> +  ByteStream HashAdjBuffer;
>> +
>> +  std::vector<HashedTypeRecord> TypeRecords;
>> +  std::unique_ptr<HeaderInfo> Header;
>> +};
>> +}
>> +}
>> +
>> +#endif
>>
>> Modified: llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt?rev=268343&r1=268342&r2=268343&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt (original)
>> +++ llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt Mon May  2 19:28:21 2016
>> @@ -36,7 +36,8 @@ add_pdb_impl_folder(Raw
>>    Raw/NameHashTable.cpp
>>    Raw/NameMap.cpp
>>    Raw/RawSession.cpp
>> -  Raw/StreamReader.cpp)
>> +  Raw/StreamReader.cpp
>> +  Raw/TpiStream.cpp)
>>
>>  list(APPEND LIBPDB_ADDITIONAL_HEADER_DIRS
>> "${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/PDB")
>>
>>
>> Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/ByteStream.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/ByteStream.cpp?rev=268343&r1=268342&r2=268343&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/PDB/Raw/ByteStream.cpp (original)
>> +++ llvm/trunk/lib/DebugInfo/PDB/Raw/ByteStream.cpp Mon May  2 19:28:21
>> 2016
>> @@ -58,6 +58,15 @@ std::error_code ByteStream::readBytes(ui
>>    return std::error_code();
>>  }
>>
>> +std::error_code ByteStream::getArrayRef(uint32_t Offset,
>> +                                        ArrayRef<uint8_t> &Buffer,
>> +                                        uint32_t Length) const {
>> +  if (Data.size() < Length + Offset)
>> +    return std::make_error_code(std::errc::bad_address);
>> +  Buffer = Data.slice(Offset, Length);
>> +  return std::error_code();
>> +}
>> +
>>  uint32_t ByteStream::getLength() const { return Data.size(); }
>>
>>  StringRef ByteStream::str() const {
>>
>> Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp?rev=268343&r1=268342&r2=268343&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp (original)
>> +++ llvm/trunk/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp Mon May  2
>> 19:28:21 2016
>> @@ -51,3 +51,9 @@ MappedBlockStream::readBytes(uint32_t Of
>>
>>    return std::error_code();
>>  }
>> +
>> +std::error_code MappedBlockStream::getArrayRef(uint32_t Offset,
>> +                                               ArrayRef<uint8_t> &Buffer,
>> +                                               uint32_t Length) const {
>> +  return std::make_error_code(std::errc::operation_not_supported);
>> +}
>>
>> Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp?rev=268343&r1=268342&r2=268343&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp (original)
>> +++ llvm/trunk/lib/DebugInfo/PDB/Raw/PDBFile.cpp Mon May  2 19:28:21 2016
>> @@ -11,6 +11,7 @@
>>  #include "llvm/ADT/ArrayRef.h"
>>  #include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
>>  #include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
>> +#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
>>  #include "llvm/Support/Endian.h"
>>  #include "llvm/Support/MemoryBuffer.h"
>>
>> @@ -119,6 +120,8 @@ StringRef PDBFile::getBlockData(uint32_t
>>  std::error_code PDBFile::parseFileHeaders() {
>>    std::error_code EC;
>>    MemoryBufferRef BufferRef = *Context->Buffer;
>> +  // Make sure the file is sufficiently large to hold a super block.
>> +  // Do this before attempting to read the super block.
>>    if (BufferRef.getBufferSize() < sizeof(SuperBlock))
>>      return std::make_error_code(std::errc::illegal_byte_sequence);
>>
>> @@ -135,10 +138,6 @@ std::error_code PDBFile::parseFileHeader
>>    if (BufferRef.getBufferSize() % SB->BlockSize != 0)
>>      return std::make_error_code(std::errc::illegal_byte_sequence);
>>
>> -  // Make sure the file is sufficiently large to hold a super block.
>> -  if (BufferRef.getBufferSize() < sizeof(SuperBlock))
>> -    return std::make_error_code(std::errc::illegal_byte_sequence);
>> -
>>    // Check the magic bytes.
>>    if (memcmp(SB->MagicBytes, Magic, sizeof(Magic)) != 0)
>>      return std::make_error_code(std::errc::illegal_byte_sequence);
>> @@ -271,3 +270,11 @@ DbiStream &PDBFile::getPDBDbiStream() {
>>    }
>>    return *Dbi;
>>  }
>> +
>> +TpiStream &PDBFile::getPDBTpiStream() {
>> +  if (!Tpi) {
>> +    Tpi.reset(new TpiStream(*this));
>> +    Tpi->reload();
>> +  }
>> +  return *Tpi;
>> +}
>>
>> Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/StreamReader.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/StreamReader.cpp?rev=268343&r1=268342&r2=268343&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/PDB/Raw/StreamReader.cpp (original)
>> +++ llvm/trunk/lib/DebugInfo/PDB/Raw/StreamReader.cpp Mon May  2 19:28:21
>> 2016
>> @@ -39,3 +39,11 @@ std::error_code StreamReader::readZeroSt
>>    } while (C != '\0');
>>    return std::error_code();
>>  }
>> +
>> +std::error_code StreamReader::getArrayRef(ArrayRef<uint8_t> &Array,
>> +                                          uint32_t Length) {
>> +  if (auto EC = Stream.getArrayRef(Offset, Array, Length))
>> +    return EC;
>> +  Offset += Length;
>> +  return std::error_code();
>> +}
>>
>> Added: llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp?rev=268343&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp (added)
>> +++ llvm/trunk/lib/DebugInfo/PDB/Raw/TpiStream.cpp Mon May  2 19:28:21
>> 2016
>> @@ -0,0 +1,143 @@
>> +//===- TpiStream.cpp - PDB Type Info (TPI) Stream 2 Access
>> ----------------===//
>> +//
>> +//                     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/TpiStream.h"
>> +
>> +#include "llvm/DebugInfo/CodeView/CodeView.h"
>> +#include "llvm/DebugInfo/CodeView/TypeRecord.h"
>> +#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
>> +#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
>> +#include "llvm/DebugInfo/PDB/Raw/StreamReader.h"
>> +
>> +#include "llvm/Support/Endian.h"
>> +
>> +using namespace llvm;
>> +using namespace llvm::support;
>> +using namespace llvm::pdb;
>> +
>> +namespace {
>> +const uint32_t MinTypeIndex = codeview::TypeIndex::FirstNonSimpleIndex;
>> +
>> +const uint32_t MinHashBuckets = 0x1000;
>> +const uint32_t MaxHashBuckets = 0x40000;
>> +}
>> +
>> +static uint32_t HashBufferV8(uint8_t *buffer, uint32_t NumBuckets) {
>> +  // Not yet implemented, this is probably some variation of CRC32 but
>> we need
>> +  // to be sure of the precise implementation otherwise we won't be able
>> to work
>> +  // with persisted hash values.
>> +  return 0;
>> +}
>> +
>> +struct TpiStream::HeaderInfo {
>> +  struct EmbeddedBuf {
>> +    little32_t Off;
>> +    ulittle32_t Length;
>> +  };
>> +
>> +  ulittle32_t Version;
>> +  ulittle32_t HeaderSize;
>> +  ulittle32_t TypeIndexBegin;
>> +  ulittle32_t TypeIndexEnd;
>> +  ulittle32_t TypeRecordBytes;
>> +
>> +  ulittle16_t HashStreamIndex;
>> +  ulittle16_t HashAuxStreamIndex;
>> +  ulittle32_t HashKeySize;
>> +  ulittle32_t NumHashBuckets;
>> +
>> +  EmbeddedBuf HashValueBuffer;
>> +  EmbeddedBuf IndexOffsetBuffer;
>> +  EmbeddedBuf HashAdjBuffer;
>> +};
>> +
>> +TpiStream::TpiStream(PDBFile &File)
>> +    : Pdb(File), Stream(StreamTPI, File), HashFunction(nullptr) {}
>> +
>> +TpiStream::~TpiStream() {}
>> +
>> +std::error_code TpiStream::reload() {
>> +  StreamReader Reader(Stream);
>> +
>> +  if (Reader.bytesRemaining() < sizeof(HeaderInfo))
>> +    return std::make_error_code(std::errc::illegal_byte_sequence);
>> +
>> +  Header.reset(new HeaderInfo());
>> +  Reader.readObject(Header.get());
>> +
>> +  if (Header->Version != PdbTpiV80)
>> +    return std::make_error_code(std::errc::not_supported);
>> +
>> +  if (Header->HeaderSize != sizeof(HeaderInfo))
>> +    return std::make_error_code(std::errc::illegal_byte_sequence);
>> +
>> +  if (Header->HashKeySize != sizeof(ulittle32_t))
>> +    return std::make_error_code(std::errc::illegal_byte_sequence);
>> +
>> +  if (Header->NumHashBuckets < MinHashBuckets ||
>> +      Header->NumHashBuckets > MaxHashBuckets)
>> +    return std::make_error_code(std::errc::illegal_byte_sequence);
>> +
>> +  HashFunction = HashBufferV8;
>> +
>> +  // The actual type records themselves come from this stream
>> +  RecordsBuffer.initialize(Reader, Header->TypeRecordBytes);
>> +  TypeRecords.resize(TypeIndexEnd() - ::MinTypeIndex);
>> +  StreamReader RecordsReader(RecordsBuffer);
>> +  for (uint32_t I = TypeIndexBegin(); I < TypeIndexEnd(); ++I) {
>> +    HashedTypeRecord &Record = TypeRecords[I - ::MinTypeIndex];
>> +    codeview::TypeRecordPrefix Prefix;
>> +    if (auto EC = RecordsReader.readObject(&Prefix))
>> +      return EC;
>> +
>> +    Record.Kind =
>> +
>> static_cast<codeview::TypeLeafKind>(static_cast<uint16_t>(Prefix.Leaf));
>> +
>> +    // Since we read this entire buffer into a ByteStream, we are
>> guaranteed
>> +    // that the entire buffer is contiguous (i.e. there's no longer a
>> chance
>> +    // that it splits across a page boundary.  So we can request a
>> reference
>> +    // directly into the stream buffer to avoid unnecessary memory
>> copies.
>> +    uint32_t RecordSize = Prefix.Len - sizeof(Prefix.Leaf);
>> +    if (auto EC = RecordsReader.getArrayRef(Record.Record, RecordSize))
>> +      return EC;
>> +  }
>> +
>> +  // Hash indices, hash values, etc come from the hash stream.
>> +  MappedBlockStream HS(Header->HashStreamIndex, Pdb);
>> +  StreamReader HSR(HS);
>> +  HSR.setOffset(Header->HashValueBuffer.Off);
>> +  HashValuesBuffer.initialize(HSR, Header->HashValueBuffer.Length);
>> +
>> +  HSR.setOffset(Header->HashAdjBuffer.Off);
>> +  HashAdjBuffer.initialize(HSR, Header->HashAdjBuffer.Length);
>> +
>> +  HSR.setOffset(Header->IndexOffsetBuffer.Off);
>> +  TypeIndexOffsetBuffer.initialize(HSR,
>> Header->IndexOffsetBuffer.Length);
>> +
>> +  return std::error_code();
>> +}
>> +
>> +PdbRaw_TpiVer TpiStream::getTpiVersion() const {
>> +  uint32_t Value = Header->Version;
>> +  return static_cast<PdbRaw_TpiVer>(Value);
>> +}
>> +
>> +uint32_t TpiStream::TypeIndexBegin() const { return
>> Header->TypeIndexBegin; }
>> +
>> +uint32_t TpiStream::TypeIndexEnd() const { return Header->TypeIndexEnd; }
>> +
>> +uint32_t TpiStream::NumTypeRecords() const {
>> +  return TypeIndexEnd() - TypeIndexBegin();
>> +}
>> +
>> +ArrayRef<TpiStream::HashedTypeRecord> TpiStream::records() const {
>> +  const HashedTypeRecord *Begin =
>> +      &TypeRecords[TypeIndexBegin() - ::MinTypeIndex];
>> +  return ArrayRef<HashedTypeRecord>(Begin, NumTypeRecords());
>> +}
>>
>> Modified: llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test?rev=268343&r1=268342&r2=268343&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test (original)
>> +++ llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test Mon May  2
>> 19:28:21 2016
>> @@ -62,6 +62,15 @@
>>  ; EMPTY-NEXT:     Type Server Index: 0
>>  ; EMPTY-NEXT:     Has EC Info: 0
>>  ; EMPTY-NEXT:     0 Contributing Source Files:
>> +; EMPTY-NEXT: TPI Version: 20040203
>> +; EMPTY-NEXT: Record count: 75
>> +; EMPTY-NEXT:   Kind: 0x4609  Bytes: [00 00 00 00]
>> +; EMPTY-NEXT:   Kind: 0x4104  Bytes: [74 00 00 00 00 00 00 00 00 10 00
>> 00]
>> +; EMPTY-NEXT:   Kind: 0x4611  Bytes: [02 15 03 00 01 00 61 70 61 72 74
>> 6D 65 6E 74 00
>> +; EMPTY-NEXT:                         02 15 03 00 02 00 73 69 6E 67 6C
>> 65 00 F3 F2 F1
>> +; EMPTY-NEXT:                         02 15 03 00 03 00 66 72 65 65 00
>> F1 02 15 03 00
>> +; EMPTY-NEXT:                         04 00 6E 65 75 74 72 61 6C 00 F2
>> F1 02 15 03 00
>> +; EMPTY-NEXT:                         05 00 62 6F 74 68 00 F1]
>>
>>  BIG:      BlockSize: 4096
>>  BIG-NEXT: Unknown0: 2
>>
>> Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=268343&r1=268342&r2=268343&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
>> +++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Mon May  2 19:28:21
>> 2016
>> @@ -43,6 +43,7 @@
>>  #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
>>  #include "llvm/DebugInfo/PDB/Raw/RawSession.h"
>>  #include "llvm/DebugInfo/PDB/Raw/StreamReader.h"
>> +#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
>>  #include "llvm/Support/CommandLine.h"
>>  #include "llvm/Support/ConvertUTF.h"
>>  #include "llvm/Support/FileSystem.h"
>> @@ -148,6 +149,29 @@ cl::opt<bool> NoEnumDefs("no-enum-defini
>>                           cl::cat(FilterCategory));
>>  }
>>
>> +static void dumpBytes(raw_ostream &S, ArrayRef<uint8_t> Bytes,
>> +                      uint32_t BytesPerRow, uint32_t Indent) {
>> +  S << "[";
>> +  uint32_t I = 0;
>> +
>> +  uint32_t BytesRemaining = Bytes.size();
>> +  while (BytesRemaining > 0) {
>> +    uint32_t BytesThisLine = std::min(BytesRemaining, BytesPerRow);
>> +    for (size_t L = 0; L < BytesThisLine; ++L, ++I) {
>> +      S << format_hex_no_prefix(Bytes[I], 2, true);
>> +      if (L + 1 < BytesThisLine)
>> +        S << ' ';
>> +    }
>> +    BytesRemaining -= BytesThisLine;
>> +    if (BytesRemaining > 0) {
>> +      S << '\n';
>> +      S.indent(Indent);
>> +    }
>> +  }
>> +  S << ']';
>> +  S.flush();
>> +}
>>
>
> Could this reuse ScopedPrinter via it's printBinaryBlock?
>
>
>> +
>>  static void dumpStructure(RawSession &RS) {
>>    PDBFile &File = RS.getPDBFile();
>>
>> @@ -293,6 +317,16 @@ static void dumpStructure(RawSession &RS
>>        outs().indent(8) << File << '\n';
>>      }
>>    }
>> +
>> +  TpiStream &Tpi = File.getPDBTpiStream();
>> +  outs() << "TPI Version: " << Tpi.getTpiVersion() << '\n';
>> +  outs() << "Record count: " << Tpi.NumTypeRecords() << '\n';
>> +  for (auto &Record : Tpi.records()) {
>> +    outs().indent(2) << "Kind: 0x" << Record.Kind;
>> +    outs().indent(2) << "Bytes: ";
>> +    dumpBytes(outs(), Record.Record, 16, 24);
>> +    outs() << '\n';
>> +  }
>>  }
>>
>>  static void reportError(StringRef Path, PDB_ErrorCode Error) {
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160504/7d59ef13/attachment.html>


More information about the llvm-commits mailing list