diff options
Diffstat (limited to 'gnu/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp')
-rw-r--r-- | gnu/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp | 76 |
1 files changed, 63 insertions, 13 deletions
diff --git a/gnu/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp b/gnu/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp index 0f55f58da38..b8a4eb79a48 100644 --- a/gnu/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp +++ b/gnu/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp @@ -7,24 +7,20 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/SparseBitVector.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/iterator_range.h" -#include "llvm/DebugInfo/MSF/StreamReader.h" #include "llvm/DebugInfo/PDB/Raw/NameMap.h" +#include "llvm/ADT/SparseBitVector.h" +#include "llvm/DebugInfo/CodeView/StreamReader.h" +#include "llvm/DebugInfo/CodeView/StreamWriter.h" #include "llvm/DebugInfo/PDB/Raw/RawError.h" -#include "llvm/Support/Error.h" -#include <algorithm> -#include <cstdint> using namespace llvm; -using namespace llvm::msf; +using namespace llvm::codeview; using namespace llvm::pdb; -NameMap::NameMap() = default; +NameMap::NameMap() {} + +Error NameMap::load(codeview::StreamReader &Stream) { -Error NameMap::load(StreamReader &Stream) { // This is some sort of weird string-set/hash table encoded in the stream. // It starts with the number of bytes in the table. uint32_t NumberOfBytes; @@ -149,9 +145,63 @@ Error NameMap::load(StreamReader &Stream) { return Error::success(); } +Error NameMap::commit(codeview::StreamWriter &Writer) { + // The first field is the number of bytes of string data. So add + // up the length of all strings plus a null terminator for each + // one. + uint32_t NumBytes = 0; + for (auto B = Mapping.begin(), E = Mapping.end(); B != E; ++B) { + NumBytes += B->getKeyLength() + 1; + } + + if (auto EC = Writer.writeInteger(NumBytes)) // Number of bytes of string data + return EC; + // Now all of the string data itself. + for (auto B = Mapping.begin(), E = Mapping.end(); B != E; ++B) { + if (auto EC = Writer.writeZeroString(B->getKey())) + return EC; + } + + if (auto EC = Writer.writeInteger(Mapping.size())) // Hash Size + return EC; + + if (auto EC = Writer.writeInteger(Mapping.size())) // Max Number of Strings + return EC; + + if (auto EC = Writer.writeInteger(Mapping.size())) // Num Present Words + return EC; + + // For each entry in the mapping, write a bit mask which represents a bucket + // to store it in. We don't use this, so the value we write isn't important + // to us, it just has to be there. + for (auto B = Mapping.begin(), E = Mapping.end(); B != E; ++B) { + if (auto EC = Writer.writeInteger(1U)) + return EC; + } + + if (auto EC = Writer.writeInteger(0U)) // Num Deleted Words + return EC; + + // Mappings of each word. + uint32_t OffsetSoFar = 0; + for (auto B = Mapping.begin(), E = Mapping.end(); B != E; ++B) { + // This is a list of key value pairs where the key is the offset into the + // strings buffer, and the value is a stream number. Write each pair. + if (auto EC = Writer.writeInteger(OffsetSoFar)) + return EC; + + if (auto EC = Writer.writeInteger(B->second)) + return EC; + + OffsetSoFar += B->getKeyLength() + 1; + } + + return Error::success(); +} + iterator_range<StringMapConstIterator<uint32_t>> NameMap::entries() const { - return make_range<StringMapConstIterator<uint32_t>>(Mapping.begin(), - Mapping.end()); + return llvm::make_range<StringMapConstIterator<uint32_t>>(Mapping.begin(), + Mapping.end()); } bool NameMap::tryGetValue(StringRef Name, uint32_t &Value) const { |