Fixed 2 more issues found by the address sanitizer:
1 - A store off the end of a buffer in ValueObject.cpp 2 - DataExtractor had cases where bad offsets could cause invalid memory to be accessed. llvm-svn: 174757
This commit is contained in:
@@ -434,7 +434,13 @@ public:
|
|||||||
/// and length are valid, or NULL otherwise.
|
/// and length are valid, or NULL otherwise.
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
const void*
|
const void*
|
||||||
GetData (lldb::offset_t *offset_ptr, lldb::offset_t length) const;
|
GetData (lldb::offset_t *offset_ptr, lldb::offset_t length) const
|
||||||
|
{
|
||||||
|
const uint8_t *ptr = PeekData (*offset_ptr, length);
|
||||||
|
if (ptr)
|
||||||
|
*offset_ptr += length;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
/// Copy \a dst_len bytes from \a *offset_ptr and ensure the copied
|
/// Copy \a dst_len bytes from \a *offset_ptr and ensure the copied
|
||||||
@@ -1066,7 +1072,12 @@ public:
|
|||||||
/// otherwise.
|
/// otherwise.
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
const uint8_t*
|
const uint8_t*
|
||||||
PeekData (lldb::offset_t offset, lldb::offset_t length) const;
|
PeekData (lldb::offset_t offset, lldb::offset_t length) const
|
||||||
|
{
|
||||||
|
if (length > 0 && ValidOffsetForDataOfSize(offset, length))
|
||||||
|
return m_start + offset;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
/// Set the address byte size.
|
/// Set the address byte size.
|
||||||
@@ -1221,7 +1232,11 @@ public:
|
|||||||
/// length bytes available at that offset, \b false otherwise.
|
/// length bytes available at that offset, \b false otherwise.
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
ValidOffsetForDataOfSize (lldb::offset_t offset, lldb::offset_t length) const;
|
ValidOffsetForDataOfSize (lldb::offset_t offset, lldb::offset_t length) const
|
||||||
|
{
|
||||||
|
lldb::offset_t bytes_left = BytesLeft (offset);
|
||||||
|
return length <= bytes_left;
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
Copy (DataExtractor& dest_data) const;
|
Copy (DataExtractor& dest_data) const;
|
||||||
@@ -1233,6 +1248,16 @@ public:
|
|||||||
Append (void* bytes, lldb::offset_t length);
|
Append (void* bytes, lldb::offset_t length);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
lldb::offset_t
|
||||||
|
BytesLeft (lldb::offset_t offset) const
|
||||||
|
{
|
||||||
|
const lldb::offset_t size = GetByteSize();
|
||||||
|
if (offset >= size)
|
||||||
|
return 0;
|
||||||
|
return offset - size;
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// Member variables
|
// Member variables
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|||||||
@@ -620,6 +620,9 @@ public:
|
|||||||
virtual lldb::LanguageType
|
virtual lldb::LanguageType
|
||||||
GetObjectRuntimeLanguage();
|
GetObjectRuntimeLanguage();
|
||||||
|
|
||||||
|
virtual uint32_t
|
||||||
|
GetTypeInfo (lldb::clang_type_t *pointee_or_element_clang_type = NULL);
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
IsPointerType ();
|
IsPointerType ();
|
||||||
|
|
||||||
|
|||||||
@@ -107,6 +107,9 @@ public:
|
|||||||
GetTypeNameForOpaqueQualType (clang::ASTContext *ast,
|
GetTypeNameForOpaqueQualType (clang::ASTContext *ast,
|
||||||
lldb::clang_type_t opaque_qual_type);
|
lldb::clang_type_t opaque_qual_type);
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
GetClangTypeByteSize ();
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
GetClangTypeBitWidth ();
|
GetClangTypeBitWidth ();
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,23 @@ ReadInt64(const unsigned char* ptr, offset_t offset)
|
|||||||
return *(uint64_t *)(ptr + offset);
|
return *(uint64_t *)(ptr + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint16_t
|
||||||
|
ReadInt16(const void* ptr)
|
||||||
|
{
|
||||||
|
return *(uint16_t *)(ptr);
|
||||||
|
}
|
||||||
|
static inline uint32_t
|
||||||
|
ReadInt32 (const void* ptr)
|
||||||
|
{
|
||||||
|
return *(uint32_t *)(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t
|
||||||
|
ReadInt64(const void* ptr)
|
||||||
|
{
|
||||||
|
return *(uint64_t *)(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
static inline uint16_t
|
static inline uint16_t
|
||||||
ReadSwapInt16(const unsigned char* ptr, offset_t offset)
|
ReadSwapInt16(const unsigned char* ptr, offset_t offset)
|
||||||
{
|
{
|
||||||
@@ -71,6 +88,23 @@ ReadSwapInt64(const unsigned char* ptr, offset_t offset)
|
|||||||
return llvm::ByteSwap_64(*(uint64_t *)(ptr + offset));
|
return llvm::ByteSwap_64(*(uint64_t *)(ptr + offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint16_t
|
||||||
|
ReadSwapInt16(const void* ptr)
|
||||||
|
{
|
||||||
|
return llvm::ByteSwap_16(*(uint16_t *)(ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
ReadSwapInt32 (const void* ptr)
|
||||||
|
{
|
||||||
|
return llvm::ByteSwap_32(*(uint32_t *)(ptr));
|
||||||
|
}
|
||||||
|
static inline uint64_t
|
||||||
|
ReadSwapInt64(const void* ptr)
|
||||||
|
{
|
||||||
|
return llvm::ByteSwap_64(*(uint64_t *)(ptr));
|
||||||
|
}
|
||||||
|
|
||||||
#define NON_PRINTABLE_CHAR '.'
|
#define NON_PRINTABLE_CHAR '.'
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// Default constructor.
|
// Default constructor.
|
||||||
@@ -208,32 +242,6 @@ DataExtractor::GetSharedDataOffset () const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
|
||||||
// Returns true if there are LENGTH bytes availabe starting OFFSET
|
|
||||||
// into the data that is in this object.
|
|
||||||
//------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
DataExtractor::ValidOffsetForDataOfSize (offset_t offset, offset_t length) const
|
|
||||||
{
|
|
||||||
offset_t size = GetByteSize();
|
|
||||||
if (offset >= size)
|
|
||||||
return false; // offset isn't valid
|
|
||||||
|
|
||||||
if (length == 0)
|
|
||||||
return true; // No bytes requested at this offset, return true
|
|
||||||
|
|
||||||
// If we flip the bits in offset we can figure out how
|
|
||||||
// many bytes we have left before "offset + length"
|
|
||||||
// could overflow when doing unsigned arithmetic.
|
|
||||||
if (length > ~offset)
|
|
||||||
return false; // unsigned overflow
|
|
||||||
|
|
||||||
// Make sure "offset + length" is a valid offset as well.
|
|
||||||
// length must be greater than zero for this to be a
|
|
||||||
// valid expression, and we have already checked for this.
|
|
||||||
return ((offset + length) <= size);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// Set the data with which this object will extract from to data
|
// Set the data with which this object will extract from to data
|
||||||
// starting at BYTES and set the length of the data to LENGTH bytes
|
// starting at BYTES and set the length of the data to LENGTH bytes
|
||||||
@@ -354,13 +362,10 @@ DataExtractor::SetData (const DataBufferSP& data_sp, offset_t data_offset, offse
|
|||||||
uint8_t
|
uint8_t
|
||||||
DataExtractor::GetU8 (offset_t *offset_ptr) const
|
DataExtractor::GetU8 (offset_t *offset_ptr) const
|
||||||
{
|
{
|
||||||
uint8_t val = 0;
|
const uint8_t *data = (const uint8_t *)GetData (offset_ptr, 1);
|
||||||
if ( m_start < m_end )
|
if (data)
|
||||||
{
|
return *data;
|
||||||
val = m_start[*offset_ptr];
|
return 0;
|
||||||
*offset_ptr += sizeof(val);
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
@@ -375,14 +380,11 @@ DataExtractor::GetU8 (offset_t *offset_ptr) const
|
|||||||
void *
|
void *
|
||||||
DataExtractor::GetU8 (offset_t *offset_ptr, void *dst, uint32_t count) const
|
DataExtractor::GetU8 (offset_t *offset_ptr, void *dst, uint32_t count) const
|
||||||
{
|
{
|
||||||
lldb::offset_t offset = *offset_ptr;
|
const uint8_t *data = (const uint8_t *)GetData (offset_ptr, count);
|
||||||
|
if (data)
|
||||||
if ((count > 0) && ValidOffsetForDataOfSize(offset, count) )
|
|
||||||
{
|
{
|
||||||
// Copy the data into the buffer
|
// Copy the data into the buffer
|
||||||
memcpy (dst, m_start + offset, count);
|
memcpy (dst, data, count);
|
||||||
// Advance the offset
|
|
||||||
*offset_ptr += count;
|
|
||||||
// Return a non-NULL pointer to the converted data as an indicator of success
|
// Return a non-NULL pointer to the converted data as an indicator of success
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
@@ -399,16 +401,13 @@ uint16_t
|
|||||||
DataExtractor::GetU16 (offset_t *offset_ptr) const
|
DataExtractor::GetU16 (offset_t *offset_ptr) const
|
||||||
{
|
{
|
||||||
uint16_t val = 0;
|
uint16_t val = 0;
|
||||||
lldb::offset_t offset = *offset_ptr;
|
const uint8_t *data = (const uint8_t *)GetData (offset_ptr, sizeof(val));
|
||||||
if ( ValidOffsetForDataOfSize(offset, sizeof(val)) )
|
if (data)
|
||||||
{
|
{
|
||||||
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
||||||
val = ReadSwapInt16(m_start, offset);
|
val = ReadSwapInt16(data);
|
||||||
else
|
else
|
||||||
val = ReadInt16 (m_start, offset);
|
val = ReadInt16 (data);
|
||||||
|
|
||||||
// Advance the offset
|
|
||||||
*offset_ptr += sizeof(val);
|
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@@ -416,9 +415,11 @@ DataExtractor::GetU16 (offset_t *offset_ptr) const
|
|||||||
uint16_t
|
uint16_t
|
||||||
DataExtractor::GetU16_unchecked (offset_t *offset_ptr) const
|
DataExtractor::GetU16_unchecked (offset_t *offset_ptr) const
|
||||||
{
|
{
|
||||||
uint16_t val = (m_byte_order == lldb::endian::InlHostByteOrder()) ?
|
uint16_t val;
|
||||||
ReadInt16 (m_start, *offset_ptr) :
|
if (m_byte_order == lldb::endian::InlHostByteOrder())
|
||||||
ReadSwapInt16(m_start, *offset_ptr);
|
val = ReadInt16 (m_start, *offset_ptr);
|
||||||
|
else
|
||||||
|
val = ReadSwapInt16(m_start, *offset_ptr);
|
||||||
*offset_ptr += sizeof(val);
|
*offset_ptr += sizeof(val);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@@ -426,9 +427,11 @@ DataExtractor::GetU16_unchecked (offset_t *offset_ptr) const
|
|||||||
uint32_t
|
uint32_t
|
||||||
DataExtractor::GetU32_unchecked (offset_t *offset_ptr) const
|
DataExtractor::GetU32_unchecked (offset_t *offset_ptr) const
|
||||||
{
|
{
|
||||||
uint32_t val = (m_byte_order == lldb::endian::InlHostByteOrder()) ?
|
uint32_t val;
|
||||||
ReadInt32 (m_start, *offset_ptr) :
|
if (m_byte_order == lldb::endian::InlHostByteOrder())
|
||||||
ReadSwapInt32 (m_start, *offset_ptr);
|
val = ReadInt32 (m_start, *offset_ptr);
|
||||||
|
else
|
||||||
|
val = ReadSwapInt32 (m_start, *offset_ptr);
|
||||||
*offset_ptr += sizeof(val);
|
*offset_ptr += sizeof(val);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@@ -436,9 +439,11 @@ DataExtractor::GetU32_unchecked (offset_t *offset_ptr) const
|
|||||||
uint64_t
|
uint64_t
|
||||||
DataExtractor::GetU64_unchecked (offset_t *offset_ptr) const
|
DataExtractor::GetU64_unchecked (offset_t *offset_ptr) const
|
||||||
{
|
{
|
||||||
uint64_t val = (m_byte_order == lldb::endian::InlHostByteOrder()) ?
|
uint64_t val;
|
||||||
ReadInt64 (m_start, *offset_ptr) :
|
if (m_byte_order == lldb::endian::InlHostByteOrder())
|
||||||
ReadSwapInt64 (m_start, *offset_ptr);
|
val = ReadInt64 (m_start, *offset_ptr);
|
||||||
|
else
|
||||||
|
val = ReadSwapInt64 (m_start, *offset_ptr);
|
||||||
*offset_ptr += sizeof(val);
|
*offset_ptr += sizeof(val);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@@ -456,29 +461,28 @@ DataExtractor::GetU64_unchecked (offset_t *offset_ptr) const
|
|||||||
void *
|
void *
|
||||||
DataExtractor::GetU16 (offset_t *offset_ptr, void *void_dst, uint32_t count) const
|
DataExtractor::GetU16 (offset_t *offset_ptr, void *void_dst, uint32_t count) const
|
||||||
{
|
{
|
||||||
uint16_t *dst = (uint16_t *)void_dst;
|
const size_t src_size = sizeof(uint16_t) * count;
|
||||||
const size_t value_size = sizeof(*dst);
|
const uint16_t *src = (const uint16_t *)GetData (offset_ptr, src_size);
|
||||||
lldb::offset_t offset = *offset_ptr;
|
if (src)
|
||||||
|
|
||||||
if ((count > 0) && ValidOffsetForDataOfSize(offset, value_size * count) )
|
|
||||||
{
|
{
|
||||||
uint16_t *value_ptr;
|
|
||||||
uint16_t *end = dst + count;
|
|
||||||
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
||||||
{
|
{
|
||||||
for (value_ptr = dst; value_ptr < end; ++value_ptr, offset += value_size)
|
uint16_t *dst_pos = (uint16_t *)void_dst;
|
||||||
*value_ptr = ReadSwapInt16 (m_start, offset);
|
uint16_t *dst_end = dst_pos + count;
|
||||||
|
const uint16_t *src_pos = src;
|
||||||
|
while (dst_pos < dst_end)
|
||||||
|
{
|
||||||
|
*dst_pos = ReadSwapInt16 (src_pos);
|
||||||
|
++dst_pos;
|
||||||
|
++src_pos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (value_ptr = dst; value_ptr < end; ++value_ptr, offset += value_size)
|
memcpy (void_dst, src, src_size);
|
||||||
*value_ptr = ReadInt16 (m_start, offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance the offset
|
|
||||||
*offset_ptr = offset;
|
|
||||||
// Return a non-NULL pointer to the converted data as an indicator of success
|
// Return a non-NULL pointer to the converted data as an indicator of success
|
||||||
return dst;
|
return void_dst;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -493,17 +497,13 @@ uint32_t
|
|||||||
DataExtractor::GetU32 (offset_t *offset_ptr) const
|
DataExtractor::GetU32 (offset_t *offset_ptr) const
|
||||||
{
|
{
|
||||||
uint32_t val = 0;
|
uint32_t val = 0;
|
||||||
lldb::offset_t offset = *offset_ptr;
|
const uint32_t *data = (const uint32_t *)GetData (offset_ptr, sizeof(val));
|
||||||
|
if (data)
|
||||||
if ( ValidOffsetForDataOfSize(offset, sizeof(val)) )
|
|
||||||
{
|
{
|
||||||
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
||||||
val = ReadSwapInt32 (m_start, offset);
|
val = ReadSwapInt32 (data);
|
||||||
else
|
else
|
||||||
val = ReadInt32 (m_start, offset);
|
val = *data;
|
||||||
|
|
||||||
// Advance the offset
|
|
||||||
*offset_ptr += sizeof(val);
|
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@@ -520,30 +520,28 @@ DataExtractor::GetU32 (offset_t *offset_ptr) const
|
|||||||
void *
|
void *
|
||||||
DataExtractor::GetU32 (offset_t *offset_ptr, void *void_dst, uint32_t count) const
|
DataExtractor::GetU32 (offset_t *offset_ptr, void *void_dst, uint32_t count) const
|
||||||
{
|
{
|
||||||
uint32_t *dst = (uint32_t *)void_dst;
|
const size_t src_size = sizeof(uint32_t) * count;
|
||||||
const size_t value_size = sizeof(*dst);
|
const uint32_t *src = (const uint32_t *)GetData (offset_ptr, src_size);
|
||||||
lldb::offset_t offset = *offset_ptr;
|
if (src)
|
||||||
|
|
||||||
if ((count > 0) && ValidOffsetForDataOfSize(offset, value_size * count))
|
|
||||||
{
|
{
|
||||||
uint32_t *value_ptr;
|
|
||||||
uint32_t *end = dst + count;
|
|
||||||
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
||||||
{
|
{
|
||||||
for (value_ptr = dst; value_ptr < end; ++value_ptr, offset += value_size)
|
uint32_t *dst_pos = (uint32_t *)void_dst;
|
||||||
*value_ptr = ReadSwapInt32 (m_start, offset);
|
uint32_t *dst_end = dst_pos + count;
|
||||||
|
const uint32_t *src_pos = src;
|
||||||
|
while (dst_pos < dst_end)
|
||||||
|
{
|
||||||
|
*dst_pos = ReadSwapInt32 (src_pos);
|
||||||
|
++dst_pos;
|
||||||
|
++src_pos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (value_ptr = dst; value_ptr < end; ++value_ptr, offset += value_size)
|
memcpy (void_dst, src, src_size);
|
||||||
*value_ptr = ReadInt32 (m_start, offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance the offset
|
|
||||||
*offset_ptr = offset;
|
|
||||||
// Return a non-NULL pointer to the converted data as an indicator of success
|
// Return a non-NULL pointer to the converted data as an indicator of success
|
||||||
return dst;
|
return void_dst;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -558,16 +556,13 @@ uint64_t
|
|||||||
DataExtractor::GetU64 (offset_t *offset_ptr) const
|
DataExtractor::GetU64 (offset_t *offset_ptr) const
|
||||||
{
|
{
|
||||||
uint64_t val = 0;
|
uint64_t val = 0;
|
||||||
lldb::offset_t offset = *offset_ptr;
|
const uint64_t *data = (const uint64_t *)GetData (offset_ptr, sizeof(val));
|
||||||
if ( ValidOffsetForDataOfSize(offset, sizeof(val)) )
|
if (data)
|
||||||
{
|
{
|
||||||
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
||||||
val = ReadSwapInt64 (m_start, offset);
|
val = ReadSwapInt64 (data);
|
||||||
else
|
else
|
||||||
val = ReadInt64 (m_start, offset);
|
val = *data;
|
||||||
|
|
||||||
// Advance the offset
|
|
||||||
*offset_ptr += sizeof(val);
|
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@@ -582,30 +577,28 @@ DataExtractor::GetU64 (offset_t *offset_ptr) const
|
|||||||
void *
|
void *
|
||||||
DataExtractor::GetU64 (offset_t *offset_ptr, void *void_dst, uint32_t count) const
|
DataExtractor::GetU64 (offset_t *offset_ptr, void *void_dst, uint32_t count) const
|
||||||
{
|
{
|
||||||
uint64_t *dst = (uint64_t *)void_dst;
|
const size_t src_size = sizeof(uint64_t) * count;
|
||||||
const size_t value_size = sizeof(uint64_t);
|
const uint64_t *src = (const uint64_t *)GetData (offset_ptr, src_size);
|
||||||
lldb::offset_t offset = *offset_ptr;
|
if (src)
|
||||||
|
|
||||||
if ((count > 0) && ValidOffsetForDataOfSize(offset, value_size * count))
|
|
||||||
{
|
{
|
||||||
uint64_t *value_ptr;
|
|
||||||
uint64_t *end = dst + count;
|
|
||||||
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
||||||
{
|
{
|
||||||
for (value_ptr = dst; value_ptr < end; ++value_ptr, offset += value_size)
|
uint64_t *dst_pos = (uint64_t *)void_dst;
|
||||||
*value_ptr = ReadSwapInt64 (m_start, offset);
|
uint64_t *dst_end = dst_pos + count;
|
||||||
|
const uint64_t *src_pos = src;
|
||||||
|
while (dst_pos < dst_end)
|
||||||
|
{
|
||||||
|
*dst_pos = ReadSwapInt64 (src_pos);
|
||||||
|
++dst_pos;
|
||||||
|
++src_pos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (value_ptr = dst; value_ptr < end; ++value_ptr, offset += value_size)
|
memcpy (void_dst, src, src_size);
|
||||||
*value_ptr = ReadInt64 (m_start, offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance the offset
|
|
||||||
*offset_ptr = offset;
|
|
||||||
// Return a non-NULL pointer to the converted data as an indicator of success
|
// Return a non-NULL pointer to the converted data as an indicator of success
|
||||||
return dst;
|
return void_dst;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -732,19 +725,20 @@ DataExtractor::GetFloat (offset_t *offset_ptr) const
|
|||||||
{
|
{
|
||||||
typedef float float_type;
|
typedef float float_type;
|
||||||
float_type val = 0.0;
|
float_type val = 0.0;
|
||||||
const uint8_t *src_data = PeekData (*offset_ptr, sizeof(float_type));
|
const size_t src_size = sizeof(float_type);
|
||||||
|
const float_type *src = (const float_type *)GetData (offset_ptr, src_size);
|
||||||
if (src_data)
|
if (src)
|
||||||
{
|
{
|
||||||
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
||||||
{
|
{
|
||||||
|
const uint8_t *src_data = (const uint8_t *)src;
|
||||||
uint8_t *dst_data = (uint8_t *)&val;
|
uint8_t *dst_data = (uint8_t *)&val;
|
||||||
for (int i=0; i<sizeof(float_type); ++i)
|
for (int i=0; i<sizeof(float_type); ++i)
|
||||||
dst_data[sizeof(float_type) - 1 - i] = src_data[i];
|
dst_data[sizeof(float_type) - 1 - i] = src_data[i];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
::memcpy (&val, src_data, sizeof (float_type));
|
val = *src;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance the offset
|
// Advance the offset
|
||||||
@@ -758,19 +752,20 @@ DataExtractor::GetDouble (offset_t *offset_ptr) const
|
|||||||
{
|
{
|
||||||
typedef double float_type;
|
typedef double float_type;
|
||||||
float_type val = 0.0;
|
float_type val = 0.0;
|
||||||
const uint8_t *src_data = PeekData (*offset_ptr, sizeof(float_type));
|
const size_t src_size = sizeof(float_type);
|
||||||
|
const float_type *src = (const float_type *)GetData (offset_ptr, src_size);
|
||||||
if (src_data)
|
if (src)
|
||||||
{
|
{
|
||||||
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
||||||
{
|
{
|
||||||
|
const uint8_t *src_data = (const uint8_t *)src;
|
||||||
uint8_t *dst_data = (uint8_t *)&val;
|
uint8_t *dst_data = (uint8_t *)&val;
|
||||||
for (int i=0; i<sizeof(float_type); ++i)
|
for (int i=0; i<sizeof(float_type); ++i)
|
||||||
dst_data[sizeof(float_type) - 1 - i] = src_data[i];
|
dst_data[sizeof(float_type) - 1 - i] = src_data[i];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
::memcpy (&val, src_data, sizeof (float_type));
|
val = *src;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance the offset
|
// Advance the offset
|
||||||
@@ -785,19 +780,20 @@ DataExtractor::GetLongDouble (offset_t *offset_ptr) const
|
|||||||
{
|
{
|
||||||
typedef long double float_type;
|
typedef long double float_type;
|
||||||
float_type val = 0.0;
|
float_type val = 0.0;
|
||||||
const uint8_t *src_data = PeekData (*offset_ptr, sizeof(float_type));
|
const size_t src_size = sizeof(float_type);
|
||||||
|
const float_type *src = (const float_type *)GetData (offset_ptr, src_size);
|
||||||
if (src_data)
|
if (src)
|
||||||
{
|
{
|
||||||
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
if (m_byte_order != lldb::endian::InlHostByteOrder())
|
||||||
{
|
{
|
||||||
|
const uint8_t *src_data = (const uint8_t *)src;
|
||||||
uint8_t *dst_data = (uint8_t *)&val;
|
uint8_t *dst_data = (uint8_t *)&val;
|
||||||
for (int i=0; i<sizeof(float_type); ++i)
|
for (int i=0; i<sizeof(float_type); ++i)
|
||||||
dst_data[sizeof(float_type) - 1 - i] = src_data[i];
|
dst_data[sizeof(float_type) - 1 - i] = src_data[i];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
::memcpy (&val, src_data, sizeof (float_type));
|
val = *src;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance the offset
|
// Advance the offset
|
||||||
@@ -964,41 +960,6 @@ DataExtractor::ExtractBytes (offset_t offset, offset_t length, ByteOrder dst_byt
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------
|
|
||||||
// Peeks at bytes in the contained data.
|
|
||||||
//
|
|
||||||
// Returns a valid pointer to bytes if "offset" is a valid offset in
|
|
||||||
// and there are "length" bytes available, else NULL is returned.
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
const uint8_t*
|
|
||||||
DataExtractor::PeekData (offset_t offset, offset_t length) const
|
|
||||||
{
|
|
||||||
if ( length > 0 && ValidOffsetForDataOfSize(offset, length) )
|
|
||||||
return m_start + offset;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
// Returns a pointer to a bytes in this object's data at the offset
|
|
||||||
// pointed to by "offset_ptr". If "length" is zero or too large,
|
|
||||||
// then the offset pointed to by "offset_ptr" will not be updated
|
|
||||||
// and NULL will be returned.
|
|
||||||
//
|
|
||||||
// Returns a pointer to the data if the offset and length are valid,
|
|
||||||
// or NULL otherwise.
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
const void*
|
|
||||||
DataExtractor::GetData (offset_t *offset_ptr, offset_t length) const
|
|
||||||
{
|
|
||||||
const uint8_t* bytes = NULL;
|
|
||||||
lldb::offset_t offset = *offset_ptr;
|
|
||||||
if ( length > 0 && ValidOffsetForDataOfSize(offset, length) )
|
|
||||||
{
|
|
||||||
bytes = m_start + offset;
|
|
||||||
*offset_ptr = offset + length;
|
|
||||||
}
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract data and swap if needed when doing the copy
|
// Extract data and swap if needed when doing the copy
|
||||||
lldb::offset_t
|
lldb::offset_t
|
||||||
@@ -1129,20 +1090,29 @@ DataExtractor::CopyByteOrderedData (offset_t src_offset,
|
|||||||
const char*
|
const char*
|
||||||
DataExtractor::GetCStr (offset_t *offset_ptr) const
|
DataExtractor::GetCStr (offset_t *offset_ptr) const
|
||||||
{
|
{
|
||||||
const char *s = NULL;
|
const char *cstr = (const char *)PeekData (*offset_ptr, 1);
|
||||||
if ( m_start < m_end )
|
if (cstr)
|
||||||
{
|
{
|
||||||
s = (char*)m_start + *offset_ptr;
|
const char *cstr_end = cstr;
|
||||||
|
const char *end = (const char *)m_end;
|
||||||
|
while (cstr_end < end && *cstr_end)
|
||||||
|
++cstr_end;
|
||||||
|
|
||||||
size_t length = strlen(s) + 1;
|
// Now we are either at the end of the data or we point to the
|
||||||
|
// NULL C string terminator with cstr_end...
|
||||||
|
if (*cstr_end == '\0')
|
||||||
|
{
|
||||||
|
// Advance the offset with one extra byte for the NULL terminator
|
||||||
|
*offset_ptr += (cstr_end - cstr + 1);
|
||||||
|
return cstr;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ValidOffsetForDataOfSize(*offset_ptr, length))
|
// We reached the end of the data without finding a NULL C string
|
||||||
return NULL;
|
// terminator. Fall through and return NULL otherwise anyone that
|
||||||
|
// would have used the result as a C string can wonder into
|
||||||
// Advance the offset
|
// unknown memory...
|
||||||
*offset_ptr += length;
|
|
||||||
}
|
}
|
||||||
return s;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
@@ -1156,9 +1126,7 @@ DataExtractor::GetCStr (offset_t *offset_ptr) const
|
|||||||
const char *
|
const char *
|
||||||
DataExtractor::PeekCStr (offset_t offset) const
|
DataExtractor::PeekCStr (offset_t offset) const
|
||||||
{
|
{
|
||||||
if (ValidOffset (offset))
|
return (const char *)PeekData (offset, 1);
|
||||||
return (const char*)m_start + offset;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
@@ -1172,7 +1140,7 @@ DataExtractor::PeekCStr (offset_t offset) const
|
|||||||
uint64_t
|
uint64_t
|
||||||
DataExtractor::GetULEB128 (offset_t *offset_ptr) const
|
DataExtractor::GetULEB128 (offset_t *offset_ptr) const
|
||||||
{
|
{
|
||||||
const uint8_t *src = m_start + *offset_ptr;
|
const uint8_t *src = (const uint8_t *)PeekData (*offset_ptr, 1);
|
||||||
const uint8_t *end = m_end;
|
const uint8_t *end = m_end;
|
||||||
|
|
||||||
if (src < end)
|
if (src < end)
|
||||||
@@ -1191,7 +1159,7 @@ DataExtractor::GetULEB128 (offset_t *offset_ptr) const
|
|||||||
shift += 7;
|
shift += 7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*offset_ptr = (uint32_t)(src - m_start);
|
*offset_ptr = src - m_start;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1209,18 +1177,19 @@ DataExtractor::GetULEB128 (offset_t *offset_ptr) const
|
|||||||
int64_t
|
int64_t
|
||||||
DataExtractor::GetSLEB128 (offset_t *offset_ptr) const
|
DataExtractor::GetSLEB128 (offset_t *offset_ptr) const
|
||||||
{
|
{
|
||||||
int64_t result = 0;
|
const uint8_t *src = (const uint8_t *)PeekData (*offset_ptr, 1);
|
||||||
|
const uint8_t *end = m_end;
|
||||||
|
|
||||||
if ( m_start < m_end )
|
if (src < end)
|
||||||
{
|
{
|
||||||
|
int64_t result = 0;
|
||||||
int shift = 0;
|
int shift = 0;
|
||||||
int size = sizeof (uint32_t) * 8;
|
int size = sizeof (int64_t) * 8;
|
||||||
const uint8_t *src = m_start + *offset_ptr;
|
|
||||||
|
|
||||||
uint8_t byte = 0;
|
uint8_t byte = 0;
|
||||||
int bytecount = 0;
|
int bytecount = 0;
|
||||||
|
|
||||||
while (src < m_end)
|
while (src < end)
|
||||||
{
|
{
|
||||||
bytecount++;
|
bytecount++;
|
||||||
byte = *src++;
|
byte = *src++;
|
||||||
@@ -1235,8 +1204,9 @@ DataExtractor::GetSLEB128 (offset_t *offset_ptr) const
|
|||||||
result |= - (1 << shift);
|
result |= - (1 << shift);
|
||||||
|
|
||||||
*offset_ptr += bytecount;
|
*offset_ptr += bytecount;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return result;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
@@ -1251,15 +1221,15 @@ uint32_t
|
|||||||
DataExtractor::Skip_LEB128 (offset_t *offset_ptr) const
|
DataExtractor::Skip_LEB128 (offset_t *offset_ptr) const
|
||||||
{
|
{
|
||||||
uint32_t bytes_consumed = 0;
|
uint32_t bytes_consumed = 0;
|
||||||
if ( m_start < m_end )
|
const uint8_t *src = (const uint8_t *)PeekData (*offset_ptr, 1);
|
||||||
|
const uint8_t *end = m_end;
|
||||||
|
|
||||||
|
if (src < end)
|
||||||
{
|
{
|
||||||
const uint8_t *start = m_start + *offset_ptr;
|
const uint8_t *src_pos = src;
|
||||||
const uint8_t *src = start;
|
while ((src_pos < end) && (*src_pos++ & 0x80))
|
||||||
|
|
||||||
while ((src < m_end) && (*src++ & 0x80))
|
|
||||||
++bytes_consumed;
|
++bytes_consumed;
|
||||||
|
*offset_ptr += src_pos - src;
|
||||||
*offset_ptr += src - start;
|
|
||||||
}
|
}
|
||||||
return bytes_consumed;
|
return bytes_consumed;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -674,12 +674,9 @@ bool
|
|||||||
ValueObject::MightHaveChildren()
|
ValueObject::MightHaveChildren()
|
||||||
{
|
{
|
||||||
bool has_children = false;
|
bool has_children = false;
|
||||||
clang_type_t clang_type = GetClangType();
|
const uint32_t type_info = GetTypeInfo();
|
||||||
if (clang_type)
|
if (type_info)
|
||||||
{
|
{
|
||||||
const uint32_t type_info = ClangASTContext::GetTypeInfo (clang_type,
|
|
||||||
GetClangAST(),
|
|
||||||
NULL);
|
|
||||||
if (type_info & (ClangASTContext::eTypeHasChildren |
|
if (type_info & (ClangASTContext::eTypeHasChildren |
|
||||||
ClangASTContext::eTypeIsPointer |
|
ClangASTContext::eTypeIsPointer |
|
||||||
ClangASTContext::eTypeIsReference))
|
ClangASTContext::eTypeIsReference))
|
||||||
@@ -877,11 +874,9 @@ bool
|
|||||||
ValueObject::IsCStringContainer(bool check_pointer)
|
ValueObject::IsCStringContainer(bool check_pointer)
|
||||||
{
|
{
|
||||||
clang_type_t elem_or_pointee_clang_type;
|
clang_type_t elem_or_pointee_clang_type;
|
||||||
const Flags type_flags (ClangASTContext::GetTypeInfo (GetClangType(),
|
const Flags type_flags (GetTypeInfo (&elem_or_pointee_clang_type));
|
||||||
GetClangAST(),
|
|
||||||
&elem_or_pointee_clang_type));
|
|
||||||
bool is_char_arr_ptr (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
|
bool is_char_arr_ptr (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
|
||||||
ClangASTContext::IsCharType (elem_or_pointee_clang_type));
|
ClangASTContext::IsCharType (elem_or_pointee_clang_type));
|
||||||
if (!is_char_arr_ptr)
|
if (!is_char_arr_ptr)
|
||||||
return false;
|
return false;
|
||||||
if (!check_pointer)
|
if (!check_pointer)
|
||||||
@@ -899,19 +894,20 @@ ValueObject::GetPointeeData (DataExtractor& data,
|
|||||||
uint32_t item_idx,
|
uint32_t item_idx,
|
||||||
uint32_t item_count)
|
uint32_t item_count)
|
||||||
{
|
{
|
||||||
if (!IsPointerType() && !IsArrayType())
|
clang_type_t pointee_or_element_clang_type;
|
||||||
|
const uint32_t type_info = GetTypeInfo (&pointee_or_element_clang_type);
|
||||||
|
const bool is_pointer_type = type_info & ClangASTContext::eTypeIsPointer;
|
||||||
|
const bool is_array_type = type_info & ClangASTContext::eTypeIsArray;
|
||||||
|
if (!(is_pointer_type || is_array_type))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (item_count == 0)
|
if (item_count == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
uint32_t stride = 0;
|
clang::ASTContext *ast = GetClangAST();
|
||||||
|
ClangASTType pointee_or_element_type(ast, pointee_or_element_clang_type);
|
||||||
|
|
||||||
ClangASTType type(GetClangAST(),
|
const uint64_t item_type_size = pointee_or_element_type.GetClangTypeByteSize();
|
||||||
GetClangType());
|
|
||||||
|
|
||||||
const uint64_t item_type_size = (IsPointerType() ? ClangASTType::GetTypeByteSize(GetClangAST(), type.GetPointeeType()) :
|
|
||||||
ClangASTType::GetTypeByteSize(GetClangAST(), type.GetArrayElementType(stride)));
|
|
||||||
|
|
||||||
const uint64_t bytes = item_count * item_type_size;
|
const uint64_t bytes = item_count * item_type_size;
|
||||||
|
|
||||||
@@ -919,7 +915,7 @@ ValueObject::GetPointeeData (DataExtractor& data,
|
|||||||
|
|
||||||
if (item_idx == 0 && item_count == 1) // simply a deref
|
if (item_idx == 0 && item_count == 1) // simply a deref
|
||||||
{
|
{
|
||||||
if (IsPointerType())
|
if (is_pointer_type)
|
||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
ValueObjectSP pointee_sp = Dereference(error);
|
ValueObjectSP pointee_sp = Dereference(error);
|
||||||
@@ -943,7 +939,7 @@ ValueObject::GetPointeeData (DataExtractor& data,
|
|||||||
lldb::DataBufferSP data_sp(heap_buf_ptr = new lldb_private::DataBufferHeap());
|
lldb::DataBufferSP data_sp(heap_buf_ptr = new lldb_private::DataBufferHeap());
|
||||||
|
|
||||||
AddressType addr_type;
|
AddressType addr_type;
|
||||||
lldb::addr_t addr = IsPointerType() ? GetPointerValue(&addr_type) : GetAddressOf(true, &addr_type);
|
lldb::addr_t addr = is_pointer_type ? GetPointerValue(&addr_type) : GetAddressOf(true, &addr_type);
|
||||||
|
|
||||||
switch (addr_type)
|
switch (addr_type)
|
||||||
{
|
{
|
||||||
@@ -988,9 +984,15 @@ ValueObject::GetPointeeData (DataExtractor& data,
|
|||||||
break;
|
break;
|
||||||
case eAddressTypeHost:
|
case eAddressTypeHost:
|
||||||
{
|
{
|
||||||
heap_buf_ptr->CopyData((uint8_t*)(addr + offset), bytes);
|
ClangASTType valobj_type(ast, GetClangType());
|
||||||
data.SetData(data_sp);
|
uint64_t max_bytes = valobj_type.GetClangTypeByteSize();
|
||||||
return bytes;
|
if (max_bytes > offset)
|
||||||
|
{
|
||||||
|
size_t bytes_read = std::min<uint64_t>(max_bytes - offset, bytes);
|
||||||
|
heap_buf_ptr->CopyData((uint8_t*)(addr + offset), bytes_read);
|
||||||
|
data.SetData(data_sp);
|
||||||
|
return bytes_read;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case eAddressTypeInvalid:
|
case eAddressTypeInvalid:
|
||||||
@@ -1031,7 +1033,7 @@ strlen_or_inf (const char* str,
|
|||||||
while(*str)
|
while(*str)
|
||||||
{
|
{
|
||||||
len++;str++;
|
len++;str++;
|
||||||
if (len > maxlen)
|
if (len >= maxlen)
|
||||||
return maxlen_value;
|
return maxlen_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1053,9 +1055,7 @@ ValueObject::ReadPointedString (Stream& s,
|
|||||||
|
|
||||||
clang_type_t clang_type = GetClangType();
|
clang_type_t clang_type = GetClangType();
|
||||||
clang_type_t elem_or_pointee_clang_type;
|
clang_type_t elem_or_pointee_clang_type;
|
||||||
const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
|
const Flags type_flags (GetTypeInfo (&elem_or_pointee_clang_type));
|
||||||
GetClangAST(),
|
|
||||||
&elem_or_pointee_clang_type));
|
|
||||||
if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
|
if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
|
||||||
ClangASTContext::IsCharType (elem_or_pointee_clang_type))
|
ClangASTContext::IsCharType (elem_or_pointee_clang_type))
|
||||||
{
|
{
|
||||||
@@ -1383,7 +1383,7 @@ ValueObject::HasSpecialPrintableRepresentation(ValueObjectRepresentationStyle va
|
|||||||
Format custom_format)
|
Format custom_format)
|
||||||
{
|
{
|
||||||
clang_type_t elem_or_pointee_type;
|
clang_type_t elem_or_pointee_type;
|
||||||
Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type));
|
Flags flags(GetTypeInfo(&elem_or_pointee_type));
|
||||||
|
|
||||||
if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
|
if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
|
||||||
&& val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)
|
&& val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)
|
||||||
@@ -1427,7 +1427,7 @@ ValueObject::DumpPrintableRepresentation(Stream& s,
|
|||||||
{
|
{
|
||||||
|
|
||||||
clang_type_t elem_or_pointee_type;
|
clang_type_t elem_or_pointee_type;
|
||||||
Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type));
|
Flags flags(GetTypeInfo(&elem_or_pointee_type));
|
||||||
|
|
||||||
bool allow_special = ((special & ePrintableRepresentationSpecialCasesAllow) == ePrintableRepresentationSpecialCasesAllow);
|
bool allow_special = ((special & ePrintableRepresentationSpecialCasesAllow) == ePrintableRepresentationSpecialCasesAllow);
|
||||||
bool only_special = ((special & ePrintableRepresentationSpecialCasesOnly) == ePrintableRepresentationSpecialCasesOnly);
|
bool only_special = ((special & ePrintableRepresentationSpecialCasesOnly) == ePrintableRepresentationSpecialCasesOnly);
|
||||||
@@ -1843,6 +1843,12 @@ ValueObject::GetSyntheticChild (const ConstString &key) const
|
|||||||
return synthetic_child_sp;
|
return synthetic_child_sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
ValueObject::GetTypeInfo (clang_type_t *pointee_or_element_clang_type)
|
||||||
|
{
|
||||||
|
return ClangASTContext::GetTypeInfo (GetClangType(), GetClangAST(), pointee_or_element_clang_type);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ValueObject::IsPointerType ()
|
ValueObject::IsPointerType ()
|
||||||
{
|
{
|
||||||
@@ -1896,10 +1902,11 @@ ValueObject::IsObjCNil ()
|
|||||||
ValueObjectSP
|
ValueObjectSP
|
||||||
ValueObject::GetSyntheticArrayMember (size_t index, bool can_create)
|
ValueObject::GetSyntheticArrayMember (size_t index, bool can_create)
|
||||||
{
|
{
|
||||||
if (IsArrayType())
|
const uint32_t type_info = GetTypeInfo ();
|
||||||
|
if (type_info & ClangASTContext::eTypeIsArray)
|
||||||
return GetSyntheticArrayMemberFromArray(index, can_create);
|
return GetSyntheticArrayMemberFromArray(index, can_create);
|
||||||
|
|
||||||
if (IsPointerType())
|
if (type_info & ClangASTContext::eTypeIsPointer)
|
||||||
return GetSyntheticArrayMemberFromPointer(index, can_create);
|
return GetSyntheticArrayMemberFromPointer(index, can_create);
|
||||||
|
|
||||||
return ValueObjectSP();
|
return ValueObjectSP();
|
||||||
|
|||||||
@@ -1200,6 +1200,12 @@ ClangASTType::DumpSummary
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
ClangASTType::GetClangTypeByteSize ()
|
||||||
|
{
|
||||||
|
return (GetClangTypeBitWidth (m_ast, m_type) + 7) / 8;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
ClangASTType::GetClangTypeBitWidth ()
|
ClangASTType::GetClangTypeBitWidth ()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user