Commits

Anonymous committed dd02a16

fixup bitfield processing for big-endian systems.
avoid funky alignment problems on sparc.

Comments (0)

Files changed (2)

       /* convert to bit offset from start of storage */
       /* FIXME: check this for big endian systems */
       if (!gimli_dwarf_die_get_uint64_t_attr(die, DW_AT_byte_size, &bytesize)) {
-        bytesize = gimli_type_size(memt);
+        bytesize = gimli_type_size(memt)/8;
       }
       offset = ((bytesize * 8) - 1) - offset;
 
 
   if (bytes > 8 || (bits % 8 != 0) || (bytes & (bytes - 1)) != 0) {
     /* it's a bitfield */
-    uint8_t shift = offset - (bits - 1);
+    uint8_t bitoff = offset - (8*(offset/8));
+    uint8_t shift =
+#if WORDS_BIGENDIAN
+        (sizeof(u.u64)*8) - (bitoff + bits);
+#else
+        bitoff - (bits - 1);
+#endif
     uint64_t mask = (1ULL << bits) - 1;
+    bytes = (bits + 7) / 8;
 
-    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)) {
       printf("??? <invalid bitfield size %" PRIu64 ">", bits);
       return;
         bytes, addr);
       return;
     }
-    if (offset % 8 != 0) {
-      /* not at a byte boundary, so shift it down to the lowest bits */
-      u.u64 >>= shift;
-    }
+//printf("READ: 0x%" PRIx64 "\n", u.u64);
+    u.u64 >>= shift;
     u.u64 &= mask;
 
     bytes = 8;
   uint64_t off = sdata->offset;
   int depth = sdata->depth;
   char addrkey[64];
-  int dummy;
   uint32_t i;
   struct print_data data = *sdata;
   int is_struct;
 
 static void print_pointer(struct print_data *data, gimli_type_t t)
 {
+  void *dummy;
   gimli_type_t target = gimli_type_resolve(gimli_type_follow_pointer(t));
   struct gimli_type_encoding enc;
   void *tptr;
   gimli_addr_t addrsave = data->addr;
   int depth = data->depth;
   char addrkey[64];
-  int dummy;
   char namebuf[1024];
   const char *symname;
   struct print_data savdata = *data;
   }
 
   snprintf(addrkey, sizeof(addrkey), "%p:%" PRIx64, target, data->addr);
-  if (gimli_hash_find(derefd, addrkey, (void**)&dummy)) {
+  if (gimli_hash_find(derefd, addrkey, &dummy)) {
     printf(" " PTRFMT " [deref'd above]", ptr);
     return;
   }
   int indent = 4 * (data->depth + 1);
   gimli_addr_t addr;
   char addrkey[64];
-  int dummy;
+  void *dummy;
 
   if (data->frame) {
 
       case GIMLI_K_UNION:
       case GIMLI_K_STRUCT:
         snprintf(addrkey, sizeof(addrkey), "%p:%" PRIx64, t, addr);
-        if (gimli_hash_find(derefd, addrkey, (void**)&dummy)) {
+        if (gimli_hash_find(derefd, addrkey, &dummy)) {
           printf(" " PTRFMT " [deref'd above]\n", addr);
           return;
         }