Commits

Wez Furlong  committed b40b4e0

more fun with bitfields; handle bigger bitfields properly

  • Participants
  • Parent commits b523222
  • Branches onering

Comments (0)

Files changed (3)

File dwarf-read.c

       if (!gimli_dwarf_die_get_uint64_t_attr(die, DW_AT_byte_size, &bytesize)) {
         bytesize = gimli_type_size(memt)/8;
       }
+//printf("bitfield: offset=%" PRIu64 " from MSB, bytesize=%" PRIu64 " bits=%" PRIu64 "\n", offset, bytesize, size);
 #if !WORDS_BIGENDIAN
-      offset = ((bytesize * 8) - 1) - offset;
+      offset = (bytesize * 8) - (offset + size);
+//printf("    -> offset=%" PRIu64 " from lowest byte\n", offset);
 #endif
 
     } else {
 
   if (bytes > 8 || (bits % 8 != 0) || (bytes & (bytes - 1)) != 0) {
     /* it's a bitfield */
+    uint64_t mask = (1ULL << bits) - 1;
     uint8_t bitoff = offset - (8*(offset/8));
-    uint8_t shift =
+    uint8_t shift;
+
+    /* how many bytes we're going to read. */
+    bytes = (bits + bitoff + 7) / 8;
+
+    /* shift is how far we need to shift to make it line up in
+     * the u64 that we're storing it into */
 #if WORDS_BIGENDIAN
-        (sizeof(u.u64)*8) - (bitoff + bits);
+    shift = (sizeof(u.u64)*8) - (bitoff + bits);
 #else
-        bitoff - (bits - 1);
+    shift = bitoff;
 #endif
-    uint64_t mask = (1ULL << bits) - 1;
-    bytes = (bits + 7) / 8;
 
 //printf("bitfield read from " PTRFMT " bits=%" PRIu64 " bytes=%" PRIu64 " offset=%" PRIu64 " bitoff=%d shift=%d mask=%" PRIx64 "\n", addr, bits, bytes, offset, bitoff, shift, mask);
     if (bytes > sizeof(u.u64)) {
   unsigned bit1:1;
   unsigned bit2:1;
   signed moo:5;
+  unsigned bigbits:18;
   double aftermoo;
   int (*func)(int, ...);
   int arr[4];
   d.bit1 = 1;
   d.bit2 = 0;
   d.moo = 13;
+  d.bigbits = 0x29999;
   d.aftermoo = 4.5;
   d.lone.a = 3;
   d.lone.b = 4;