///
/// @param[in] bitfield_bit_offset
/// The bit offset of the bitfield value in the extracted
- /// integer (the number of bits to shift the integer to the
- /// right).
+ /// integer. For little-endian data, this is the offset of
+ /// the LSB of the bitfield from the LSB of the integer.
+ /// For big-endian data, this is the offset of the MSB of the
+ /// bitfield from the MSB of the integer.
///
/// @return
/// The unsigned bitfield integer value that was extracted, or
///
/// @param[in] bitfield_bit_offset
/// The bit offset of the bitfield value in the extracted
- /// integer (the number of bits to shift the integer to the
- /// right).
+ /// integer. For little-endian data, this is the offset of
+ /// the LSB of the bitfield from the LSB of the integer.
+ /// For big-endian data, this is the offset of the MSB of the
+ /// bitfield from the MSB of the integer.
///
/// @return
/// The signed bitfield integer value that was extracted, or
uint64_t uval64 = GetMaxU64 (offset_ptr, size);
if (bitfield_bit_size > 0)
{
- if (bitfield_bit_offset > 0)
- uval64 >>= bitfield_bit_offset;
+ int32_t lsbcount = bitfield_bit_offset;
+ if (m_byte_order == eByteOrderBig)
+ lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;
+ if (lsbcount > 0)
+ uval64 >>= lsbcount;
uint64_t bitfield_mask = ((1ul << bitfield_bit_size) - 1);
if (!bitfield_mask && bitfield_bit_offset == 0 && bitfield_bit_size == 64)
return uval64;
int64_t sval64 = GetMaxS64 (offset_ptr, size);
if (bitfield_bit_size > 0)
{
- if (bitfield_bit_offset > 0)
- sval64 >>= bitfield_bit_offset;
+ int32_t lsbcount = bitfield_bit_offset;
+ if (m_byte_order == eByteOrderBig)
+ lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;
+ if (lsbcount > 0)
+ sval64 >>= lsbcount;
uint64_t bitfield_mask = (((uint64_t)1) << bitfield_bit_size) - 1;
sval64 &= bitfield_mask;
// sign extend if needed
synthetic_child_sp = GetSyntheticChild (index_const_str);
if (!synthetic_child_sp)
{
+ uint32_t bit_field_size = to - from + 1;
+ uint32_t bit_field_offset = from;
+ if (GetDataExtractor().GetByteOrder() == eByteOrderBig)
+ bit_field_offset = GetByteSize() * 8 - bit_field_size - bit_field_offset;
// We haven't made a synthetic array member for INDEX yet, so
// lets make one and cache it for any future reference.
ValueObjectChild *synthetic_child = new ValueObjectChild (*this,
index_const_str,
GetByteSize(),
0,
- to-from+1,
- from,
+ bit_field_size,
+ bit_field_offset,
false,
false,
eAddressTypeInvalid,
add_lldb_unittest(LLDBCoreTests
+ DataExtractorTest.cpp
ScalarTest.cpp
)
--- /dev/null
+//===-- DataExtractorTest.cpp -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
+// Workaround for MSVC standard library bug, which fails to include <thread> when
+// exceptions are disabled.
+#include <eh.h>
+#endif
+
+#include "gtest/gtest.h"
+
+#include "lldb/Core/DataExtractor.h"
+
+using namespace lldb_private;
+
+TEST(DataExtractorTest, GetBitfield)
+{
+ char buffer[] = { 0x01, 0x23, 0x45, 0x67 };
+ DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, sizeof(void *));
+ DataExtractor BE(buffer, sizeof(buffer), lldb::eByteOrderBig, sizeof(void *));
+
+ lldb::offset_t offset;
+
+ offset = 0;
+ ASSERT_EQ(buffer[1], LE.GetMaxU64Bitfield(&offset, sizeof(buffer), 8, 8));
+ offset = 0;
+ ASSERT_EQ(buffer[1], BE.GetMaxU64Bitfield(&offset, sizeof(buffer), 8, 8));
+
+ offset = 0;
+ ASSERT_EQ(buffer[1], LE.GetMaxS64Bitfield(&offset, sizeof(buffer), 8, 8));
+ offset = 0;
+ ASSERT_EQ(buffer[1], BE.GetMaxS64Bitfield(&offset, sizeof(buffer), 8, 8));
+}