annotate lib/DebugInfo/PDB/Native/NamedStreamMap.cpp @ 121:803732b1fca8

LLVM 5.0
author kono
date Fri, 27 Oct 2017 17:07:41 +0900
parents
children c2174574ed3a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
1 //===- NamedStreamMap.cpp - PDB Named Stream Map --------------------------===//
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
2 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
3 // The LLVM Compiler Infrastructure
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
4 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
5 // This file is distributed under the University of Illinois Open Source
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
6 // License. See LICENSE.TXT for details.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
7 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
8 //===----------------------------------------------------------------------===//
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
9
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
10 #include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
11 #include "llvm/ADT/StringMap.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
12 #include "llvm/ADT/StringRef.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
13 #include "llvm/ADT/iterator_range.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
14 #include "llvm/DebugInfo/PDB/Native/HashTable.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
15 #include "llvm/DebugInfo/PDB/Native/RawError.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
16 #include "llvm/Support/BinaryStreamReader.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
17 #include "llvm/Support/BinaryStreamRef.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
18 #include "llvm/Support/BinaryStreamWriter.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
19 #include "llvm/Support/Endian.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
20 #include "llvm/Support/Error.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
21 #include <algorithm>
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
22 #include <cassert>
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
23 #include <cstdint>
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
24 #include <tuple>
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
25
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
26 using namespace llvm;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
27 using namespace llvm::pdb;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
28
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
29 // FIXME: This shouldn't be necessary, but if we insert the strings in any
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
30 // other order, cvdump cannot read the generated name map. This suggests that
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
31 // we may be using the wrong hash function. A closer inspection of the cvdump
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
32 // source code may reveal something, but for now this at least makes us work,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
33 // even if only by accident.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
34 static constexpr const char *OrderedStreamNames[] = {"/LinkInfo", "/names",
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
35 "/src/headerblock"};
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
36
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
37 NamedStreamMap::NamedStreamMap() = default;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
38
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
39 Error NamedStreamMap::load(BinaryStreamReader &Stream) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
40 Mapping.clear();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
41 FinalizedHashTable.clear();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
42 FinalizedInfo.reset();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
43
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
44 uint32_t StringBufferSize;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
45 if (auto EC = Stream.readInteger(StringBufferSize))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
46 return joinErrors(std::move(EC),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
47 make_error<RawError>(raw_error_code::corrupt_file,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
48 "Expected string buffer size"));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
49
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
50 BinaryStreamRef StringsBuffer;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
51 if (auto EC = Stream.readStreamRef(StringsBuffer, StringBufferSize))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
52 return EC;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
53
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
54 HashTable OffsetIndexMap;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
55 if (auto EC = OffsetIndexMap.load(Stream))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
56 return EC;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
57
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
58 uint32_t NameOffset;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
59 uint32_t NameIndex;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
60 for (const auto &Entry : OffsetIndexMap) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
61 std::tie(NameOffset, NameIndex) = Entry;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
62
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
63 // Compute the offset of the start of the string relative to the stream.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
64 BinaryStreamReader NameReader(StringsBuffer);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
65 NameReader.setOffset(NameOffset);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
66 // Pump out our c-string from the stream.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
67 StringRef Str;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
68 if (auto EC = NameReader.readCString(Str))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
69 return joinErrors(std::move(EC),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
70 make_error<RawError>(raw_error_code::corrupt_file,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
71 "Expected name map name"));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
72
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
73 // Add this to a string-map from name to stream number.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
74 Mapping.insert({Str, NameIndex});
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
75 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
76
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
77 return Error::success();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
78 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
79
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
80 Error NamedStreamMap::commit(BinaryStreamWriter &Writer) const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
81 assert(FinalizedInfo.hasValue());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
82
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
83 // The first field is the number of bytes of string data.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
84 if (auto EC = Writer.writeInteger(FinalizedInfo->StringDataBytes))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
85 return EC;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
86
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
87 for (const auto &Name : OrderedStreamNames) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
88 auto Item = Mapping.find(Name);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
89 if (Item == Mapping.end())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
90 continue;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
91 if (auto EC = Writer.writeCString(Item->getKey()))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
92 return EC;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
93 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
94
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
95 // And finally the Offset Index map.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
96 if (auto EC = FinalizedHashTable.commit(Writer))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
97 return EC;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
98
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
99 return Error::success();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
100 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
101
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
102 uint32_t NamedStreamMap::finalize() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
103 if (FinalizedInfo.hasValue())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
104 return FinalizedInfo->SerializedLength;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
105
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
106 // Build the finalized hash table.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
107 FinalizedHashTable.clear();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
108 FinalizedInfo.emplace();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
109
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
110 for (const auto &Name : OrderedStreamNames) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
111 auto Item = Mapping.find(Name);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
112 if (Item == Mapping.end())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
113 continue;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
114 FinalizedHashTable.set(FinalizedInfo->StringDataBytes, Item->getValue());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
115 FinalizedInfo->StringDataBytes += Item->getKeyLength() + 1;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
116 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
117
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
118 // Number of bytes of string data.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
119 FinalizedInfo->SerializedLength += sizeof(support::ulittle32_t);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
120 // Followed by that many actual bytes of string data.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
121 FinalizedInfo->SerializedLength += FinalizedInfo->StringDataBytes;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
122 // Followed by the mapping from Offset to Index.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
123 FinalizedInfo->SerializedLength +=
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
124 FinalizedHashTable.calculateSerializedLength();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
125 return FinalizedInfo->SerializedLength;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
126 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
127
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
128 iterator_range<StringMapConstIterator<uint32_t>>
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
129 NamedStreamMap::entries() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
130 return make_range<StringMapConstIterator<uint32_t>>(Mapping.begin(),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
131 Mapping.end());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
132 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
133
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
134 uint32_t NamedStreamMap::size() const { return Mapping.size(); }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
135
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
136 bool NamedStreamMap::get(StringRef Stream, uint32_t &StreamNo) const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
137 auto Iter = Mapping.find(Stream);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
138 if (Iter == Mapping.end())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
139 return false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
140 StreamNo = Iter->second;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
141 return true;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
142 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
143
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
144 void NamedStreamMap::set(StringRef Stream, uint32_t StreamNo) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
145 FinalizedInfo.reset();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
146 Mapping[Stream] = StreamNo;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
147 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
148
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
149 void NamedStreamMap::remove(StringRef Stream) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
150 FinalizedInfo.reset();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
151 Mapping.erase(Stream);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
152 }