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