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:
Greg Clayton
2013-02-08 22:02:02 +00:00
parent b2f426c40e
commit 2452ab7fa8
6 changed files with 242 additions and 228 deletions

View File

@@ -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
//------------------------------------------------------------------ //------------------------------------------------------------------

View File

@@ -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 ();

View File

@@ -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 ();

View File

@@ -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;
} }

View File

@@ -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();

View File

@@ -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 ()
{ {