blob: 5dc518beeaf4e93cb92cfd873f2941c0c5916fe5 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- DataExtractor.cpp ---------------------------------------*- C++ -*-===//
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
Eugene Zelenkodf370552016-03-02 02:18:18 +000010// C Includes
11// C++ Includes
Eugene Zelenkodf370552016-03-02 02:18:18 +000012#include <cassert>
Eugene Zelenkodf370552016-03-02 02:18:18 +000013#include <cmath>
Kate Stoneb9c1b512016-09-06 20:57:50 +000014#include <cstddef>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015#include <string>
16
Zachary Turner666cc0b2017-03-04 01:30:05 +000017// Project includes
18#include "lldb/Utility/DataBuffer.h"
19#include "lldb/Utility/DataBufferHeap.h"
20#include "lldb/Utility/DataExtractor.h"
21#include "lldb/Utility/Endian.h"
22#include "lldb/Utility/Log.h"
23#include "lldb/Utility/Stream.h"
24#include "lldb/Utility/StreamString.h"
25#include "lldb/Utility/UUID.h"
26
Eugene Zelenkodf370552016-03-02 02:18:18 +000027// Other libraries and framework includes
Greg Claytonf6a5fc22011-08-15 07:23:47 +000028#include "llvm/ADT/ArrayRef.h"
Greg Claytonbc8fc0f2013-06-11 21:56:55 +000029#include "llvm/ADT/SmallVector.h"
Sean Callanan7375f3e2014-12-09 21:18:59 +000030#include "llvm/Support/MD5.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000031#include "llvm/Support/MathExtras.h"
Greg Claytonbc8fc0f2013-06-11 21:56:55 +000032
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033using namespace lldb;
34using namespace lldb_private;
35
Kate Stoneb9c1b512016-09-06 20:57:50 +000036static inline uint16_t ReadInt16(const unsigned char *ptr, offset_t offset) {
37 uint16_t value;
38 memcpy(&value, ptr + offset, 2);
39 return value;
Eli Friedman5b405ed2010-06-10 23:56:16 +000040}
Jason Molendabbef4012014-01-25 05:12:35 +000041
Kate Stoneb9c1b512016-09-06 20:57:50 +000042static inline uint32_t ReadInt32(const unsigned char *ptr,
43 offset_t offset = 0) {
44 uint32_t value;
45 memcpy(&value, ptr + offset, 4);
46 return value;
Eli Friedman5b405ed2010-06-10 23:56:16 +000047}
Greg Claytonb852a112010-06-12 01:03:17 +000048
Kate Stoneb9c1b512016-09-06 20:57:50 +000049static inline uint64_t ReadInt64(const unsigned char *ptr,
50 offset_t offset = 0) {
51 uint64_t value;
52 memcpy(&value, ptr + offset, 8);
53 return value;
Eli Friedman5b405ed2010-06-10 23:56:16 +000054}
Greg Claytonb852a112010-06-12 01:03:17 +000055
Kate Stoneb9c1b512016-09-06 20:57:50 +000056static inline uint16_t ReadInt16(const void *ptr) {
57 uint16_t value;
58 memcpy(&value, ptr, 2);
59 return value;
Greg Clayton2452ab72013-02-08 22:02:02 +000060}
Jason Molendabbef4012014-01-25 05:12:35 +000061
Kate Stoneb9c1b512016-09-06 20:57:50 +000062static inline uint16_t ReadSwapInt16(const unsigned char *ptr,
63 offset_t offset) {
64 uint16_t value;
65 memcpy(&value, ptr + offset, 2);
66 return llvm::ByteSwap_16(value);
Eli Friedman5b405ed2010-06-10 23:56:16 +000067}
Greg Claytonb852a112010-06-12 01:03:17 +000068
Kate Stoneb9c1b512016-09-06 20:57:50 +000069static inline uint32_t ReadSwapInt32(const unsigned char *ptr,
70 offset_t offset) {
71 uint32_t value;
72 memcpy(&value, ptr + offset, 4);
73 return llvm::ByteSwap_32(value);
Eli Friedman5b405ed2010-06-10 23:56:16 +000074}
Jason Molendabbef4012014-01-25 05:12:35 +000075
Kate Stoneb9c1b512016-09-06 20:57:50 +000076static inline uint64_t ReadSwapInt64(const unsigned char *ptr,
77 offset_t offset) {
78 uint64_t value;
79 memcpy(&value, ptr + offset, 8);
80 return llvm::ByteSwap_64(value);
Eli Friedman5b405ed2010-06-10 23:56:16 +000081}
82
Kate Stoneb9c1b512016-09-06 20:57:50 +000083static inline uint16_t ReadSwapInt16(const void *ptr) {
84 uint16_t value;
85 memcpy(&value, ptr, 2);
86 return llvm::ByteSwap_16(value);
Greg Clayton2452ab72013-02-08 22:02:02 +000087}
88
Kate Stoneb9c1b512016-09-06 20:57:50 +000089static inline uint32_t ReadSwapInt32(const void *ptr) {
90 uint32_t value;
91 memcpy(&value, ptr, 4);
92 return llvm::ByteSwap_32(value);
Greg Clayton2452ab72013-02-08 22:02:02 +000093}
Jason Molendabbef4012014-01-25 05:12:35 +000094
Kate Stoneb9c1b512016-09-06 20:57:50 +000095static inline uint64_t ReadSwapInt64(const void *ptr) {
96 uint64_t value;
97 memcpy(&value, ptr, 8);
98 return llvm::ByteSwap_64(value);
Greg Clayton2452ab72013-02-08 22:02:02 +000099}
100
Kate Stoneb9c1b512016-09-06 20:57:50 +0000101DataExtractor::DataExtractor()
102 : m_start(nullptr), m_end(nullptr),
103 m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)),
104 m_data_sp(), m_target_byte_size(1) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000105
106//----------------------------------------------------------------------
107// This constructor allows us to use data that is owned by someone else.
108// The data must stay around as long as this object is valid.
109//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110DataExtractor::DataExtractor(const void *data, offset_t length,
111 ByteOrder endian, uint32_t addr_size,
112 uint32_t target_byte_size /*=1*/)
113 : m_start(const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(data))),
114 m_end(const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(data)) +
115 length),
116 m_byte_order(endian), m_addr_size(addr_size), m_data_sp(),
117 m_target_byte_size(target_byte_size) {
Jason Molenda13ca1422015-11-05 23:41:08 +0000118#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119 assert(addr_size == 4 || addr_size == 8);
Jason Molenda13ca1422015-11-05 23:41:08 +0000120#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000121}
122
123//----------------------------------------------------------------------
124// Make a shared pointer reference to the shared data in "data_sp" and
125// set the endian swapping setting to "swap", and the address size to
126// "addr_size". The shared data reference will ensure the data lives
127// as long as any DataExtractor objects exist that have a reference to
128// this data.
129//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000130DataExtractor::DataExtractor(const DataBufferSP &data_sp, ByteOrder endian,
131 uint32_t addr_size,
132 uint32_t target_byte_size /*=1*/)
133 : m_start(nullptr), m_end(nullptr), m_byte_order(endian),
134 m_addr_size(addr_size), m_data_sp(),
135 m_target_byte_size(target_byte_size) {
Jason Molenda13ca1422015-11-05 23:41:08 +0000136#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137 assert(addr_size == 4 || addr_size == 8);
Jason Molenda13ca1422015-11-05 23:41:08 +0000138#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139 SetData(data_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140}
141
142//----------------------------------------------------------------------
143// Initialize this object with a subset of the data bytes in "data".
144// If "data" contains shared data, then a reference to this shared
145// data will added and the shared data will stay around as long
146// as any object contains a reference to that data. The endian
147// swap and address size settings are copied from "data".
148//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000149DataExtractor::DataExtractor(const DataExtractor &data, offset_t offset,
150 offset_t length, uint32_t target_byte_size /*=1*/)
151 : m_start(nullptr), m_end(nullptr), m_byte_order(data.m_byte_order),
152 m_addr_size(data.m_addr_size), m_data_sp(),
153 m_target_byte_size(target_byte_size) {
Jason Molenda13ca1422015-11-05 23:41:08 +0000154#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +0000155 assert(m_addr_size == 4 || m_addr_size == 8);
Jason Molenda13ca1422015-11-05 23:41:08 +0000156#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000157 if (data.ValidOffset(offset)) {
158 offset_t bytes_available = data.GetByteSize() - offset;
159 if (length > bytes_available)
160 length = bytes_available;
161 SetData(data, offset, length);
162 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000163}
164
Kate Stoneb9c1b512016-09-06 20:57:50 +0000165DataExtractor::DataExtractor(const DataExtractor &rhs)
166 : m_start(rhs.m_start), m_end(rhs.m_end), m_byte_order(rhs.m_byte_order),
167 m_addr_size(rhs.m_addr_size), m_data_sp(rhs.m_data_sp),
168 m_target_byte_size(rhs.m_target_byte_size) {
Jason Molenda13ca1422015-11-05 23:41:08 +0000169#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +0000170 assert(m_addr_size == 4 || m_addr_size == 8);
Jason Molenda13ca1422015-11-05 23:41:08 +0000171#endif
Greg Clayton007d5be2011-05-30 00:49:24 +0000172}
173
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000174//----------------------------------------------------------------------
175// Assignment operator
176//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000177const DataExtractor &DataExtractor::operator=(const DataExtractor &rhs) {
178 if (this != &rhs) {
179 m_start = rhs.m_start;
180 m_end = rhs.m_end;
181 m_byte_order = rhs.m_byte_order;
182 m_addr_size = rhs.m_addr_size;
183 m_data_sp = rhs.m_data_sp;
184 }
185 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000186}
187
Eugene Zelenkodf370552016-03-02 02:18:18 +0000188DataExtractor::~DataExtractor() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000189
190//------------------------------------------------------------------
191// Clears the object contents back to a default invalid state, and
192// release any references to shared data that this object may
193// contain.
194//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000195void DataExtractor::Clear() {
196 m_start = nullptr;
197 m_end = nullptr;
198 m_byte_order = endian::InlHostByteOrder();
199 m_addr_size = sizeof(void *);
200 m_data_sp.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201}
202
203//------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204// If this object contains shared data, this function returns the
205// offset into that shared data. Else zero is returned.
206//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000207size_t DataExtractor::GetSharedDataOffset() const {
208 if (m_start != nullptr) {
209 const DataBuffer *data = m_data_sp.get();
210 if (data != nullptr) {
211 const uint8_t *data_bytes = data->GetBytes();
212 if (data_bytes != nullptr) {
213 assert(m_start >= data_bytes);
214 return m_start - data_bytes;
215 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000216 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000217 }
218 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000219}
220
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000221//----------------------------------------------------------------------
222// Set the data with which this object will extract from to data
223// starting at BYTES and set the length of the data to LENGTH bytes
224// long. The data is externally owned must be around at least as
225// long as this object points to the data. No copy of the data is
226// made, this object just refers to this data and can extract from
227// it. If this object refers to any shared data upon entry, the
228// reference to that data will be released. Is SWAP is set to true,
229// any data extracted will be endian swapped.
230//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000231lldb::offset_t DataExtractor::SetData(const void *bytes, offset_t length,
232 ByteOrder endian) {
233 m_byte_order = endian;
234 m_data_sp.reset();
235 if (bytes == nullptr || length == 0) {
236 m_start = nullptr;
237 m_end = nullptr;
238 } else {
239 m_start = const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(bytes));
240 m_end = m_start + length;
241 }
242 return GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000243}
244
245//----------------------------------------------------------------------
246// Assign the data for this object to be a subrange in "data"
247// starting "data_offset" bytes into "data" and ending "data_length"
248// bytes later. If "data_offset" is not a valid offset into "data",
249// then this object will contain no bytes. If "data_offset" is
250// within "data" yet "data_length" is too large, the length will be
251// capped at the number of bytes remaining in "data". If "data"
252// contains a shared pointer to other data, then a ref counted
253// pointer to that data will be made in this object. If "data"
254// doesn't contain a shared pointer to data, then the bytes referred
255// to in "data" will need to exist at least as long as this object
256// refers to those bytes. The address size and endian swap settings
257// are copied from the current values in "data".
258//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000259lldb::offset_t DataExtractor::SetData(const DataExtractor &data,
260 offset_t data_offset,
261 offset_t data_length) {
262 m_addr_size = data.m_addr_size;
Jason Molenda13ca1422015-11-05 23:41:08 +0000263#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +0000264 assert(m_addr_size == 4 || m_addr_size == 8);
Jason Molenda13ca1422015-11-05 23:41:08 +0000265#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000266 // If "data" contains shared pointer to data, then we can use that
267 if (data.m_data_sp) {
268 m_byte_order = data.m_byte_order;
269 return SetData(data.m_data_sp, data.GetSharedDataOffset() + data_offset,
270 data_length);
271 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000272
Kate Stoneb9c1b512016-09-06 20:57:50 +0000273 // We have a DataExtractor object that just has a pointer to bytes
274 if (data.ValidOffset(data_offset)) {
275 if (data_length > data.GetByteSize() - data_offset)
276 data_length = data.GetByteSize() - data_offset;
277 return SetData(data.GetDataStart() + data_offset, data_length,
278 data.GetByteOrder());
279 }
280 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000281}
282
283//----------------------------------------------------------------------
284// Assign the data for this object to be a subrange of the shared
285// data in "data_sp" starting "data_offset" bytes into "data_sp"
286// and ending "data_length" bytes later. If "data_offset" is not
287// a valid offset into "data_sp", then this object will contain no
288// bytes. If "data_offset" is within "data_sp" yet "data_length" is
289// too large, the length will be capped at the number of bytes
290// remaining in "data_sp". A ref counted pointer to the data in
291// "data_sp" will be made in this object IF the number of bytes this
292// object refers to in greater than zero (if at least one byte was
293// available starting at "data_offset") to ensure the data stays
294// around as long as it is needed. The address size and endian swap
295// settings will remain unchanged from their current settings.
296//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000297lldb::offset_t DataExtractor::SetData(const DataBufferSP &data_sp,
298 offset_t data_offset,
299 offset_t data_length) {
300 m_start = m_end = nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000301
Kate Stoneb9c1b512016-09-06 20:57:50 +0000302 if (data_length > 0) {
303 m_data_sp = data_sp;
304 if (data_sp) {
305 const size_t data_size = data_sp->GetByteSize();
306 if (data_offset < data_size) {
307 m_start = data_sp->GetBytes() + data_offset;
308 const size_t bytes_left = data_size - data_offset;
309 // Cap the length of we asked for too many
310 if (data_length <= bytes_left)
311 m_end = m_start + data_length; // We got all the bytes we wanted
312 else
313 m_end = m_start + bytes_left; // Not all the bytes requested were
314 // available in the shared data
315 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000316 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000317 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000318
Kate Stoneb9c1b512016-09-06 20:57:50 +0000319 size_t new_size = GetByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000320
Kate Stoneb9c1b512016-09-06 20:57:50 +0000321 // Don't hold a shared pointer to the data buffer if we don't share
322 // any valid bytes in the shared buffer.
323 if (new_size == 0)
324 m_data_sp.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325
Kate Stoneb9c1b512016-09-06 20:57:50 +0000326 return new_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327}
328
329//----------------------------------------------------------------------
330// Extract a single unsigned char from the binary data and update
331// the offset pointed to by "offset_ptr".
332//
333// RETURNS the byte that was extracted, or zero on failure.
334//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000335uint8_t DataExtractor::GetU8(offset_t *offset_ptr) const {
336 const uint8_t *data = (const uint8_t *)GetData(offset_ptr, 1);
337 if (data)
338 return *data;
339 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340}
341
342//----------------------------------------------------------------------
343// Extract "count" unsigned chars from the binary data and update the
344// offset pointed to by "offset_ptr". The extracted data is copied into
345// "dst".
346//
Eugene Zelenkodf370552016-03-02 02:18:18 +0000347// RETURNS the non-nullptr buffer pointer upon successful extraction of
348// all the requested bytes, or nullptr when the data is not available in
Bruce Mitchener6a7f3332014-06-27 02:42:12 +0000349// the buffer due to being out of bounds, or insufficient data.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000350//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000351void *DataExtractor::GetU8(offset_t *offset_ptr, void *dst,
352 uint32_t count) const {
353 const uint8_t *data = (const uint8_t *)GetData(offset_ptr, count);
354 if (data) {
355 // Copy the data into the buffer
356 memcpy(dst, data, count);
357 // Return a non-nullptr pointer to the converted data as an indicator of
358 // success
359 return dst;
360 }
361 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000362}
363
364//----------------------------------------------------------------------
365// Extract a single uint16_t from the data and update the offset
366// pointed to by "offset_ptr".
367//
368// RETURNS the uint16_t that was extracted, or zero on failure.
369//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000370uint16_t DataExtractor::GetU16(offset_t *offset_ptr) const {
371 uint16_t val = 0;
372 const uint8_t *data = (const uint8_t *)GetData(offset_ptr, sizeof(val));
373 if (data) {
374 if (m_byte_order != endian::InlHostByteOrder())
375 val = ReadSwapInt16(data);
376 else
377 val = ReadInt16(data);
378 }
379 return val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000380}
381
Kate Stoneb9c1b512016-09-06 20:57:50 +0000382uint16_t DataExtractor::GetU16_unchecked(offset_t *offset_ptr) const {
383 uint16_t val;
384 if (m_byte_order == endian::InlHostByteOrder())
385 val = ReadInt16(m_start, *offset_ptr);
386 else
387 val = ReadSwapInt16(m_start, *offset_ptr);
388 *offset_ptr += sizeof(val);
389 return val;
Greg Claytond88d7592010-09-15 08:33:30 +0000390}
391
Kate Stoneb9c1b512016-09-06 20:57:50 +0000392uint32_t DataExtractor::GetU32_unchecked(offset_t *offset_ptr) const {
393 uint32_t val;
394 if (m_byte_order == endian::InlHostByteOrder())
395 val = ReadInt32(m_start, *offset_ptr);
396 else
397 val = ReadSwapInt32(m_start, *offset_ptr);
398 *offset_ptr += sizeof(val);
399 return val;
Greg Claytond88d7592010-09-15 08:33:30 +0000400}
401
Kate Stoneb9c1b512016-09-06 20:57:50 +0000402uint64_t DataExtractor::GetU64_unchecked(offset_t *offset_ptr) const {
403 uint64_t val;
404 if (m_byte_order == endian::InlHostByteOrder())
405 val = ReadInt64(m_start, *offset_ptr);
406 else
407 val = ReadSwapInt64(m_start, *offset_ptr);
408 *offset_ptr += sizeof(val);
409 return val;
Greg Claytond88d7592010-09-15 08:33:30 +0000410}
411
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000412//----------------------------------------------------------------------
413// Extract "count" uint16_t values from the binary data and update
414// the offset pointed to by "offset_ptr". The extracted data is
415// copied into "dst".
416//
Eugene Zelenkodf370552016-03-02 02:18:18 +0000417// RETURNS the non-nullptr buffer pointer upon successful extraction of
418// all the requested bytes, or nullptr when the data is not available
Bruce Mitchener6a7f3332014-06-27 02:42:12 +0000419// in the buffer due to being out of bounds, or insufficient data.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000420//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000421void *DataExtractor::GetU16(offset_t *offset_ptr, void *void_dst,
422 uint32_t count) const {
423 const size_t src_size = sizeof(uint16_t) * count;
424 const uint16_t *src = (const uint16_t *)GetData(offset_ptr, src_size);
425 if (src) {
426 if (m_byte_order != endian::InlHostByteOrder()) {
427 uint16_t *dst_pos = (uint16_t *)void_dst;
428 uint16_t *dst_end = dst_pos + count;
429 const uint16_t *src_pos = src;
430 while (dst_pos < dst_end) {
431 *dst_pos = ReadSwapInt16(src_pos);
432 ++dst_pos;
433 ++src_pos;
434 }
435 } else {
436 memcpy(void_dst, src, src_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000437 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000438 // Return a non-nullptr pointer to the converted data as an indicator of
439 // success
440 return void_dst;
441 }
442 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000443}
444
445//----------------------------------------------------------------------
446// Extract a single uint32_t from the data and update the offset
447// pointed to by "offset_ptr".
448//
449// RETURNS the uint32_t that was extracted, or zero on failure.
450//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000451uint32_t DataExtractor::GetU32(offset_t *offset_ptr) const {
452 uint32_t val = 0;
453 const uint8_t *data = (const uint8_t *)GetData(offset_ptr, sizeof(val));
454 if (data) {
455 if (m_byte_order != endian::InlHostByteOrder()) {
456 val = ReadSwapInt32(data);
457 } else {
458 memcpy(&val, data, 4);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000459 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000460 }
461 return val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000462}
463
464//----------------------------------------------------------------------
465// Extract "count" uint32_t values from the binary data and update
466// the offset pointed to by "offset_ptr". The extracted data is
467// copied into "dst".
468//
Eugene Zelenkodf370552016-03-02 02:18:18 +0000469// RETURNS the non-nullptr buffer pointer upon successful extraction of
470// all the requested bytes, or nullptr when the data is not available
Bruce Mitchener6a7f3332014-06-27 02:42:12 +0000471// in the buffer due to being out of bounds, or insufficient data.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000472//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000473void *DataExtractor::GetU32(offset_t *offset_ptr, void *void_dst,
474 uint32_t count) const {
475 const size_t src_size = sizeof(uint32_t) * count;
476 const uint32_t *src = (const uint32_t *)GetData(offset_ptr, src_size);
477 if (src) {
478 if (m_byte_order != endian::InlHostByteOrder()) {
479 uint32_t *dst_pos = (uint32_t *)void_dst;
480 uint32_t *dst_end = dst_pos + count;
481 const uint32_t *src_pos = src;
482 while (dst_pos < dst_end) {
483 *dst_pos = ReadSwapInt32(src_pos);
484 ++dst_pos;
485 ++src_pos;
486 }
487 } else {
488 memcpy(void_dst, src, src_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000490 // Return a non-nullptr pointer to the converted data as an indicator of
491 // success
492 return void_dst;
493 }
494 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000495}
496
497//----------------------------------------------------------------------
498// Extract a single uint64_t from the data and update the offset
499// pointed to by "offset_ptr".
500//
501// RETURNS the uint64_t that was extracted, or zero on failure.
502//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000503uint64_t DataExtractor::GetU64(offset_t *offset_ptr) const {
504 uint64_t val = 0;
505 const uint8_t *data = (const uint8_t *)GetData(offset_ptr, sizeof(val));
506 if (data) {
507 if (m_byte_order != endian::InlHostByteOrder()) {
508 val = ReadSwapInt64(data);
509 } else {
510 memcpy(&val, data, 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000511 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000512 }
513 return val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000514}
515
516//----------------------------------------------------------------------
517// GetU64
518//
519// Get multiple consecutive 64 bit values. Return true if the entire
520// read succeeds and increment the offset pointed to by offset_ptr, else
521// return false and leave the offset pointed to by offset_ptr unchanged.
522//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000523void *DataExtractor::GetU64(offset_t *offset_ptr, void *void_dst,
524 uint32_t count) const {
525 const size_t src_size = sizeof(uint64_t) * count;
526 const uint64_t *src = (const uint64_t *)GetData(offset_ptr, src_size);
527 if (src) {
528 if (m_byte_order != endian::InlHostByteOrder()) {
529 uint64_t *dst_pos = (uint64_t *)void_dst;
530 uint64_t *dst_end = dst_pos + count;
531 const uint64_t *src_pos = src;
532 while (dst_pos < dst_end) {
533 *dst_pos = ReadSwapInt64(src_pos);
534 ++dst_pos;
535 ++src_pos;
536 }
537 } else {
538 memcpy(void_dst, src, src_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000539 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000540 // Return a non-nullptr pointer to the converted data as an indicator of
541 // success
542 return void_dst;
543 }
544 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000545}
546
547//----------------------------------------------------------------------
548// Extract a single integer value from the data and update the offset
549// pointed to by "offset_ptr". The size of the extracted integer
550// is specified by the "byte_size" argument. "byte_size" should have
551// a value between 1 and 4 since the return value is only 32 bits
552// wide. Any "byte_size" values less than 1 or greater than 4 will
553// result in nothing being extracted, and zero being returned.
554//
555// RETURNS the integer value that was extracted, or zero on failure.
556//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000557uint32_t DataExtractor::GetMaxU32(offset_t *offset_ptr,
558 size_t byte_size) const {
559 switch (byte_size) {
560 case 1:
561 return GetU8(offset_ptr);
562 break;
563 case 2:
564 return GetU16(offset_ptr);
565 break;
566 case 4:
567 return GetU32(offset_ptr);
568 break;
569 default:
570 assert(false && "GetMaxU32 unhandled case!");
571 break;
572 }
573 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000574}
575
576//----------------------------------------------------------------------
577// Extract a single integer value from the data and update the offset
578// pointed to by "offset_ptr". The size of the extracted integer
579// is specified by the "byte_size" argument. "byte_size" should have
580// a value >= 1 and <= 8 since the return value is only 64 bits
581// wide. Any "byte_size" values less than 1 or greater than 8 will
582// result in nothing being extracted, and zero being returned.
583//
584// RETURNS the integer value that was extracted, or zero on failure.
585//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000586uint64_t DataExtractor::GetMaxU64(offset_t *offset_ptr, size_t size) const {
587 switch (size) {
588 case 1:
589 return GetU8(offset_ptr);
590 break;
591 case 2:
592 return GetU16(offset_ptr);
593 break;
594 case 4:
595 return GetU32(offset_ptr);
596 break;
597 case 8:
598 return GetU64(offset_ptr);
599 break;
600 default:
601 assert(false && "GetMax64 unhandled case!");
602 break;
603 }
604 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000605}
606
Kate Stoneb9c1b512016-09-06 20:57:50 +0000607uint64_t DataExtractor::GetMaxU64_unchecked(offset_t *offset_ptr,
608 size_t size) const {
609 switch (size) {
610 case 1:
611 return GetU8_unchecked(offset_ptr);
612 break;
613 case 2:
614 return GetU16_unchecked(offset_ptr);
615 break;
616 case 4:
617 return GetU32_unchecked(offset_ptr);
618 break;
619 case 8:
620 return GetU64_unchecked(offset_ptr);
621 break;
622 default:
623 assert(false && "GetMax64 unhandled case!");
624 break;
625 }
626 return 0;
Greg Clayton77ccca72011-12-30 00:32:24 +0000627}
628
Kate Stoneb9c1b512016-09-06 20:57:50 +0000629int64_t DataExtractor::GetMaxS64(offset_t *offset_ptr, size_t size) const {
630 switch (size) {
631 case 1:
632 return (int8_t)GetU8(offset_ptr);
633 break;
634 case 2:
635 return (int16_t)GetU16(offset_ptr);
636 break;
637 case 4:
638 return (int32_t)GetU32(offset_ptr);
639 break;
640 case 8:
641 return (int64_t)GetU64(offset_ptr);
642 break;
643 default:
644 assert(false && "GetMax64 unhandled case!");
645 break;
646 }
647 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000648}
649
Kate Stoneb9c1b512016-09-06 20:57:50 +0000650uint64_t DataExtractor::GetMaxU64Bitfield(offset_t *offset_ptr, size_t size,
651 uint32_t bitfield_bit_size,
652 uint32_t bitfield_bit_offset) const {
653 uint64_t uval64 = GetMaxU64(offset_ptr, size);
654 if (bitfield_bit_size > 0) {
655 int32_t lsbcount = bitfield_bit_offset;
656 if (m_byte_order == eByteOrderBig)
657 lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;
658 if (lsbcount > 0)
659 uval64 >>= lsbcount;
660 uint64_t bitfield_mask = ((1ul << bitfield_bit_size) - 1);
661 if (!bitfield_mask && bitfield_bit_offset == 0 && bitfield_bit_size == 64)
662 return uval64;
663 uval64 &= bitfield_mask;
664 }
665 return uval64;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000666}
667
Kate Stoneb9c1b512016-09-06 20:57:50 +0000668int64_t DataExtractor::GetMaxS64Bitfield(offset_t *offset_ptr, size_t size,
669 uint32_t bitfield_bit_size,
670 uint32_t bitfield_bit_offset) const {
671 int64_t sval64 = GetMaxS64(offset_ptr, size);
672 if (bitfield_bit_size > 0) {
673 int32_t lsbcount = bitfield_bit_offset;
674 if (m_byte_order == eByteOrderBig)
675 lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;
676 if (lsbcount > 0)
677 sval64 >>= lsbcount;
678 uint64_t bitfield_mask = (((uint64_t)1) << bitfield_bit_size) - 1;
679 sval64 &= bitfield_mask;
680 // sign extend if needed
681 if (sval64 & (((uint64_t)1) << (bitfield_bit_size - 1)))
682 sval64 |= ~bitfield_mask;
683 }
684 return sval64;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000685}
686
Kate Stoneb9c1b512016-09-06 20:57:50 +0000687float DataExtractor::GetFloat(offset_t *offset_ptr) const {
688 typedef float float_type;
689 float_type val = 0.0;
690 const size_t src_size = sizeof(float_type);
691 const float_type *src = (const float_type *)GetData(offset_ptr, src_size);
692 if (src) {
693 if (m_byte_order != endian::InlHostByteOrder()) {
694 const uint8_t *src_data = (const uint8_t *)src;
695 uint8_t *dst_data = (uint8_t *)&val;
696 for (size_t i = 0; i < sizeof(float_type); ++i)
697 dst_data[sizeof(float_type) - 1 - i] = src_data[i];
698 } else {
699 val = *src;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000700 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000701 }
702 return val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000703}
704
Kate Stoneb9c1b512016-09-06 20:57:50 +0000705double DataExtractor::GetDouble(offset_t *offset_ptr) const {
706 typedef double float_type;
707 float_type val = 0.0;
708 const size_t src_size = sizeof(float_type);
709 const float_type *src = (const float_type *)GetData(offset_ptr, src_size);
710 if (src) {
711 if (m_byte_order != endian::InlHostByteOrder()) {
712 const uint8_t *src_data = (const uint8_t *)src;
713 uint8_t *dst_data = (uint8_t *)&val;
714 for (size_t i = 0; i < sizeof(float_type); ++i)
715 dst_data[sizeof(float_type) - 1 - i] = src_data[i];
716 } else {
717 val = *src;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000719 }
720 return val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000721}
722
Kate Stoneb9c1b512016-09-06 20:57:50 +0000723long double DataExtractor::GetLongDouble(offset_t *offset_ptr) const {
724 long double val = 0.0;
725#if defined(__i386__) || defined(__amd64__) || defined(__x86_64__) || \
726 defined(_M_IX86) || defined(_M_IA64) || defined(_M_X64)
727 *offset_ptr += CopyByteOrderedData(*offset_ptr, 10, &val, sizeof(val),
728 endian::InlHostByteOrder());
Richard Mittonf2bef0b2013-08-19 19:39:03 +0000729#else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000730 *offset_ptr += CopyByteOrderedData(*offset_ptr, sizeof(val), &val,
731 sizeof(val), endian::InlHostByteOrder());
Richard Mittonf2bef0b2013-08-19 19:39:03 +0000732#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000733 return val;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000734}
735
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000736//------------------------------------------------------------------
737// Extract a single address from the data and update the offset
738// pointed to by "offset_ptr". The size of the extracted address
739// comes from the "this->m_addr_size" member variable and should be
740// set correctly prior to extracting any address values.
741//
742// RETURNS the address that was extracted, or zero on failure.
743//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000744uint64_t DataExtractor::GetAddress(offset_t *offset_ptr) const {
Jason Molenda13ca1422015-11-05 23:41:08 +0000745#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +0000746 assert(m_addr_size == 4 || m_addr_size == 8);
Jason Molenda13ca1422015-11-05 23:41:08 +0000747#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000748 return GetMaxU64(offset_ptr, m_addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000749}
750
Kate Stoneb9c1b512016-09-06 20:57:50 +0000751uint64_t DataExtractor::GetAddress_unchecked(offset_t *offset_ptr) const {
Jason Molenda13ca1422015-11-05 23:41:08 +0000752#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +0000753 assert(m_addr_size == 4 || m_addr_size == 8);
Jason Molenda13ca1422015-11-05 23:41:08 +0000754#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000755 return GetMaxU64_unchecked(offset_ptr, m_addr_size);
Greg Clayton77ccca72011-12-30 00:32:24 +0000756}
757
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000758//------------------------------------------------------------------
759// Extract a single pointer from the data and update the offset
760// pointed to by "offset_ptr". The size of the extracted pointer
761// comes from the "this->m_addr_size" member variable and should be
762// set correctly prior to extracting any pointer values.
763//
764// RETURNS the pointer that was extracted, or zero on failure.
765//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000766uint64_t DataExtractor::GetPointer(offset_t *offset_ptr) const {
Jason Molenda13ca1422015-11-05 23:41:08 +0000767#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50 +0000768 assert(m_addr_size == 4 || m_addr_size == 8);
Jason Molenda13ca1422015-11-05 23:41:08 +0000769#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000770 return GetMaxU64(offset_ptr, m_addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000771}
772
Kate Stoneb9c1b512016-09-06 20:57:50 +0000773size_t DataExtractor::ExtractBytes(offset_t offset, offset_t length,
774 ByteOrder dst_byte_order, void *dst) const {
775 const uint8_t *src = PeekData(offset, length);
776 if (src) {
777 if (dst_byte_order != GetByteOrder()) {
778 // Validate that only a word- or register-sized dst is byte swapped
779 assert(length == 1 || length == 2 || length == 4 || length == 8 ||
780 length == 10 || length == 16 || length == 32);
Ed Maste7c0f2ce2013-09-19 15:12:36 +0000781
Kate Stoneb9c1b512016-09-06 20:57:50 +0000782 for (uint32_t i = 0; i < length; ++i)
783 ((uint8_t *)dst)[i] = src[length - i - 1];
784 } else
785 ::memcpy(dst, src, length);
786 return length;
787 }
788 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000789}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000790
Ed Masteb0e33d42013-10-09 20:34:25 +0000791// Extract data as it exists in target memory
Kate Stoneb9c1b512016-09-06 20:57:50 +0000792lldb::offset_t DataExtractor::CopyData(offset_t offset, offset_t length,
793 void *dst) const {
794 const uint8_t *src = PeekData(offset, length);
795 if (src) {
796 ::memcpy(dst, src, length);
797 return length;
798 }
799 return 0;
Ed Masteb0e33d42013-10-09 20:34:25 +0000800}
801
Greg Clayton7349bd92011-05-09 20:18:18 +0000802// Extract data and swap if needed when doing the copy
Greg Claytonc7bece562013-01-25 18:06:21 +0000803lldb::offset_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000804DataExtractor::CopyByteOrderedData(offset_t src_offset, offset_t src_len,
805 void *dst_void_ptr, offset_t dst_len,
806 ByteOrder dst_byte_order) const {
807 // Validate the source info
808 if (!ValidOffsetForDataOfSize(src_offset, src_len))
809 assert(ValidOffsetForDataOfSize(src_offset, src_len));
810 assert(src_len > 0);
811 assert(m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle);
Greg Clayton7349bd92011-05-09 20:18:18 +0000812
Kate Stoneb9c1b512016-09-06 20:57:50 +0000813 // Validate the destination info
814 assert(dst_void_ptr != nullptr);
815 assert(dst_len > 0);
816 assert(dst_byte_order == eByteOrderBig || dst_byte_order == eByteOrderLittle);
Ed Maste7c0f2ce2013-09-19 15:12:36 +0000817
Kate Stoneb9c1b512016-09-06 20:57:50 +0000818 // Validate that only a word- or register-sized dst is byte swapped
819 assert(dst_byte_order == m_byte_order || dst_len == 1 || dst_len == 2 ||
820 dst_len == 4 || dst_len == 8 || dst_len == 10 || dst_len == 16 ||
821 dst_len == 32);
Ed Maste7c0f2ce2013-09-19 15:12:36 +0000822
Kate Stoneb9c1b512016-09-06 20:57:50 +0000823 // Must have valid byte orders set in this object and for destination
824 if (!(dst_byte_order == eByteOrderBig ||
825 dst_byte_order == eByteOrderLittle) ||
826 !(m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle))
Greg Clayton7349bd92011-05-09 20:18:18 +0000827 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000828
829 uint8_t *dst = (uint8_t *)dst_void_ptr;
830 const uint8_t *src = (const uint8_t *)PeekData(src_offset, src_len);
831 if (src) {
832 if (dst_len >= src_len) {
833 // We are copying the entire value from src into dst.
834 // Calculate how many, if any, zeroes we need for the most
835 // significant bytes if "dst_len" is greater than "src_len"...
836 const size_t num_zeroes = dst_len - src_len;
837 if (dst_byte_order == eByteOrderBig) {
838 // Big endian, so we lead with zeroes...
839 if (num_zeroes > 0)
840 ::memset(dst, 0, num_zeroes);
841 // Then either copy or swap the rest
842 if (m_byte_order == eByteOrderBig) {
843 ::memcpy(dst + num_zeroes, src, src_len);
844 } else {
845 for (uint32_t i = 0; i < src_len; ++i)
846 dst[i + num_zeroes] = src[src_len - 1 - i];
847 }
848 } else {
849 // Little endian destination, so we lead the value bytes
850 if (m_byte_order == eByteOrderBig) {
851 for (uint32_t i = 0; i < src_len; ++i)
852 dst[i] = src[src_len - 1 - i];
853 } else {
854 ::memcpy(dst, src, src_len);
855 }
856 // And zero the rest...
857 if (num_zeroes > 0)
858 ::memset(dst + src_len, 0, num_zeroes);
859 }
860 return src_len;
861 } else {
862 // We are only copying some of the value from src into dst..
863
864 if (dst_byte_order == eByteOrderBig) {
865 // Big endian dst
866 if (m_byte_order == eByteOrderBig) {
867 // Big endian dst, with big endian src
868 ::memcpy(dst, src + (src_len - dst_len), dst_len);
869 } else {
870 // Big endian dst, with little endian src
871 for (uint32_t i = 0; i < dst_len; ++i)
872 dst[i] = src[dst_len - 1 - i];
873 }
874 } else {
875 // Little endian dst
876 if (m_byte_order == eByteOrderBig) {
877 // Little endian dst, with big endian src
878 for (uint32_t i = 0; i < dst_len; ++i)
879 dst[i] = src[src_len - 1 - i];
880 } else {
881 // Little endian dst, with big endian src
882 ::memcpy(dst, src, dst_len);
883 }
884 }
885 return dst_len;
886 }
887 }
888 return 0;
Greg Clayton7349bd92011-05-09 20:18:18 +0000889}
890
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000891//----------------------------------------------------------------------
Ed Maste76859d62013-07-23 18:22:17 +0000892// Extracts a variable length NULL terminated C string from
893// the data at the offset pointed to by "offset_ptr". The
894// "offset_ptr" will be updated with the offset of the byte that
895// follows the NULL terminator byte.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000896//
897// If the offset pointed to by "offset_ptr" is out of bounds, or if
Bruce Mitchener6a7f3332014-06-27 02:42:12 +0000898// "length" is non-zero and there aren't enough available
Eugene Zelenkodf370552016-03-02 02:18:18 +0000899// bytes, nullptr will be returned and "offset_ptr" will not be
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000900// updated.
901//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000902const char *DataExtractor::GetCStr(offset_t *offset_ptr) const {
903 const char *cstr = (const char *)PeekData(*offset_ptr, 1);
904 if (cstr) {
905 const char *cstr_end = cstr;
906 const char *end = (const char *)m_end;
907 while (cstr_end < end && *cstr_end)
908 ++cstr_end;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000909
Kate Stoneb9c1b512016-09-06 20:57:50 +0000910 // Now we are either at the end of the data or we point to the
911 // NULL C string terminator with cstr_end...
912 if (*cstr_end == '\0') {
913 // Advance the offset with one extra byte for the NULL terminator
914 *offset_ptr += (cstr_end - cstr + 1);
915 return cstr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000916 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000917
918 // We reached the end of the data without finding a NULL C string
919 // terminator. Fall through and return nullptr otherwise anyone that
920 // would have used the result as a C string can wander into
921 // unknown memory...
922 }
923 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000924}
925
Ed Maste76859d62013-07-23 18:22:17 +0000926//----------------------------------------------------------------------
927// Extracts a NULL terminated C string from the fixed length field of
928// length "len" at the offset pointed to by "offset_ptr".
929// The "offset_ptr" will be updated with the offset of the byte that
930// follows the fixed length field.
931//
932// If the offset pointed to by "offset_ptr" is out of bounds, or if
933// the offset plus the length of the field is out of bounds, or if the
Eugene Zelenkodf370552016-03-02 02:18:18 +0000934// field does not contain a NULL terminator byte, nullptr will be returned
Ed Maste76859d62013-07-23 18:22:17 +0000935// and "offset_ptr" will not be updated.
936//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000937const char *DataExtractor::GetCStr(offset_t *offset_ptr, offset_t len) const {
938 const char *cstr = (const char *)PeekData(*offset_ptr, len);
939 if (cstr != nullptr) {
940 if (memchr(cstr, '\0', len) == nullptr) {
941 return nullptr;
Ed Maste76859d62013-07-23 18:22:17 +0000942 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000943 *offset_ptr += len;
944 return cstr;
945 }
946 return nullptr;
Ed Maste76859d62013-07-23 18:22:17 +0000947}
948
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000949//------------------------------------------------------------------
950// Peeks at a string in the contained data. No verification is done
951// to make sure the entire string lies within the bounds of this
952// object's data, only "offset" is verified to be a valid offset.
953//
954// Returns a valid C string pointer if "offset" is a valid offset in
Eugene Zelenkodf370552016-03-02 02:18:18 +0000955// this object's data, else nullptr is returned.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000956//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000957const char *DataExtractor::PeekCStr(offset_t offset) const {
958 return (const char *)PeekData(offset, 1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000959}
960
961//----------------------------------------------------------------------
962// Extracts an unsigned LEB128 number from this object's data
963// starting at the offset pointed to by "offset_ptr". The offset
964// pointed to by "offset_ptr" will be updated with the offset of the
965// byte following the last extracted byte.
966//
967// Returned the extracted integer value.
968//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000969uint64_t DataExtractor::GetULEB128(offset_t *offset_ptr) const {
970 const uint8_t *src = (const uint8_t *)PeekData(*offset_ptr, 1);
971 if (src == nullptr)
Greg Clayton02947e02011-11-14 22:56:58 +0000972 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000973
974 const uint8_t *end = m_end;
975
976 if (src < end) {
977 uint64_t result = *src++;
978 if (result >= 0x80) {
979 result &= 0x7f;
980 int shift = 7;
981 while (src < end) {
982 uint8_t byte = *src++;
983 result |= (uint64_t)(byte & 0x7f) << shift;
984 if ((byte & 0x80) == 0)
985 break;
986 shift += 7;
987 }
988 }
989 *offset_ptr = src - m_start;
990 return result;
991 }
992
993 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000994}
995
996//----------------------------------------------------------------------
997// Extracts an signed LEB128 number from this object's data
998// starting at the offset pointed to by "offset_ptr". The offset
999// pointed to by "offset_ptr" will be updated with the offset of the
1000// byte following the last extracted byte.
1001//
1002// Returned the extracted integer value.
1003//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001004int64_t DataExtractor::GetSLEB128(offset_t *offset_ptr) const {
1005 const uint8_t *src = (const uint8_t *)PeekData(*offset_ptr, 1);
1006 if (src == nullptr)
Greg Clayton2452ab72013-02-08 22:02:02 +00001007 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001008
1009 const uint8_t *end = m_end;
1010
1011 if (src < end) {
1012 int64_t result = 0;
1013 int shift = 0;
1014 int size = sizeof(int64_t) * 8;
1015
1016 uint8_t byte = 0;
1017 int bytecount = 0;
1018
1019 while (src < end) {
1020 bytecount++;
1021 byte = *src++;
1022 result |= (int64_t)(byte & 0x7f) << shift;
1023 shift += 7;
1024 if ((byte & 0x80) == 0)
1025 break;
1026 }
1027
1028 // Sign bit of byte is 2nd high order bit (0x40)
1029 if (shift < size && (byte & 0x40))
1030 result |= -(1 << shift);
1031
1032 *offset_ptr += bytecount;
1033 return result;
1034 }
1035 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001036}
1037
1038//----------------------------------------------------------------------
1039// Skips a ULEB128 number (signed or unsigned) from this object's
1040// data starting at the offset pointed to by "offset_ptr". The
1041// offset pointed to by "offset_ptr" will be updated with the offset
1042// of the byte following the last extracted byte.
1043//
1044// Returns the number of bytes consumed during the extraction.
1045//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001046uint32_t DataExtractor::Skip_LEB128(offset_t *offset_ptr) const {
1047 uint32_t bytes_consumed = 0;
1048 const uint8_t *src = (const uint8_t *)PeekData(*offset_ptr, 1);
1049 if (src == nullptr)
1050 return 0;
1051
1052 const uint8_t *end = m_end;
1053
1054 if (src < end) {
1055 const uint8_t *src_pos = src;
1056 while ((src_pos < end) && (*src_pos++ & 0x80))
1057 ++bytes_consumed;
1058 *offset_ptr += src_pos - src;
1059 }
1060 return bytes_consumed;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001061}
1062
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001063//----------------------------------------------------------------------
1064// Dumps bytes from this object's data to the stream "s" starting
1065// "start_offset" bytes into this data, and ending with the byte
1066// before "end_offset". "base_addr" will be added to the offset
1067// into the dumped data when showing the offset into the data in the
1068// output information. "num_per_line" objects of type "type" will
1069// be dumped with the option to override the format for each object
1070// with "type_format". "type_format" is a printf style formatting
Eugene Zelenkodf370552016-03-02 02:18:18 +00001071// string. If "type_format" is nullptr, then an appropriate format
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001072// string will be used for the supplied "type". If the stream "s"
Eugene Zelenkodf370552016-03-02 02:18:18 +00001073// is nullptr, then the output will be send to Log().
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001074//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001075lldb::offset_t DataExtractor::PutToLog(Log *log, offset_t start_offset,
1076 offset_t length, uint64_t base_addr,
1077 uint32_t num_per_line,
1078 DataExtractor::Type type,
1079 const char *format) const {
1080 if (log == nullptr)
1081 return start_offset;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001082
Kate Stoneb9c1b512016-09-06 20:57:50 +00001083 offset_t offset;
1084 offset_t end_offset;
1085 uint32_t count;
1086 StreamString sstr;
1087 for (offset = start_offset, end_offset = offset + length, count = 0;
1088 ValidOffset(offset) && offset < end_offset; ++count) {
1089 if ((count % num_per_line) == 0) {
1090 // Print out any previous string
1091 if (sstr.GetSize() > 0) {
Zachary Turnerc1564272016-11-16 21:15:24 +00001092 log->PutString(sstr.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001093 sstr.Clear();
1094 }
1095 // Reset string offset and fill the current line string with address:
1096 if (base_addr != LLDB_INVALID_ADDRESS)
1097 sstr.Printf("0x%8.8" PRIx64 ":",
1098 (uint64_t)(base_addr + (offset - start_offset)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001099 }
1100
Kate Stoneb9c1b512016-09-06 20:57:50 +00001101 switch (type) {
1102 case TypeUInt8:
1103 sstr.Printf(format ? format : " %2.2x", GetU8(&offset));
1104 break;
1105 case TypeChar: {
1106 char ch = GetU8(&offset);
1107 sstr.Printf(format ? format : " %c", isprint(ch) ? ch : ' ');
1108 } break;
1109 case TypeUInt16:
1110 sstr.Printf(format ? format : " %4.4x", GetU16(&offset));
1111 break;
1112 case TypeUInt32:
1113 sstr.Printf(format ? format : " %8.8x", GetU32(&offset));
1114 break;
1115 case TypeUInt64:
1116 sstr.Printf(format ? format : " %16.16" PRIx64, GetU64(&offset));
1117 break;
1118 case TypePointer:
1119 sstr.Printf(format ? format : " 0x%" PRIx64, GetAddress(&offset));
1120 break;
1121 case TypeULEB128:
1122 sstr.Printf(format ? format : " 0x%" PRIx64, GetULEB128(&offset));
1123 break;
1124 case TypeSLEB128:
1125 sstr.Printf(format ? format : " %" PRId64, GetSLEB128(&offset));
1126 break;
1127 }
1128 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001129
Zachary Turnerc1564272016-11-16 21:15:24 +00001130 if (!sstr.Empty())
1131 log->PutString(sstr.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001132
1133 return offset; // Return the offset at which we ended up
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001134}
1135
1136//----------------------------------------------------------------------
1137// DumpUUID
1138//
1139// Dump out a UUID starting at 'offset' bytes into the buffer
1140//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001141void DataExtractor::DumpUUID(Stream *s, offset_t offset) const {
1142 if (s) {
1143 const uint8_t *uuid_data = PeekData(offset, 16);
1144 if (uuid_data) {
1145 lldb_private::UUID uuid(uuid_data, 16);
1146 uuid.Dump(s);
1147 } else {
1148 s->Printf("<not enough data for UUID at offset 0x%8.8" PRIx64 ">",
1149 offset);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001150 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001151 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001152}
1153
Kate Stoneb9c1b512016-09-06 20:57:50 +00001154size_t DataExtractor::Copy(DataExtractor &dest_data) const {
1155 if (m_data_sp) {
1156 // we can pass along the SP to the data
1157 dest_data.SetData(m_data_sp);
1158 } else {
1159 const uint8_t *base_ptr = m_start;
1160 size_t data_size = GetByteSize();
1161 dest_data.SetData(DataBufferSP(new DataBufferHeap(base_ptr, data_size)));
1162 }
1163 return GetByteSize();
Enrico Granata9128ee22011-09-06 19:20:51 +00001164}
1165
Kate Stoneb9c1b512016-09-06 20:57:50 +00001166bool DataExtractor::Append(DataExtractor &rhs) {
1167 if (rhs.GetByteOrder() != GetByteOrder())
1168 return false;
Enrico Granata9128ee22011-09-06 19:20:51 +00001169
Kate Stoneb9c1b512016-09-06 20:57:50 +00001170 if (rhs.GetByteSize() == 0)
1171 return true;
1172
1173 if (GetByteSize() == 0)
1174 return (rhs.Copy(*this) > 0);
1175
1176 size_t bytes = GetByteSize() + rhs.GetByteSize();
1177
1178 DataBufferHeap *buffer_heap_ptr = nullptr;
1179 DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0));
1180
1181 if (!buffer_sp || buffer_heap_ptr == nullptr)
1182 return false;
1183
1184 uint8_t *bytes_ptr = buffer_heap_ptr->GetBytes();
1185
1186 memcpy(bytes_ptr, GetDataStart(), GetByteSize());
1187 memcpy(bytes_ptr + GetByteSize(), rhs.GetDataStart(), rhs.GetByteSize());
1188
1189 SetData(buffer_sp);
1190
1191 return true;
1192}
1193
1194bool DataExtractor::Append(void *buf, offset_t length) {
1195 if (buf == nullptr)
1196 return false;
1197
1198 if (length == 0)
1199 return true;
1200
1201 size_t bytes = GetByteSize() + length;
1202
1203 DataBufferHeap *buffer_heap_ptr = nullptr;
1204 DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0));
1205
1206 if (!buffer_sp || buffer_heap_ptr == nullptr)
1207 return false;
1208
1209 uint8_t *bytes_ptr = buffer_heap_ptr->GetBytes();
1210
1211 if (GetByteSize() > 0)
Enrico Granata9128ee22011-09-06 19:20:51 +00001212 memcpy(bytes_ptr, GetDataStart(), GetByteSize());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001213
1214 memcpy(bytes_ptr + GetByteSize(), buf, length);
1215
1216 SetData(buffer_sp);
1217
1218 return true;
Enrico Granata9128ee22011-09-06 19:20:51 +00001219}
1220
Kate Stoneb9c1b512016-09-06 20:57:50 +00001221void DataExtractor::Checksum(llvm::SmallVectorImpl<uint8_t> &dest,
1222 uint64_t max_data) {
1223 if (max_data == 0)
1224 max_data = GetByteSize();
1225 else
1226 max_data = std::min(max_data, GetByteSize());
Enrico Granata9128ee22011-09-06 19:20:51 +00001227
Kate Stoneb9c1b512016-09-06 20:57:50 +00001228 llvm::MD5 md5;
Sean Callanan7375f3e2014-12-09 21:18:59 +00001229
Kate Stoneb9c1b512016-09-06 20:57:50 +00001230 const llvm::ArrayRef<uint8_t> data(GetDataStart(), max_data);
1231 md5.update(data);
Sean Callanan7375f3e2014-12-09 21:18:59 +00001232
Kate Stoneb9c1b512016-09-06 20:57:50 +00001233 llvm::MD5::MD5Result result;
1234 md5.final(result);
Sean Callanan7375f3e2014-12-09 21:18:59 +00001235
Zachary Turner82a0c972017-03-20 23:33:18 +00001236 dest.clear();
1237 dest.append(result.Bytes.begin(), result.Bytes.end());
Sean Callanan7375f3e2014-12-09 21:18:59 +00001238}