You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.161
Former-commit-id: 4db48158d3a35497b8f118ab21b5f08ac3d86d98
This commit is contained in:
parent
37fbf886a3
commit
e19d552987
152
external/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
vendored
Normal file
152
external/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
//===- NamedStreamMap.cpp - PDB Named Stream Map --------------------------===//
|
||||
//
|
||||
// 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/Native/NamedStreamMap.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/HashTable.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/RawError.h"
|
||||
#include "llvm/Support/BinaryStreamReader.h"
|
||||
#include "llvm/Support/BinaryStreamRef.h"
|
||||
#include "llvm/Support/BinaryStreamWriter.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <tuple>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::pdb;
|
||||
|
||||
// FIXME: This shouldn't be necessary, but if we insert the strings in any
|
||||
// other order, cvdump cannot read the generated name map. This suggests that
|
||||
// we may be using the wrong hash function. A closer inspection of the cvdump
|
||||
// source code may reveal something, but for now this at least makes us work,
|
||||
// even if only by accident.
|
||||
static constexpr const char *OrderedStreamNames[] = {"/LinkInfo", "/names",
|
||||
"/src/headerblock"};
|
||||
|
||||
NamedStreamMap::NamedStreamMap() = default;
|
||||
|
||||
Error NamedStreamMap::load(BinaryStreamReader &Stream) {
|
||||
Mapping.clear();
|
||||
FinalizedHashTable.clear();
|
||||
FinalizedInfo.reset();
|
||||
|
||||
uint32_t StringBufferSize;
|
||||
if (auto EC = Stream.readInteger(StringBufferSize))
|
||||
return joinErrors(std::move(EC),
|
||||
make_error<RawError>(raw_error_code::corrupt_file,
|
||||
"Expected string buffer size"));
|
||||
|
||||
BinaryStreamRef StringsBuffer;
|
||||
if (auto EC = Stream.readStreamRef(StringsBuffer, StringBufferSize))
|
||||
return EC;
|
||||
|
||||
HashTable OffsetIndexMap;
|
||||
if (auto EC = OffsetIndexMap.load(Stream))
|
||||
return EC;
|
||||
|
||||
uint32_t NameOffset;
|
||||
uint32_t NameIndex;
|
||||
for (const auto &Entry : OffsetIndexMap) {
|
||||
std::tie(NameOffset, NameIndex) = Entry;
|
||||
|
||||
// Compute the offset of the start of the string relative to the stream.
|
||||
BinaryStreamReader NameReader(StringsBuffer);
|
||||
NameReader.setOffset(NameOffset);
|
||||
// Pump out our c-string from the stream.
|
||||
StringRef Str;
|
||||
if (auto EC = NameReader.readCString(Str))
|
||||
return joinErrors(std::move(EC),
|
||||
make_error<RawError>(raw_error_code::corrupt_file,
|
||||
"Expected name map name"));
|
||||
|
||||
// Add this to a string-map from name to stream number.
|
||||
Mapping.insert({Str, NameIndex});
|
||||
}
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error NamedStreamMap::commit(BinaryStreamWriter &Writer) const {
|
||||
assert(FinalizedInfo.hasValue());
|
||||
|
||||
// The first field is the number of bytes of string data.
|
||||
if (auto EC = Writer.writeInteger(FinalizedInfo->StringDataBytes))
|
||||
return EC;
|
||||
|
||||
for (const auto &Name : OrderedStreamNames) {
|
||||
auto Item = Mapping.find(Name);
|
||||
if (Item == Mapping.end())
|
||||
continue;
|
||||
if (auto EC = Writer.writeCString(Item->getKey()))
|
||||
return EC;
|
||||
}
|
||||
|
||||
// And finally the Offset Index map.
|
||||
if (auto EC = FinalizedHashTable.commit(Writer))
|
||||
return EC;
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
uint32_t NamedStreamMap::finalize() {
|
||||
if (FinalizedInfo.hasValue())
|
||||
return FinalizedInfo->SerializedLength;
|
||||
|
||||
// Build the finalized hash table.
|
||||
FinalizedHashTable.clear();
|
||||
FinalizedInfo.emplace();
|
||||
|
||||
for (const auto &Name : OrderedStreamNames) {
|
||||
auto Item = Mapping.find(Name);
|
||||
if (Item == Mapping.end())
|
||||
continue;
|
||||
FinalizedHashTable.set(FinalizedInfo->StringDataBytes, Item->getValue());
|
||||
FinalizedInfo->StringDataBytes += Item->getKeyLength() + 1;
|
||||
}
|
||||
|
||||
// Number of bytes of string data.
|
||||
FinalizedInfo->SerializedLength += sizeof(support::ulittle32_t);
|
||||
// Followed by that many actual bytes of string data.
|
||||
FinalizedInfo->SerializedLength += FinalizedInfo->StringDataBytes;
|
||||
// Followed by the mapping from Offset to Index.
|
||||
FinalizedInfo->SerializedLength +=
|
||||
FinalizedHashTable.calculateSerializedLength();
|
||||
return FinalizedInfo->SerializedLength;
|
||||
}
|
||||
|
||||
iterator_range<StringMapConstIterator<uint32_t>>
|
||||
NamedStreamMap::entries() const {
|
||||
return make_range<StringMapConstIterator<uint32_t>>(Mapping.begin(),
|
||||
Mapping.end());
|
||||
}
|
||||
|
||||
uint32_t NamedStreamMap::size() const { return Mapping.size(); }
|
||||
|
||||
bool NamedStreamMap::get(StringRef Stream, uint32_t &StreamNo) const {
|
||||
auto Iter = Mapping.find(Stream);
|
||||
if (Iter == Mapping.end())
|
||||
return false;
|
||||
StreamNo = Iter->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
void NamedStreamMap::set(StringRef Stream, uint32_t StreamNo) {
|
||||
FinalizedInfo.reset();
|
||||
Mapping[Stream] = StreamNo;
|
||||
}
|
||||
|
||||
void NamedStreamMap::remove(StringRef Stream) {
|
||||
FinalizedInfo.reset();
|
||||
Mapping.erase(Stream);
|
||||
}
|
Reference in New Issue
Block a user