uweigand updated this revision to Diff 53605.
uweigand added a comment.

Updated interface documentation in DataExtractor.h.

Added unit test case for the DataExtractor::GetMaxU64Bitfield and 
GetMaxS64Bitfield routines.

Retested on System z and Intel.


http://reviews.llvm.org/D18982

Files:
  include/lldb/Core/DataExtractor.h
  source/Core/DataExtractor.cpp
  source/Core/ValueObject.cpp
  unittests/Core/CMakeLists.txt
  unittests/Core/DataExtractorTest.cpp

Index: unittests/Core/DataExtractorTest.cpp
===================================================================
--- unittests/Core/DataExtractorTest.cpp
+++ unittests/Core/DataExtractorTest.cpp
@@ -0,0 +1,39 @@
+//===-- 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));
+}
Index: unittests/Core/CMakeLists.txt
===================================================================
--- unittests/Core/CMakeLists.txt
+++ unittests/Core/CMakeLists.txt
@@ -1,3 +1,4 @@
 add_lldb_unittest(LLDBCoreTests
+  DataExtractorTest.cpp
   ScalarTest.cpp
   )
Index: source/Core/ValueObject.cpp
===================================================================
--- source/Core/ValueObject.cpp
+++ source/Core/ValueObject.cpp
@@ -2146,15 +2146,19 @@
         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,
                                                                       GetCompilerType(),
                                                                       index_const_str,
                                                                       GetByteSize(),
                                                                       0,
-                                                                      to-from+1,
-                                                                      from,
+                                                                      bit_field_size,
+                                                                      bit_field_offset,
                                                                       false,
                                                                       false,
                                                                       eAddressTypeInvalid,
Index: source/Core/DataExtractor.cpp
===================================================================
--- source/Core/DataExtractor.cpp
+++ source/Core/DataExtractor.cpp
@@ -733,8 +733,11 @@
     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;
@@ -749,8 +752,11 @@
     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
Index: include/lldb/Core/DataExtractor.h
===================================================================
--- include/lldb/Core/DataExtractor.h
+++ include/lldb/Core/DataExtractor.h
@@ -763,8 +763,10 @@
     ///
     /// @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
@@ -805,8 +807,10 @@
     ///
     /// @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
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to