LLDB  mainline
DataEncoder.h
Go to the documentation of this file.
1 //===-- DataEncoder.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 LLDB_UTILITY_DATAENCODER_H
10 #define LLDB_UTILITY_DATAENCODER_H
11 
12 #if defined(__cplusplus)
13 
14 #include "lldb/lldb-defines.h"
15 #include "lldb/lldb-enumerations.h"
16 #include "lldb/lldb-forward.h"
17 #include "lldb/lldb-types.h"
18 
19 #include <cstddef>
20 #include <cstdint>
21 
22 namespace lldb_private {
23 
24 /// \class DataEncoder
25 ///
26 /// An binary data encoding class.
27 ///
28 /// DataEncoder is a class that can encode binary data (swapping if needed) to
29 /// a data buffer. The data buffer can be caller owned, or can be shared data
30 /// that can be shared between multiple DataEncoder or DataEncoder instances.
31 ///
32 /// \see DataBuffer
33 class DataEncoder {
34 public:
35  /// Default constructor.
36  ///
37  /// Initialize all members to a default empty state.
38  DataEncoder();
39 
40  /// Construct with a buffer that is owned by the caller.
41  ///
42  /// This constructor allows us to use data that is owned by the caller. The
43  /// data must stay around as long as this object is valid.
44  ///
45  /// \param[in] data
46  /// A pointer to caller owned data.
47  ///
48  /// \param[in] data_length
49  /// The length in bytes of \a data.
50  ///
51  /// \param[in] byte_order
52  /// A byte order of the data that we are extracting from.
53  ///
54  /// \param[in] addr_size
55  /// A new address byte size value.
56  DataEncoder(void *data, uint32_t data_length, lldb::ByteOrder byte_order,
57  uint8_t addr_size);
58 
59  /// Construct with shared data.
60  ///
61  /// Copies the data shared pointer which adds a reference to the contained
62  /// in \a data_sp. The shared data reference is reference counted to ensure
63  /// the data lives as long as anyone still has a valid shared pointer to the
64  /// data in \a data_sp.
65  ///
66  /// \param[in] data_sp
67  /// A shared pointer to data.
68  ///
69  /// \param[in] byte_order
70  /// A byte order of the data that we are extracting from.
71  ///
72  /// \param[in] addr_size
73  /// A new address byte size value.
74  DataEncoder(const lldb::DataBufferSP &data_sp, lldb::ByteOrder byte_order,
75  uint8_t addr_size);
76 
77  /// Destructor
78  ///
79  /// If this object contains a valid shared data reference, the reference
80  /// count on the data will be decremented, and if zero, the data will be
81  /// freed.
82  ~DataEncoder();
83 
84  /// Clears the object state.
85  ///
86  /// Clears the object contents back to a default invalid state, and release
87  /// any references to shared data that this object may contain.
88  void Clear();
89 
90  /// Encode an unsigned integer of size \a byte_size to \a offset.
91  ///
92  /// Encode a single integer value at \a offset and return the offset that
93  /// follows the newly encoded integer when the data is successfully encoded
94  /// into the existing data. There must be enough room in the data, else
95  /// UINT32_MAX will be returned to indicate that encoding failed.
96  ///
97  /// \param[in] offset
98  /// The offset within the contained data at which to put the
99  /// encoded integer.
100  ///
101  /// \param[in] byte_size
102  /// The size in byte of the integer to encode.
103  ///
104  /// \param[in] value
105  /// The integer value to write. The least significant bytes of
106  /// the integer value will be written if the size is less than
107  /// 8 bytes.
108  ///
109  /// \return
110  /// The next offset in the bytes of this data if the integer
111  /// was successfully encoded, UINT32_MAX if the encoding failed.
112  uint32_t PutUnsigned(uint32_t offset, uint32_t byte_size, uint64_t value);
113 
114  /// Encode an arbitrary number of bytes.
115  ///
116  /// \param[in] offset
117  /// The offset in bytes into the contained data at which to
118  /// start encoding.
119  ///
120  /// \param[in] src
121  /// The buffer that contains the bytes to encode.
122  ///
123  /// \param[in] src_len
124  /// The number of bytes to encode.
125  ///
126  /// \return
127  /// The next valid offset within data if the put operation
128  /// was successful, else UINT32_MAX to indicate the put failed.
129  uint32_t PutData(uint32_t offset, const void *src, uint32_t src_len);
130 
131  /// Encode an address in the existing buffer at \a offset bytes into the
132  /// buffer.
133  ///
134  /// Encode a single address (honoring the m_addr_size member) to the data
135  /// and return the next offset where subsequent data would go. pointed to by
136  /// \a offset_ptr. The size of the extracted address comes from the \a
137  /// m_addr_size member variable and should be set correctly prior to
138  /// extracting any address values.
139  ///
140  /// \param[in] offset
141  /// The offset where to encode the address.
142  ///
143  /// \param[in] addr
144  /// The address to encode.
145  ///
146  /// \return
147  /// The next valid offset within data if the put operation
148  /// was successful, else UINT32_MAX to indicate the put failed.
149  uint32_t PutAddress(uint32_t offset, lldb::addr_t addr);
150 
151  /// Put a C string to \a offset.
152  ///
153  /// Encodes a C string into the existing data including the terminating
154  ///
155  /// \param[in] offset
156  /// The offset where to encode the string.
157  ///
158  /// \param[in] cstr
159  /// The string to encode.
160  ///
161  /// \return
162  /// A pointer to the C string value in the data. If the offset
163  /// pointed to by \a offset_ptr is out of bounds, or if the
164  /// offset plus the length of the C string is out of bounds,
165  /// NULL will be returned.
166  uint32_t PutCString(uint32_t offset, const char *cstr);
167 
168 private:
169  uint32_t PutU8(uint32_t offset, uint8_t value);
170  uint32_t PutU16(uint32_t offset, uint16_t value);
171  uint32_t PutU32(uint32_t offset, uint32_t value);
172  uint32_t PutU64(uint32_t offset, uint64_t value);
173 
174  uint32_t BytesLeft(uint32_t offset) const {
175  const uint32_t size = GetByteSize();
176  if (size > offset)
177  return size - offset;
178  return 0;
179  }
180 
181  /// Test the availability of \a length bytes of data from \a offset.
182  ///
183  /// \return
184  /// \b true if \a offset is a valid offset and there are \a
185  /// length bytes available at that offset, \b false otherwise.
186  bool ValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const {
187  return length <= BytesLeft(offset);
188  }
189 
190  /// Adopt a subset of shared data in \a data_sp.
191  ///
192  /// Copies the data shared pointer which adds a reference to the contained
193  /// in \a data_sp. The shared data reference is reference counted to ensure
194  /// the data lives as long as anyone still has a valid shared pointer to the
195  /// data in \a data_sp. The byte order and address byte size settings remain
196  /// the same. If \a offset is not a valid offset in \a data_sp, then no
197  /// reference to the shared data will be added. If there are not \a length
198  /// bytes available in \a data starting at \a offset, the length will be
199  /// truncated to contains as many bytes as possible.
200  ///
201  /// \param[in] data_sp
202  /// A shared pointer to data.
203  ///
204  /// \param[in] offset
205  /// The offset into \a data_sp at which the subset starts.
206  ///
207  /// \param[in] length
208  /// The length in bytes of the subset of \a data_sp.
209  ///
210  /// \return
211  /// The number of bytes that this object now contains.
212  uint32_t SetData(const lldb::DataBufferSP &data_sp, uint32_t offset = 0,
213  uint32_t length = UINT32_MAX);
214 
215  /// Test the validity of \a offset.
216  ///
217  /// \return
218  /// \b true if \a offset is a valid offset into the data in this
219  /// object, \b false otherwise.
220  bool ValidOffset(uint32_t offset) const { return offset < GetByteSize(); }
221 
222  /// Get the number of bytes contained in this object.
223  ///
224  /// \return
225  /// The total number of bytes of data this object refers to.
226  size_t GetByteSize() const { return m_end - m_start; }
227 
228  /// A pointer to the first byte of data.
229  uint8_t *m_start = nullptr;
230 
231  /// A pointer to the byte that is past the end of the data.
232  uint8_t *m_end = nullptr;
233 
234  /// The byte order of the data we are extracting from.
235  lldb::ByteOrder m_byte_order;
236 
237  /// The address size to use when extracting pointers or
238  /// addresses
239  uint8_t m_addr_size;
240 
241  /// The shared pointer to data that can
242  /// be shared among multiple instances
243  mutable lldb::DataBufferSP m_data_sp;
244 
245  DataEncoder(const DataEncoder &) = delete;
246  const DataEncoder &operator=(const DataEncoder &) = delete;
247 };
248 
249 } // namespace lldb_private
250 
251 #endif // #if defined (__cplusplus)
252 #endif // LLDB_UTILITY_DATAENCODER_H
lldb-defines.h
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb-enumerations.h
lldb-types.h
uint32_t
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:31
uint16_t
lldb-forward.h
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb::ByteOrder
ByteOrder
Byte ordering definitions.
Definition: lldb-enumerations.h:138