40 static CVSymbol Tombstone(static_cast<SymbolKind>(-1),
59 uint32_t calculateSerializedLength()
const;
60 uint32_t calculateRecordByteSize()
const;
62 void finalizeBuckets(
uint32_t RecordZeroOffset);
66 addSymbol(SymbolSerializer::writeOneSymbol(Copy, Msf.
getAllocator(),
67 CodeViewContainer::Pdb));
70 if (Symbol.
kind() == S_UDT) {
71 auto Iter = UdtHashes.
insert(Symbol);
76 Records.push_back(Symbol);
80 uint32_t GSIHashStreamBuilder::calculateSerializedLength()
const {
83 Size += HashBitmap.size() *
sizeof(
uint32_t);
84 Size += HashBuckets.size() *
sizeof(
uint32_t);
88 uint32_t GSIHashStreamBuilder::calculateRecordByteSize()
const {
90 for (
const auto &Sym : Records)
98 Header.
VerHdr = GSIHashHeader::HdrVersion;
100 Header.
NumBuckets = HashBitmap.size() * 4 + HashBuckets.size() * 4;
121 size_t RS = S2.
size();
134 void GSIHashStreamBuilder::finalizeBuckets(
uint32_t RecordZeroOffset) {
135 std::array<std::vector<std::pair<StringRef, PSHashRecord>>,
IPHR_HASH + 1>
137 uint32_t SymOffset = RecordZeroOffset;
138 for (
const CVSymbol &Sym : Records) {
141 HR.
Off = SymOffset + 1;
147 TmpBuckets[BucketIdx].push_back(std::make_pair(Name, HR));
148 SymOffset += Sym.length();
153 HashRecords.reserve(Records.size());
156 for (
size_t BucketIdx = 0; BucketIdx <
IPHR_HASH + 1; ++BucketIdx) {
157 auto &Bucket = TmpBuckets[BucketIdx];
160 HashBitmap[BucketIdx / 32] |= 1U << (BucketIdx % 32);
165 const int SizeOfHROffsetCalc = 12;
167 ulittle32_t(HashRecords.size() * SizeOfHROffsetCalc);
168 HashBuckets.push_back(ChainStartOff);
176 llvm::sort(Bucket, [](
const std::pair<StringRef, PSHashRecord> &
Left,
177 const std::pair<StringRef, PSHashRecord> &
Right) {
181 for (
const auto &Entry : Bucket)
182 HashRecords.push_back(Entry.second);
192 uint32_t GSIStreamBuilder::calculatePublicsHashStreamSize()
const {
195 Size += PSH->calculateSerializedLength();
196 Size += PSH->Records.size() *
sizeof(
uint32_t);
202 uint32_t GSIStreamBuilder::calculateGlobalsHashStreamSize()
const {
203 return GSH->calculateSerializedLength();
209 uint32_t GSHZero = PSH->calculateRecordByteSize();
211 PSH->finalizeBuckets(PSHZero);
212 GSH->finalizeBuckets(GSHZero);
217 GSH->StreamIndex = *Idx;
218 Idx = Msf.
addStream(calculatePublicsHashStreamSize());
221 PSH->StreamIndex = *Idx;
224 GSH->calculateRecordByteSize() + PSH->calculateRecordByteSize();
229 RecordStreamIdx = *Idx;
234 const std::pair<const CVSymbol *, const PublicSym32 *> &
LS,
235 const std::pair<const CVSymbol *, const PublicSym32 *> &RS) {
236 if (LS.second->Segment != RS.second->Segment)
237 return LS.second->Segment < RS.second->Segment;
238 if (LS.second->Offset != RS.second->Offset)
239 return LS.second->Offset < RS.second->Offset;
241 return LS.second->Name < RS.second->Name;
250 std::vector<PublicSym32> DeserializedPublics;
251 std::vector<std::pair<const CVSymbol *, const PublicSym32 *>> PublicsByAddr;
252 std::vector<uint32_t> SymOffsets;
253 DeserializedPublics.reserve(Records.
size());
254 PublicsByAddr.reserve(Records.
size());
255 SymOffsets.reserve(Records.
size());
258 for (
const CVSymbol &Sym : Records) {
259 assert(Sym.kind() == SymbolKind::S_PUB32);
260 DeserializedPublics.push_back(
261 cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym)));
262 PublicsByAddr.emplace_back(&Sym, &DeserializedPublics.back());
263 SymOffsets.push_back(SymOffset);
264 SymOffset += Sym.length();
266 std::stable_sort(PublicsByAddr.begin(), PublicsByAddr.end(),
270 std::vector<ulittle32_t> AddrMap;
271 AddrMap.reserve(Records.size());
272 for (
auto &Sym : PublicsByAddr) {
273 ptrdiff_t Idx = std::distance(Records.data(), Sym.first);
274 assert(Idx >= 0 &&
size_t(Idx) < Records.size());
281 return PSH->StreamIndex;
285 return GSH->StreamIndex;
289 PSH->addSymbol(Pub, Msf);
293 GSH->addSymbol(Sym, Msf);
297 GSH->addSymbol(Sym, Msf);
301 GSH->addSymbol(Sym, Msf);
316 Error GSIStreamBuilder::commitSymbolRecordStream(
331 Error GSIStreamBuilder::commitPublicsHashStream(
337 Header.
SymHash = PSH->calculateSerializedLength();
338 Header.
AddrMap = PSH->Records.size() * 4;
348 if (
auto EC = PSH->commit(Writer))
358 Error GSIStreamBuilder::commitGlobalsHashStream(
361 return GSH->commit(Writer);
366 auto GS = WritableMappedBlockStream::createIndexedStream(
368 auto PS = WritableMappedBlockStream::createIndexedStream(
370 auto PRS = WritableMappedBlockStream::createIndexedStream(
373 if (
auto EC = commitSymbolRecordStream(*PRS))
375 if (
auto EC = commitGlobalsHashStream(*GS))
377 if (
auto EC = commitPublicsHashStream(*PS))
Error writeObject(const T &Obj)
Writes the object Obj to the underlying stream, as if by using memcpy.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
std::vector< CVSymbol > Records
This class represents lattice values for constants.
static bool isAsciiString(StringRef S)
Implements a dense probed hash-table based set.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
uint64_t xxHash64(llvm::StringRef Data)
static std::vector< ulittle32_t > computeAddrMap(ArrayRef< CVSymbol > Records)
Compute the address map.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&... args)
Constructs a new T() with the given args and returns a unique_ptr<T> which owns the object...
Error takeError()
Take ownership of the stored error.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
std::vector< PSHashRecord > HashRecords
uint32_t getPublicsStreamIndex() const
#define LLVM_UNLIKELY(EXPR)
amdgpu Simplify well known AMD library false Value Value const Twine & Name
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
static StringRef getSymbolName(SymbolKind SymKind)
support::ulittle32_t CRef
support::ulittle32_t Word
Tagged union holding either a T or a Error.
uint32_t getRecordStreamIdx() const
static Error writeRecords(BinaryStreamWriter &Writer, ArrayRef< CVSymbol > Records)
void addSymbol(const CVSymbol &Symbol)
void addSymbol(const T &Symbol, MSFBuilder &Msf)
static bool comparePubSymByAddrAndName(const std::pair< const CVSymbol *, const PublicSym32 *> &LS, const std::pair< const CVSymbol *, const PublicSym32 *> &RS)
uint32_t getGlobalsStreamIndex() const
static CVSymbol getTombstoneKey()
Error writeArray(ArrayRef< T > Array)
Writes an array of objects of type T to the underlying stream, as if by using memcpy.
static bool gsiRecordLess(StringRef S1, StringRef S2)
llvm::DenseSet< CVSymbol, UdtDenseMapInfo > UdtHashes
uint32_t hashStringV1(StringRef Str)
detail::packed_endian_specific_integral< uint32_t, little, unaligned > ulittle32_t
size_t size() const
size - Get the array size.
static unsigned getHashValue(const CVSymbol &Val)
std::pair< iterator, bool > insert(const ValueT &V)
Error writeStreamRef(BinaryStreamRef Ref)
Efficiently reads all data from Ref, and writes it to this stream.
Error finalizeMsfLayout()
Provides write only access to a subclass of WritableBinaryStream.
static CVSymbol getEmptyKey()
void sort(IteratorTy Start, IteratorTy End)
LLVM_NODISCARD int compare_lower(StringRef RHS) const
compare_lower - Compare two strings, ignoring case.
static ErrorSuccess success()
Create a success value.
std::vector< support::ulittle32_t > HashBuckets
BinaryStreamRef is to BinaryStream what ArrayRef is to an Array.
Expected< uint32_t > addStream(uint32_t Size, ArrayRef< uint32_t > Blocks)
Add a stream to the MSF file with the given size, occupying the given list of blocks.
void addGlobalSymbol(const codeview::ProcRefSym &Sym)
void addPublicSymbol(const codeview::PublicSym32 &Pub)
ArrayRef< uint8_t > RecordData
Merge contiguous icmps into a memcmp
Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef Buffer)
static bool isEqual(const CVSymbol &LHS, const CVSymbol &RHS)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
BinaryItemStream represents a sequence of objects stored in some kind of external container but for w...
Lightweight error class with error context and mandatory checking.
void setItems(ArrayRef< T > ItemArray)
StringRef - Represent a constant reference to a string, i.e.
BumpPtrAllocator & getAllocator()