LLVM  8.0.1
RecordSerialization.cpp
Go to the documentation of this file.
1 //===-- RecordSerialization.cpp -------------------------------------------===//
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 //
10 // Utilities for serializing and deserializing CodeView records.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/APSInt.h"
21 
22 using namespace llvm;
23 using namespace llvm::codeview;
24 using namespace llvm::support;
25 
26 /// Reinterpret a byte array as an array of characters. Does not interpret as
27 /// a C string, as StringRef has several helpers (split) that make that easy.
29  return StringRef(reinterpret_cast<const char *>(LeafData.data()),
30  LeafData.size());
31 }
32 
34  return getBytesAsCharacters(LeafData).split('\0').first;
35 }
36 
38  // Used to avoid overload ambiguity on APInt construtor.
39  bool FalseVal = false;
40  uint16_t Short;
41  if (auto EC = Reader.readInteger(Short))
42  return EC;
43 
44  if (Short < LF_NUMERIC) {
45  Num = APSInt(APInt(/*numBits=*/16, Short, /*isSigned=*/false),
46  /*isUnsigned=*/true);
47  return Error::success();
48  }
49 
50  switch (Short) {
51  case LF_CHAR: {
52  int8_t N;
53  if (auto EC = Reader.readInteger(N))
54  return EC;
55  Num = APSInt(APInt(8, N, true), false);
56  return Error::success();
57  }
58  case LF_SHORT: {
59  int16_t N;
60  if (auto EC = Reader.readInteger(N))
61  return EC;
62  Num = APSInt(APInt(16, N, true), false);
63  return Error::success();
64  }
65  case LF_USHORT: {
66  uint16_t N;
67  if (auto EC = Reader.readInteger(N))
68  return EC;
69  Num = APSInt(APInt(16, N, false), true);
70  return Error::success();
71  }
72  case LF_LONG: {
73  int32_t N;
74  if (auto EC = Reader.readInteger(N))
75  return EC;
76  Num = APSInt(APInt(32, N, true), false);
77  return Error::success();
78  }
79  case LF_ULONG: {
80  uint32_t N;
81  if (auto EC = Reader.readInteger(N))
82  return EC;
83  Num = APSInt(APInt(32, N, FalseVal), true);
84  return Error::success();
85  }
86  case LF_QUADWORD: {
87  int64_t N;
88  if (auto EC = Reader.readInteger(N))
89  return EC;
90  Num = APSInt(APInt(64, N, true), false);
91  return Error::success();
92  }
93  case LF_UQUADWORD: {
94  uint64_t N;
95  if (auto EC = Reader.readInteger(N))
96  return EC;
97  Num = APSInt(APInt(64, N, false), true);
98  return Error::success();
99  }
100  }
101  return make_error<CodeViewError>(cv_error_code::corrupt_record,
102  "Buffer contains invalid APSInt type");
103 }
104 
106  ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
108  BinaryStreamReader SR(S);
109  auto EC = consume(SR, Num);
110  Data = Data.take_back(SR.bytesRemaining());
111  return EC;
112 }
113 
114 /// Decode a numeric leaf value that is known to be a uint64_t.
116  uint64_t &Num) {
117  APSInt N;
118  if (auto EC = consume(Reader, N))
119  return EC;
120  if (N.isSigned() || !N.isIntN(64))
121  return make_error<CodeViewError>(cv_error_code::corrupt_record,
122  "Data is not a numeric value!");
123  Num = N.getLimitedValue();
124  return Error::success();
125 }
126 
128  return Reader.readInteger(Item);
129 }
130 
132  ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
134  BinaryStreamReader SR(S);
135  auto EC = consume(SR, Item);
136  Data = Data.take_back(SR.bytesRemaining());
137  return EC;
138 }
139 
141  return Reader.readInteger(Item);
142 }
143 
145  if (Reader.empty())
146  return make_error<CodeViewError>(cv_error_code::corrupt_record,
147  "Null terminated string buffer is empty!");
148 
149  return Reader.readCString(Item);
150 }
151 
153  uint32_t Offset) {
154  return readCVRecordFromStream<SymbolKind>(Stream, Offset);
155 }
Error consume_numeric(BinaryStreamReader &Reader, uint64_t &Value)
Decodes a numeric leaf value that is known to be a particular type.
An implementation of BinaryStream which holds its entire data set in a single contiguous buffer...
This class represents lattice values for constants.
Definition: AllocatorList.h:24
const unsigned char * bytes_end() const
Definition: StringRef.h:113
Error readInteger(T &Dest)
Read an integer of the specified endianness into Dest and update the stream&#39;s offset.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef take_back(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with only the last N elements remaining.
Definition: StringRef.h:619
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
Error readCString(StringRef &Dest)
Read a null terminated string from Dest.
This file implements a class to represent arbitrary precision integral constant values and operations...
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
bool isSigned() const
Definition: APSInt.h:59
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
Definition: APInt.h:450
const T * data() const
Definition: ArrayRef.h:146
Expected< CVSymbol > readSymbolFromStream(BinaryStreamRef Stream, uint32_t Offset)
static ErrorSuccess success()
Create a success value.
Definition: Error.h:327
BinaryStreamRef is to BinaryStream what ArrayRef is to an Array.
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:727
Class for arbitrary precision integers.
Definition: APInt.h:70
StringRef getBytesAsCharacters(ArrayRef< uint8_t > LeafData)
Reinterpret a byte array as an array of characters.
StringRef getBytesAsCString(ArrayRef< uint8_t > LeafData)
const unsigned char * bytes_begin() const
Definition: StringRef.h:110
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value...
Definition: APInt.h:482
#define N
uint32_t bytesRemaining() const
Error consume(BinaryStreamReader &Reader)
Lightweight error class with error context and mandatory checking.
Definition: Error.h:158
Provides read only access to a subclass of BinaryStream.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49