LLVM  9.0.0svn
CodeViewRecordIO.h
Go to the documentation of this file.
1 //===- CodeViewRecordIO.h ---------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H
10 #define LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H
11 
12 #include "llvm/ADT/APSInt.h"
13 #include "llvm/ADT/None.h"
14 #include "llvm/ADT/Optional.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Support/Error.h"
22 #include <cassert>
23 #include <cstdint>
24 #include <type_traits>
25 
26 namespace llvm {
27 namespace codeview {
28 
30  uint32_t getCurrentOffset() const {
31  return (isWriting()) ? Writer->getOffset() : Reader->getOffset();
32  }
33 
34 public:
35  explicit CodeViewRecordIO(BinaryStreamReader &Reader) : Reader(&Reader) {}
36  explicit CodeViewRecordIO(BinaryStreamWriter &Writer) : Writer(&Writer) {}
37 
39  Error endRecord();
40 
41  Error mapInteger(TypeIndex &TypeInd);
42 
43  bool isReading() const { return Reader != nullptr; }
44  bool isWriting() const { return !isReading(); }
45 
46  uint32_t maxFieldLength() const;
47 
48  template <typename T> Error mapObject(T &Value) {
49  if (isWriting())
50  return Writer->writeObject(Value);
51 
52  const T *ValuePtr;
53  if (auto EC = Reader->readObject(ValuePtr))
54  return EC;
55  Value = *ValuePtr;
56  return Error::success();
57  }
58 
59  template <typename T> Error mapInteger(T &Value) {
60  if (isWriting())
61  return Writer->writeInteger(Value);
62 
63  return Reader->readInteger(Value);
64  }
65 
66  template <typename T> Error mapEnum(T &Value) {
67  if (sizeof(Value) > maxFieldLength())
68  return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
69 
70  using U = typename std::underlying_type<T>::type;
71  U X;
72  if (isWriting())
73  X = static_cast<U>(Value);
74 
75  if (auto EC = mapInteger(X))
76  return EC;
77  if (isReading())
78  Value = static_cast<T>(X);
79  return Error::success();
80  }
81 
82  Error mapEncodedInteger(int64_t &Value);
83  Error mapEncodedInteger(uint64_t &Value);
85  Error mapStringZ(StringRef &Value);
86  Error mapGuid(GUID &Guid);
87 
88  Error mapStringZVectorZ(std::vector<StringRef> &Value);
89 
90  template <typename SizeType, typename T, typename ElementMapper>
91  Error mapVectorN(T &Items, const ElementMapper &Mapper) {
92  SizeType Size;
93  if (isWriting()) {
94  Size = static_cast<SizeType>(Items.size());
95  if (auto EC = Writer->writeInteger(Size))
96  return EC;
97 
98  for (auto &X : Items) {
99  if (auto EC = Mapper(*this, X))
100  return EC;
101  }
102  } else {
103  if (auto EC = Reader->readInteger(Size))
104  return EC;
105  for (SizeType I = 0; I < Size; ++I) {
106  typename T::value_type Item;
107  if (auto EC = Mapper(*this, Item))
108  return EC;
109  Items.push_back(Item);
110  }
111  }
112 
113  return Error::success();
114  }
115 
116  template <typename T, typename ElementMapper>
117  Error mapVectorTail(T &Items, const ElementMapper &Mapper) {
118  if (isWriting()) {
119  for (auto &Item : Items) {
120  if (auto EC = Mapper(*this, Item))
121  return EC;
122  }
123  } else {
124  typename T::value_type Field;
125  // Stop when we run out of bytes or we hit record padding bytes.
126  while (!Reader->empty() && Reader->peek() < 0xf0 /* LF_PAD0 */) {
127  if (auto EC = Mapper(*this, Field))
128  return EC;
129  Items.push_back(Field);
130  }
131  }
132  return Error::success();
133  }
134 
136  Error mapByteVectorTail(std::vector<uint8_t> &Bytes);
137 
139  Error skipPadding();
140 
141 private:
142  Error writeEncodedSignedInteger(const int64_t &Value);
143  Error writeEncodedUnsignedInteger(const uint64_t &Value);
144 
145  struct RecordLimit {
146  uint32_t BeginOffset;
147  Optional<uint32_t> MaxLength;
148 
149  Optional<uint32_t> bytesRemaining(uint32_t CurrentOffset) const {
150  if (!MaxLength.hasValue())
151  return None;
152  assert(CurrentOffset >= BeginOffset);
153 
154  uint32_t BytesUsed = CurrentOffset - BeginOffset;
155  if (BytesUsed >= *MaxLength)
156  return 0;
157  return *MaxLength - BytesUsed;
158  }
159  };
160 
162 
163  BinaryStreamReader *Reader = nullptr;
164  BinaryStreamWriter *Writer = nullptr;
165 };
166 
167 } // end namespace codeview
168 } // end namespace llvm
169 
170 #endif // LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H
Error writeObject(const T &Obj)
Writes the object Obj to the underlying stream, as if by using memcpy.
Error mapByteVectorTail(ArrayRef< uint8_t > &Bytes)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
Error mapVectorN(T &Items, const ElementMapper &Mapper)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Error readInteger(T &Dest)
Read an integer of the specified endianness into Dest and update the stream&#39;s offset.
Error mapInteger(TypeIndex &TypeInd)
Error mapStringZVectorZ(std::vector< StringRef > &Value)
Error readObject(const T *&Dest)
Get a pointer to an object of type T from the underlying stream, as if by memcpy, and store the resul...
uint8_t peek() const
Examine the next byte of the underlying stream without advancing the stream&#39;s offset.
CodeViewRecordIO(BinaryStreamWriter &Writer)
Error beginRecord(Optional< uint32_t > MaxLength)
This represents the &#39;GUID&#39; type from windows.h.
Definition: GUID.h:21
A 32-bit type reference.
Definition: TypeIndex.h:95
Error padToAlignment(uint32_t Align)
Provides write only access to a subclass of WritableBinaryStream.
CodeViewRecordIO(BinaryStreamReader &Reader)
Error writeInteger(T Value)
Write the integer Value to the underlying stream in the specified endianness.
static ErrorSuccess success()
Create a success value.
Definition: Error.h:326
Error mapEncodedInteger(int64_t &Value)
bool hasValue() const
Definition: Optional.h:259
#define I(x, y, z)
Definition: MD5.cpp:58
uint32_t Size
Definition: Profile.cpp:46
Error mapStringZ(StringRef &Value)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:72
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
Error mapVectorTail(T &Items, const ElementMapper &Mapper)
Provides read only access to a subclass of BinaryStream.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48