Change DataExtractor's ReadInt* and ReadSwapInt* routines, as well as

GetU32 and GetU64, to use memcpy to copy bytes into a local buffer instead
of having a (uint64_t *) etc local variable, pointing to the address, and
dereferencing it.  If compiled on a CPU where data alignment is required 
(e.g. the LDM instruction on armv7) and we try to GetU64 out of a mmap'ed 
DWARF file, that 8 byte quantity may not be world aligned and the program
can get an unaligned memory access fault.

<rdar://problem/15849231> 

llvm-svn: 200069
This commit is contained in:
Jason Molenda 2014-01-25 05:12:35 +00:00
parent 4411528461
commit bbef401896
1 changed files with 52 additions and 16 deletions

View File

@ -46,69 +46,97 @@ using namespace lldb_private;
static inline uint16_t
ReadInt16(const unsigned char* ptr, offset_t offset)
{
return *(uint16_t *)(ptr + offset);
uint16_t value;
memcpy (&value, ptr + offset, 2);
return value;
}
static inline uint32_t
ReadInt32 (const unsigned char* ptr, offset_t offset)
{
return *(uint32_t *)(ptr + offset);
uint32_t value;
memcpy (&value, ptr + offset, 4);
return value;
}
static inline uint64_t
ReadInt64(const unsigned char* ptr, offset_t offset)
{
return *(uint64_t *)(ptr + offset);
uint64_t value;
memcpy (&value, ptr + offset, 8);
return value;
}
static inline uint16_t
ReadInt16(const void* ptr)
{
return *(uint16_t *)(ptr);
uint16_t value;
memcpy (&value, ptr, 2);
return value;
}
static inline uint32_t
ReadInt32 (const void* ptr)
{
return *(uint32_t *)(ptr);
uint32_t value;
memcpy (&value, ptr, 4);
return value;
}
static inline uint64_t
ReadInt64(const void* ptr)
{
return *(uint64_t *)(ptr);
uint64_t value;
memcpy (&value, ptr, 8);
return value;
}
static inline uint16_t
ReadSwapInt16(const unsigned char* ptr, offset_t offset)
{
return llvm::ByteSwap_16(*(uint16_t *)(ptr + offset));
uint16_t value;
memcpy (&value, ptr + offset, 2);
return llvm::ByteSwap_16(value);
}
static inline uint32_t
ReadSwapInt32 (const unsigned char* ptr, offset_t offset)
{
return llvm::ByteSwap_32(*(uint32_t *)(ptr + offset));
uint32_t value;
memcpy (&value, ptr + offset, 4);
return llvm::ByteSwap_32(value);
}
static inline uint64_t
ReadSwapInt64(const unsigned char* ptr, offset_t offset)
{
return llvm::ByteSwap_64(*(uint64_t *)(ptr + offset));
uint64_t value;
memcpy (&value, ptr + offset, 8);
return llvm::ByteSwap_64(value);
}
static inline uint16_t
ReadSwapInt16(const void* ptr)
{
return llvm::ByteSwap_16(*(uint16_t *)(ptr));
uint16_t value;
memcpy (&value, ptr, 2);
return llvm::ByteSwap_16(value);
}
static inline uint32_t
ReadSwapInt32 (const void* ptr)
{
return llvm::ByteSwap_32(*(uint32_t *)(ptr));
uint32_t value;
memcpy (&value, ptr, 4);
return llvm::ByteSwap_32(value);
}
static inline uint64_t
ReadSwapInt64(const void* ptr)
{
return llvm::ByteSwap_64(*(uint64_t *)(ptr));
uint64_t value;
memcpy (&value, ptr, 8);
return llvm::ByteSwap_64(value);
}
#define NON_PRINTABLE_CHAR '.'
@ -503,13 +531,17 @@ uint32_t
DataExtractor::GetU32 (offset_t *offset_ptr) const
{
uint32_t val = 0;
const uint32_t *data = (const uint32_t *)GetData (offset_ptr, sizeof(val));
const uint8_t *data = (const uint8_t *)GetData (offset_ptr, sizeof(val));
if (data)
{
if (m_byte_order != lldb::endian::InlHostByteOrder())
{
val = ReadSwapInt32 (data);
}
else
val = *data;
{
memcpy (&val, data, 4);
}
}
return val;
}
@ -562,13 +594,17 @@ uint64_t
DataExtractor::GetU64 (offset_t *offset_ptr) const
{
uint64_t val = 0;
const uint64_t *data = (const uint64_t *)GetData (offset_ptr, sizeof(val));
const uint8_t *data = (const uint8_t *)GetData (offset_ptr, sizeof(val));
if (data)
{
if (m_byte_order != lldb::endian::InlHostByteOrder())
{
val = ReadSwapInt64 (data);
}
else
val = *data;
{
memcpy (&val, data, 8);
}
}
return val;
}