Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Publics stream seems to contain information as to public symbols. It actually contains a serialized hash table along with fixed-sized headers. This patch is not complete. It scans only till the end of the stream and dump the header information. I'll write code to de-serialize the hash table later. Reviewers: zturner Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D20256 llvm-svn: 269484
- Loading branch information
Showing
10 changed files
with
251 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
//===- PublicsStream.h - PDB Public Symbol Stream -------- ------*- 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_PUBLICSSTREAM_H | ||
#define LLVM_DEBUGINFO_PDB_RAW_PUBLICSSTREAM_H | ||
|
||
#include "llvm/DebugInfo/CodeView/TypeStream.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" | ||
|
||
#include "llvm/Support/Error.h" | ||
|
||
namespace llvm { | ||
namespace pdb { | ||
class PDBFile; | ||
|
||
class PublicsStream { | ||
struct HeaderInfo; | ||
struct GSIHashHeader; | ||
struct HRFile; | ||
|
||
public: | ||
PublicsStream(PDBFile &File, uint32_t StreamNum); | ||
~PublicsStream(); | ||
Error reload(); | ||
|
||
uint32_t getStreamNum() const { return StreamNum; } | ||
uint32_t getSymHash() const; | ||
uint32_t getAddrMap() const; | ||
uint32_t getNumBuckets() const { return NumBuckets; } | ||
|
||
private: | ||
uint32_t StreamNum; | ||
MappedBlockStream Stream; | ||
uint32_t NumBuckets = 0; | ||
|
||
std::unique_ptr<HeaderInfo> Header; | ||
std::unique_ptr<GSIHashHeader> HashHdr; | ||
}; | ||
} | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
//===- PublicsStream.cpp - PDB Public Symbol Stream -----------------------===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// The data structures defined in this file are based on the reference | ||
// implementation which is available at | ||
// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h | ||
// | ||
// When you are reading the reference source code, you'd find the | ||
// information below useful. | ||
// | ||
// - ppdb1->m_fMinimalDbgInfo seems to be always true. | ||
// - SMALLBUCKETS macro is defined. | ||
// | ||
// The reference doesn't compile, so I learned just by reading code. | ||
// It's not guaranteed to be correct. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "llvm/DebugInfo/PDB/Raw/PublicsStream.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/RawError.h" | ||
#include "llvm/DebugInfo/PDB/Raw/StreamReader.h" | ||
|
||
#include "llvm/ADT/BitVector.h" | ||
#include "llvm/Support/Endian.h" | ||
#include "llvm/Support/Format.h" | ||
#include "llvm/Support/MathExtras.h" | ||
|
||
using namespace llvm; | ||
using namespace llvm::support; | ||
using namespace llvm::pdb; | ||
|
||
|
||
static const unsigned IPHR_HASH = 4096; | ||
|
||
// This is PSGSIHDR struct defined in | ||
// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h | ||
struct PublicsStream::HeaderInfo { | ||
ulittle32_t SymHash; | ||
ulittle32_t AddrMap; | ||
ulittle32_t NumThunks; | ||
ulittle32_t SizeOfThunk; | ||
ulittle16_t ISectThunkTable; | ||
char Padding[2]; | ||
ulittle32_t OffThunkTable; | ||
ulittle32_t NumSects; | ||
}; | ||
|
||
|
||
// This is GSIHashHdr struct defined in | ||
struct PublicsStream::GSIHashHeader { | ||
enum { | ||
HdrSignature = -1, | ||
HdrVersion = 0xeffe0000 + 19990810, | ||
}; | ||
ulittle32_t VerSignature; | ||
ulittle32_t VerHdr; | ||
ulittle32_t HrSize; | ||
ulittle32_t NumBuckets; | ||
}; | ||
|
||
struct PublicsStream::HRFile { | ||
ulittle32_t Off; | ||
ulittle32_t CRef; | ||
}; | ||
|
||
PublicsStream::PublicsStream(PDBFile &File, uint32_t StreamNum) | ||
: StreamNum(StreamNum), Stream(StreamNum, File) {} | ||
|
||
PublicsStream::~PublicsStream() {} | ||
|
||
uint32_t PublicsStream::getSymHash() const { return Header->SymHash; } | ||
uint32_t PublicsStream::getAddrMap() const { return Header->AddrMap; } | ||
|
||
// Publics stream contains fixed-size headers and a serialized hash table. | ||
// This implementation is not complete yet. It reads till the end of the | ||
// stream so that we verify the stream is at least not corrupted. However, | ||
// we skip over the hash table which we believe contains information about | ||
// public symbols. | ||
Error PublicsStream::reload() { | ||
StreamReader Reader(Stream); | ||
|
||
// Check stream size. | ||
if (Reader.bytesRemaining() < sizeof(HeaderInfo) + sizeof(GSIHashHeader)) | ||
return make_error<RawError>(raw_error_code::corrupt_file, | ||
"Publics Stream does not contain a header."); | ||
|
||
// Read PSGSIHDR and GSIHashHdr structs. | ||
Header.reset(new HeaderInfo()); | ||
if (Reader.readObject(Header.get())) | ||
return make_error<RawError>(raw_error_code::corrupt_file, | ||
"Publics Stream does not contain a header."); | ||
HashHdr.reset(new GSIHashHeader()); | ||
if (Reader.readObject(HashHdr.get())) | ||
return make_error<RawError>(raw_error_code::corrupt_file, | ||
"Publics Stream does not contain a header."); | ||
|
||
// An array of HRFile follows. Read them. | ||
if (HashHdr->HrSize % sizeof(HRFile)) | ||
return make_error<RawError>(raw_error_code::corrupt_file, | ||
"Invalid HR array size."); | ||
std::vector<HRFile> HRs(HashHdr->HrSize / sizeof(HRFile)); | ||
if (auto EC = Reader.readArray<HRFile>(HRs)) | ||
return make_error<RawError>(raw_error_code::corrupt_file, | ||
"Could not read an HR array"); | ||
|
||
// A bitmap of a fixed length follows. | ||
size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32); | ||
std::vector<uint8_t> Bitmap(BitmapSizeInBits / 8); | ||
if (auto EC = Reader.readArray<uint8_t>(Bitmap)) | ||
return make_error<RawError>(raw_error_code::corrupt_file, | ||
"Could not read a bitmap."); | ||
for (uint8_t B : Bitmap) | ||
NumBuckets += countPopulation(B); | ||
|
||
// Buckets follow. | ||
if (Reader.bytesRemaining() < NumBuckets * sizeof(uint32_t)) | ||
return make_error<RawError>(raw_error_code::corrupt_file, | ||
"Hash buckets corrupted."); | ||
|
||
return Error::success(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters