LLVM  6.0.0svn
NamedStreamMap.cpp
Go to the documentation of this file.
1 //===- NamedStreamMap.cpp - PDB Named Stream Map --------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
11 #include "llvm/ADT/StringMap.h"
12 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Support/Endian.h"
20 #include "llvm/Support/Error.h"
21 #include <algorithm>
22 #include <cassert>
23 #include <cstdint>
24 #include <tuple>
25 
26 using namespace llvm;
27 using namespace llvm::pdb;
28 
29 // FIXME: This shouldn't be necessary, but if we insert the strings in any
30 // other order, cvdump cannot read the generated name map. This suggests that
31 // we may be using the wrong hash function. A closer inspection of the cvdump
32 // source code may reveal something, but for now this at least makes us work,
33 // even if only by accident.
34 static constexpr const char *OrderedStreamNames[] = {"/LinkInfo", "/names",
35  "/src/headerblock"};
36 
38 
40  Mapping.clear();
41  FinalizedHashTable.clear();
42  FinalizedInfo.reset();
43 
44  uint32_t StringBufferSize;
45  if (auto EC = Stream.readInteger(StringBufferSize))
46  return joinErrors(std::move(EC),
47  make_error<RawError>(raw_error_code::corrupt_file,
48  "Expected string buffer size"));
49 
50  BinaryStreamRef StringsBuffer;
51  if (auto EC = Stream.readStreamRef(StringsBuffer, StringBufferSize))
52  return EC;
53 
54  HashTable OffsetIndexMap;
55  if (auto EC = OffsetIndexMap.load(Stream))
56  return EC;
57 
58  uint32_t NameOffset;
59  uint32_t NameIndex;
60  for (const auto &Entry : OffsetIndexMap) {
61  std::tie(NameOffset, NameIndex) = Entry;
62 
63  // Compute the offset of the start of the string relative to the stream.
64  BinaryStreamReader NameReader(StringsBuffer);
65  NameReader.setOffset(NameOffset);
66  // Pump out our c-string from the stream.
67  StringRef Str;
68  if (auto EC = NameReader.readCString(Str))
69  return joinErrors(std::move(EC),
70  make_error<RawError>(raw_error_code::corrupt_file,
71  "Expected name map name"));
72 
73  // Add this to a string-map from name to stream number.
74  Mapping.insert({Str, NameIndex});
75  }
76 
77  return Error::success();
78 }
79 
81  assert(FinalizedInfo.hasValue());
82 
83  // The first field is the number of bytes of string data.
84  if (auto EC = Writer.writeInteger(FinalizedInfo->StringDataBytes))
85  return EC;
86 
87  for (const auto &Name : OrderedStreamNames) {
88  auto Item = Mapping.find(Name);
89  if (Item == Mapping.end())
90  continue;
91  if (auto EC = Writer.writeCString(Item->getKey()))
92  return EC;
93  }
94 
95  // And finally the Offset Index map.
96  if (auto EC = FinalizedHashTable.commit(Writer))
97  return EC;
98 
99  return Error::success();
100 }
101 
103  if (FinalizedInfo.hasValue())
104  return FinalizedInfo->SerializedLength;
105 
106  // Build the finalized hash table.
107  FinalizedHashTable.clear();
108  FinalizedInfo.emplace();
109 
110  for (const auto &Name : OrderedStreamNames) {
111  auto Item = Mapping.find(Name);
112  if (Item == Mapping.end())
113  continue;
114  FinalizedHashTable.set(FinalizedInfo->StringDataBytes, Item->getValue());
115  FinalizedInfo->StringDataBytes += Item->getKeyLength() + 1;
116  }
117 
118  // Number of bytes of string data.
119  FinalizedInfo->SerializedLength += sizeof(support::ulittle32_t);
120  // Followed by that many actual bytes of string data.
121  FinalizedInfo->SerializedLength += FinalizedInfo->StringDataBytes;
122  // Followed by the mapping from Offset to Index.
123  FinalizedInfo->SerializedLength +=
124  FinalizedHashTable.calculateSerializedLength();
125  return FinalizedInfo->SerializedLength;
126 }
127 
130  return make_range<StringMapConstIterator<uint32_t>>(Mapping.begin(),
131  Mapping.end());
132 }
133 
134 uint32_t NamedStreamMap::size() const { return Mapping.size(); }
135 
136 bool NamedStreamMap::get(StringRef Stream, uint32_t &StreamNo) const {
137  auto Iter = Mapping.find(Stream);
138  if (Iter == Mapping.end())
139  return false;
140  StreamNo = Iter->second;
141  return true;
142 }
143 
144 void NamedStreamMap::set(StringRef Stream, uint32_t StreamNo) {
145  FinalizedInfo.reset();
146  Mapping[Stream] = StreamNo;
147 }
148 
150  FinalizedInfo.reset();
151  Mapping.erase(Stream);
152 }
iterator_range< StringMapConstIterator< uint32_t > > entries() const
void remove(StringRef Stream)
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
Error readInteger(T &Dest)
Read an integer of the specified endianness into Dest and update the stream&#39;s offset.
Error commit(BinaryStreamWriter &Writer) const
Definition: HashTable.cpp:84
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
void emplace(ArgTypes &&... Args)
Create a new object by constructing it in place with the given arguments.
Definition: Optional.h:79
iterator find(StringRef Key)
Definition: StringMap.h:337
void set(StringRef Stream, uint32_t StreamNo)
static constexpr const char * OrderedStreamNames[]
unsigned size() const
Definition: StringMap.h:112
Error readCString(StringRef &Dest)
Read a null terminated string from Dest.
void set(uint32_t K, uint32_t V)
Definition: HashTable.cpp:151
const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:127
Error load(BinaryStreamReader &Stream)
detail::packed_endian_specific_integral< uint32_t, little, unaligned > ulittle32_t
Definition: Endian.h:271
void erase(iterator I)
Definition: StringMap.h:440
Provides write only access to a subclass of WritableBinaryStream.
Error writeInteger(T Value)
Write the the integer Value to the underlying stream in the specified endianness. ...
Error load(BinaryStreamReader &Stream)
Definition: HashTable.cpp:29
Error writeCString(StringRef Str)
Write the the string Str to the underlying stream followed by a null terminator.
Error commit(BinaryStreamWriter &Writer) const
void setOffset(uint32_t Off)
static ErrorSuccess success()
Create a success value.
Definition: Error.h:313
BinaryStreamRef is to BinaryStream what ArrayRef is to an Array.
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition: StringMap.h:370
A range adaptor for a pair of iterators.
bool hasValue() const
Definition: Optional.h:137
iterator begin()
Definition: StringMap.h:319
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition: Error.h:408
Error readStreamRef(BinaryStreamRef &Ref)
Read the entire remainder of the underlying stream into Ref.
bool get(StringRef Stream, uint32_t &StreamNo) const
void reset()
Definition: Optional.h:112
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
uint32_t calculateSerializedLength() const
Definition: HashTable.cpp:64
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
Provides read only access to a subclass of BinaryStream.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
iterator end()
Definition: StringMap.h:322