* readelf.c (decode_location_expression): Loop through multiple
authorJason Merrill <jason@redhat.com>
Fri, 7 Apr 2000 00:16:45 +0000 (00:16 +0000)
committerJason Merrill <jason@redhat.com>
Fri, 7 Apr 2000 00:16:45 +0000 (00:16 +0000)
        operations.
        (read_and_display_attr): Pass in length.

binutils/ChangeLog
binutils/readelf.c

index e5cc250463c21f9c30e86c7ac01d007e04c7077f..2bbfef48ebee66c6738af45a167915d591f82433 100644 (file)
@@ -1,4 +1,8 @@
-2000-04-06  Jason Merrill  <jason@casey.cygnus.com>
+2000-04-06  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * readelf.c (decode_location_expression): Loop through multiple
+       operations.
+       (read_and_display_attr): Pass in length.
 
        * readelf.c (read_and_display_attr): Add CU offset to references.
        (display_debug_info): Pass it in.
index ab9f92bf7bdf272763c0d785322ecdc9bc5565cd..f4c47f4342d542fdd108619a8a8bc79cff777a63 100644 (file)
@@ -212,7 +212,7 @@ static void               add_abbrev                  PARAMS ((unsigned long, un
 static void               add_abbrev_attr             PARAMS ((unsigned long, unsigned long));
 static unsigned char *    read_and_display_attr       PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long, unsigned long));
 static unsigned char *    display_block               PARAMS ((unsigned char *, unsigned long));
-static void               decode_location_expression  PARAMS ((unsigned char *, unsigned int));
+static void               decode_location_expression  PARAMS ((unsigned char *, unsigned int, unsigned long));
 static void              request_dump                PARAMS ((unsigned int, char));
 static const char *       get_elf_class               PARAMS ((unsigned char));
 static const char *       get_data_encoding           PARAMS ((unsigned char));
@@ -5596,465 +5596,310 @@ display_block (data, length)
 }
 
 static void
-decode_location_expression (data, pointer_size)
+decode_location_expression (data, pointer_size, length)
      unsigned char * data;
      unsigned int    pointer_size;
+     unsigned long length;
 {
-  unsigned char op;
+  unsigned op;
   int           bytes_read;
   unsigned long uvalue;
+  unsigned char *end = data + length;
 
-  op = * data ++;
-
-  switch (op)
+  while (data < end)
     {
-    case DW_OP_addr:
-      printf ("DW_OP_addr: %lx", (unsigned long) byte_get (data, pointer_size));
-      break;
-    case DW_OP_deref:
-      printf ("DW_OP_deref");
-      break;
-    case DW_OP_const1u:
-      printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data, 1));
-      break;
-    case DW_OP_const1s:
-      printf ("DW_OP_const1s: %ld", (long) byte_get (data, 1));
-      break;
-    case DW_OP_const2u:
-      printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
-      break;
-    case DW_OP_const2s:
-      printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
-      break;
-    case DW_OP_const4u:
-      printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
-      break;
-    case DW_OP_const4s:
-      printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
-      break;
-    case DW_OP_const8u:
-      printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
-             (unsigned long) byte_get (data + 4, 4));
-      break;
-    case DW_OP_const8s:
-      printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
-             (long) byte_get (data + 4, 4));
-      break;
-    case DW_OP_constu:
-      printf ("DW_OP_constu: %lu", read_leb128 (data, NULL, 0));
-      break;
-    case DW_OP_consts:
-      printf ("DW_OP_consts: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_dup:
-      printf ("DW_OP_dup");
-      break;
-    case DW_OP_drop:
-      printf ("DW_OP_drop");
-      break;
-    case DW_OP_over:
-      printf ("DW_OP_over");
-      break;
-    case DW_OP_pick:
-      printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data, 1));
-      break;
-    case DW_OP_swap:
-      printf ("DW_OP_swap");
-      break;
-    case DW_OP_rot:
-      printf ("DW_OP_rot");
-      break;
-    case DW_OP_xderef:
-      printf ("DW_OP_xderef");
-      break;
-    case DW_OP_abs:
-      printf ("DW_OP_abs");
-      break;
-    case DW_OP_and:
-      printf ("DW_OP_and");
-      break;
-    case DW_OP_div:
-      printf ("DW_OP_div");
-      break;
-    case DW_OP_minus:
-      printf ("DW_OP_minus");
-      break;
-    case DW_OP_mod:
-      printf ("DW_OP_mod");
-      break;
-    case DW_OP_mul:
-      printf ("DW_OP_mul");
-      break;
-    case DW_OP_neg:
-      printf ("DW_OP_neg");
-      break;
-    case DW_OP_not:
-      printf ("DW_OP_not");
-      break;
-    case DW_OP_or:
-      printf ("DW_OP_or");
-      break;
-    case DW_OP_plus:
-      printf ("DW_OP_plus");
-      break;
-    case DW_OP_plus_uconst:
-      printf ("DW_OP_plus_uconst: %lu", read_leb128 (data, NULL, 0));
-      break;
-    case DW_OP_shl:
-      printf ("DW_OP_shl");
-      break;
-    case DW_OP_shr:
-      printf ("DW_OP_shr");
-      break;
-    case DW_OP_shra:
-      printf ("DW_OP_shra");
-      break;
-    case DW_OP_xor:
-      printf ("DW_OP_xor");
-      break;
-    case DW_OP_bra:
-      printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
-      break;
-    case DW_OP_eq:
-      printf ("DW_OP_eq");
-      break;
-    case DW_OP_ge:
-      printf ("DW_OP_ge");
-      break;
-    case DW_OP_gt:
-      printf ("DW_OP_gt");
-      break;
-    case DW_OP_le:
-      printf ("DW_OP_le");
-      break;
-    case DW_OP_lt:
-      printf ("DW_OP_lt");
-      break;
-    case DW_OP_ne:
-      printf ("DW_OP_ne");
-      break;
-    case DW_OP_skip:
-      printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
-      break;
-    case DW_OP_lit0:
-      printf ("DW_OP_lit0");
-      break;
-    case DW_OP_lit1:
-      printf ("DW_OP_lit1");
-      break;
-    case DW_OP_lit2:
-      printf ("DW_OP_lit2");
-      break;
-    case DW_OP_lit3:
-      printf ("DW_OP_lit3");
-      break;
-    case DW_OP_lit4:
-      printf ("DW_OP_lit4");
-      break;
-    case DW_OP_lit5:
-      printf ("DW_OP_lit5");
-      break;
-    case DW_OP_lit6:
-      printf ("DW_OP_lit6");
-      break;
-    case DW_OP_lit7:
-      printf ("DW_OP_lit7");
-      break;
-    case DW_OP_lit8:
-      printf ("DW_OP_lit8");
-      break;
-    case DW_OP_lit9:
-      printf ("DW_OP_lit9");
-      break;
-    case DW_OP_lit10:
-      printf ("DW_OP_lit10");
-      break;
-    case DW_OP_lit11:
-      printf ("DW_OP_lit11");
-      break;
-    case DW_OP_lit12:
-      printf ("DW_OP_lit12");
-      break;
-    case DW_OP_lit13:
-      printf ("DW_OP_lit13");
-      break;
-    case DW_OP_lit14:
-      printf ("DW_OP_lit14");
-      break;
-    case DW_OP_lit15:
-      printf ("DW_OP_lit15");
-      break;
-    case DW_OP_lit16:
-      printf ("DW_OP_lit16");
-      break;
-    case DW_OP_lit17:
-      printf ("DW_OP_lit17");
-      break;
-    case DW_OP_lit18:
-      printf ("DW_OP_lit18");
-      break;
-    case DW_OP_lit19:
-      printf ("DW_OP_lit19");
-      break;
-    case DW_OP_lit20:
-      printf ("DW_OP_lit20");
-      break;
-    case DW_OP_lit21:
-      printf ("DW_OP_lit21");
-      break;
-    case DW_OP_lit22:
-      printf ("DW_OP_lit22");
-      break;
-    case DW_OP_lit23:
-      printf ("DW_OP_lit23");
-      break;
-    case DW_OP_lit24:
-      printf ("DW_OP_lit24");
-      break;
-    case DW_OP_lit25:
-      printf ("DW_OP_lit25");
-      break;
-    case DW_OP_lit26:
-      printf ("DW_OP_lit26");
-      break;
-    case DW_OP_lit27:
-      printf ("DW_OP_lit27");
-      break;
-    case DW_OP_lit28:
-      printf ("DW_OP_lit28");
-      break;
-    case DW_OP_lit29:
-      printf ("DW_OP_lit29");
-      break;
-    case DW_OP_lit30:
-      printf ("DW_OP_lit30");
-      break;
-    case DW_OP_lit31:
-      printf ("DW_OP_lit31");
-      break;
-    case DW_OP_reg0:
-      printf ("DW_OP_reg0");
-      break;
-    case DW_OP_reg1:
-      printf ("DW_OP_reg1");
-      break;
-    case DW_OP_reg2:
-      printf ("DW_OP_reg2");
-      break;
-    case DW_OP_reg3:
-      printf ("DW_OP_reg3");
-      break;
-    case DW_OP_reg4:
-      printf ("DW_OP_reg4");
-      break;
-    case DW_OP_reg5:
-      printf ("DW_OP_reg5");
-      break;
-    case DW_OP_reg6:
-      printf ("DW_OP_reg6");
-      break;
-    case DW_OP_reg7:
-      printf ("DW_OP_reg7");
-      break;
-    case DW_OP_reg8:
-      printf ("DW_OP_reg8");
-      break;
-    case DW_OP_reg9:
-      printf ("DW_OP_reg9");
-      break;
-    case DW_OP_reg10:
-      printf ("DW_OP_reg10");
-      break;
-    case DW_OP_reg11:
-      printf ("DW_OP_reg11");
-      break;
-    case DW_OP_reg12:
-      printf ("DW_OP_reg12");
-      break;
-    case DW_OP_reg13:
-      printf ("DW_OP_reg13");
-      break;
-    case DW_OP_reg14:
-      printf ("DW_OP_reg14");
-      break;
-    case DW_OP_reg15:
-      printf ("DW_OP_reg15");
-      break;
-    case DW_OP_reg16:
-      printf ("DW_OP_reg16");
-      break;
-    case DW_OP_reg17:
-      printf ("DW_OP_reg17");
-      break;
-    case DW_OP_reg18:
-      printf ("DW_OP_reg18");
-      break;
-    case DW_OP_reg19:
-      printf ("DW_OP_reg19");
-      break;
-    case DW_OP_reg20:
-      printf ("DW_OP_reg20");
-      break;
-    case DW_OP_reg21:
-      printf ("DW_OP_reg21");
-      break;
-    case DW_OP_reg22:
-      printf ("DW_OP_reg22");
-      break;
-    case DW_OP_reg23:
-      printf ("DW_OP_reg23");
-      break;
-    case DW_OP_reg24:
-      printf ("DW_OP_reg24");
-      break;
-    case DW_OP_reg25:
-      printf ("DW_OP_reg25");
-      break;
-    case DW_OP_reg26:
-      printf ("DW_OP_reg26");
-      break;
-    case DW_OP_reg27:
-      printf ("DW_OP_reg27");
-      break;
-    case DW_OP_reg28:
-      printf ("DW_OP_reg28");
-      break;
-    case DW_OP_reg29:
-      printf ("DW_OP_reg29");
-      break;
-    case DW_OP_reg30:
-      printf ("DW_OP_reg30");
-      break;
-    case DW_OP_reg31:
-      printf ("DW_OP_reg31");
-      break;
-    case DW_OP_breg0:
-      printf ("DW_OP_breg0: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg1:
-      printf ("DW_OP_breg1: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg2:
-      printf ("DW_OP_breg2: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg3:
-      printf ("DW_OP_breg3: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg4:
-      printf ("DW_OP_breg4: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg5:
-      printf ("DW_OP_breg5: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg6:
-      printf ("DW_OP_breg6: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg7:
-      printf ("DW_OP_breg7: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg8:
-      printf ("DW_OP_breg8: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg9:
-      printf ("DW_OP_breg9: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg10:
-      printf ("DW_OP_breg10: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg11:
-      printf ("DW_OP_breg11: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg12:
-      printf ("DW_OP_breg12: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg13:
-      printf ("DW_OP_breg13: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg14:
-      printf ("DW_OP_breg14: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg15:
-      printf ("DW_OP_breg15: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg16:
-      printf ("DW_OP_breg16: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg17:
-      printf ("DW_OP_breg17: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg18:
-      printf ("DW_OP_breg18: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg19:
-      printf ("DW_OP_breg19: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg20:
-      printf ("DW_OP_breg20: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg21:
-      printf ("DW_OP_breg21: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg22:
-      printf ("DW_OP_breg22: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg23:
-      printf ("DW_OP_breg23: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg24:
-      printf ("DW_OP_breg24: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg25:
-      printf ("DW_OP_breg25: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg26:
-      printf ("DW_OP_breg26: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg27:
-      printf ("DW_OP_breg27: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg28:
-      printf ("DW_OP_breg28: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg29:
-      printf ("DW_OP_breg29: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg30:
-      printf ("DW_OP_breg30: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_breg31:
-      printf ("DW_OP_breg31: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_regx:
-      printf ("DW_OP_regx: %lu", read_leb128 (data, NULL, 0));
-      break;
-    case DW_OP_fbreg:
-      printf ("DW_OP_fbreg: %ld", read_leb128 (data, NULL, 1));
-      break;
-    case DW_OP_bregx:
-      uvalue = read_leb128 (data, &bytes_read, 0);
-      printf ("DW_OP_bregx: %lu %ld", uvalue,
-             read_leb128 (data + bytes_read, NULL, 1));
-      break;
-    case DW_OP_piece:
-      printf ("DW_OP_piece: %lu", read_leb128 (data, NULL, 0));
-      break;
-    case DW_OP_deref_size:
-      printf ("DW_OP_deref_size: %ld", (long) byte_get (data, 1));
-      break;
-    case DW_OP_xderef_size:
-      printf ("DW_OP_xderef_size: %ld", (long) byte_get (data, 1));
-      break;
-    case DW_OP_nop:
-      printf ("DW_OP_nop");
-      break;
+      op = * data ++;
 
-    default:
-      if (op >= DW_OP_lo_user
-         && op <= DW_OP_hi_user)
-       printf (_("(User defined location op)"));
-      else
-       printf (_("(Unknown location op)"));
-      break;
+      switch (op)
+       {
+       case DW_OP_addr:
+         printf ("DW_OP_addr: %lx",
+                 (unsigned long) byte_get (data, pointer_size));
+         data += pointer_size;
+         break;
+       case DW_OP_deref:
+         printf ("DW_OP_deref");
+         break;
+       case DW_OP_const1u:
+         printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
+         break;
+       case DW_OP_const1s:
+         printf ("DW_OP_const1s: %ld", (long) byte_get (data++, 1));
+         break;
+       case DW_OP_const2u:
+         printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
+         data += 2;
+         break;
+       case DW_OP_const2s:
+         printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
+         data += 2;
+         break;
+       case DW_OP_const4u:
+         printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
+         data += 4;
+         break;
+       case DW_OP_const4s:
+         printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
+         data += 4;
+         break;
+       case DW_OP_const8u:
+         printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
+                 (unsigned long) byte_get (data + 4, 4));
+         data += 8;
+         break;
+       case DW_OP_const8s:
+         printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
+                 (long) byte_get (data + 4, 4));
+         data += 8;
+         break;
+       case DW_OP_constu:
+         printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
+         data += bytes_read;
+         break;
+       case DW_OP_consts:
+         printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
+         data += bytes_read;
+         break;
+       case DW_OP_dup:
+         printf ("DW_OP_dup");
+         break;
+       case DW_OP_drop:
+         printf ("DW_OP_drop");
+         break;
+       case DW_OP_over:
+         printf ("DW_OP_over");
+         break;
+       case DW_OP_pick:
+         printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
+         break;
+       case DW_OP_swap:
+         printf ("DW_OP_swap");
+         break;
+       case DW_OP_rot:
+         printf ("DW_OP_rot");
+         break;
+       case DW_OP_xderef:
+         printf ("DW_OP_xderef");
+         break;
+       case DW_OP_abs:
+         printf ("DW_OP_abs");
+         break;
+       case DW_OP_and:
+         printf ("DW_OP_and");
+         break;
+       case DW_OP_div:
+         printf ("DW_OP_div");
+         break;
+       case DW_OP_minus:
+         printf ("DW_OP_minus");
+         break;
+       case DW_OP_mod:
+         printf ("DW_OP_mod");
+         break;
+       case DW_OP_mul:
+         printf ("DW_OP_mul");
+         break;
+       case DW_OP_neg:
+         printf ("DW_OP_neg");
+         break;
+       case DW_OP_not:
+         printf ("DW_OP_not");
+         break;
+       case DW_OP_or:
+         printf ("DW_OP_or");
+         break;
+       case DW_OP_plus:
+         printf ("DW_OP_plus");
+         break;
+       case DW_OP_plus_uconst:
+         printf ("DW_OP_plus_uconst: %lu",
+                 read_leb128 (data, &bytes_read, 0));
+         data += bytes_read;
+         break;
+       case DW_OP_shl:
+         printf ("DW_OP_shl");
+         break;
+       case DW_OP_shr:
+         printf ("DW_OP_shr");
+         break;
+       case DW_OP_shra:
+         printf ("DW_OP_shra");
+         break;
+       case DW_OP_xor:
+         printf ("DW_OP_xor");
+         break;
+       case DW_OP_bra:
+         printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
+         data += 2;
+         break;
+       case DW_OP_eq:
+         printf ("DW_OP_eq");
+         break;
+       case DW_OP_ge:
+         printf ("DW_OP_ge");
+         break;
+       case DW_OP_gt:
+         printf ("DW_OP_gt");
+         break;
+       case DW_OP_le:
+         printf ("DW_OP_le");
+         break;
+       case DW_OP_lt:
+         printf ("DW_OP_lt");
+         break;
+       case DW_OP_ne:
+         printf ("DW_OP_ne");
+         break;
+       case DW_OP_skip:
+         printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
+         data += 2;
+         break;
+
+       case DW_OP_lit0:
+       case DW_OP_lit1:
+       case DW_OP_lit2:
+       case DW_OP_lit3:
+       case DW_OP_lit4:
+       case DW_OP_lit5:
+       case DW_OP_lit6:
+       case DW_OP_lit7:
+       case DW_OP_lit8:
+       case DW_OP_lit9:
+       case DW_OP_lit10:
+       case DW_OP_lit11:
+       case DW_OP_lit12:
+       case DW_OP_lit13:
+       case DW_OP_lit14:
+       case DW_OP_lit15:
+       case DW_OP_lit16:
+       case DW_OP_lit17:
+       case DW_OP_lit18:
+       case DW_OP_lit19:
+       case DW_OP_lit20:
+       case DW_OP_lit21:
+       case DW_OP_lit22:
+       case DW_OP_lit23:
+       case DW_OP_lit24:
+       case DW_OP_lit25:
+       case DW_OP_lit26:
+       case DW_OP_lit27:
+       case DW_OP_lit28:
+       case DW_OP_lit29:
+       case DW_OP_lit30:
+       case DW_OP_lit31:
+         printf ("DW_OP_lit%d", op - DW_OP_lit0);
+         break;
+
+       case DW_OP_reg0:
+       case DW_OP_reg1:
+       case DW_OP_reg2:
+       case DW_OP_reg3:
+       case DW_OP_reg4:
+       case DW_OP_reg5:
+       case DW_OP_reg6:
+       case DW_OP_reg7:
+       case DW_OP_reg8:
+       case DW_OP_reg9:
+       case DW_OP_reg10:
+       case DW_OP_reg11:
+       case DW_OP_reg12:
+       case DW_OP_reg13:
+       case DW_OP_reg14:
+       case DW_OP_reg15:
+       case DW_OP_reg16:
+       case DW_OP_reg17:
+       case DW_OP_reg18:
+       case DW_OP_reg19:
+       case DW_OP_reg20:
+       case DW_OP_reg21:
+       case DW_OP_reg22:
+       case DW_OP_reg23:
+       case DW_OP_reg24:
+       case DW_OP_reg25:
+       case DW_OP_reg26:
+       case DW_OP_reg27:
+       case DW_OP_reg28:
+       case DW_OP_reg29:
+       case DW_OP_reg30:
+       case DW_OP_reg31:
+         printf ("DW_OP_reg%d", op - DW_OP_reg0);
+         break;
+
+       case DW_OP_breg0:
+       case DW_OP_breg1:
+       case DW_OP_breg2:
+       case DW_OP_breg3:
+       case DW_OP_breg4:
+       case DW_OP_breg5:
+       case DW_OP_breg6:
+       case DW_OP_breg7:
+       case DW_OP_breg8:
+       case DW_OP_breg9:
+       case DW_OP_breg10:
+       case DW_OP_breg11:
+       case DW_OP_breg12:
+       case DW_OP_breg13:
+       case DW_OP_breg14:
+       case DW_OP_breg15:
+       case DW_OP_breg16:
+       case DW_OP_breg17:
+       case DW_OP_breg18:
+       case DW_OP_breg19:
+       case DW_OP_breg20:
+       case DW_OP_breg21:
+       case DW_OP_breg22:
+       case DW_OP_breg23:
+       case DW_OP_breg24:
+       case DW_OP_breg25:
+       case DW_OP_breg26:
+       case DW_OP_breg27:
+       case DW_OP_breg28:
+       case DW_OP_breg29:
+       case DW_OP_breg30:
+       case DW_OP_breg31:
+         printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
+                 read_leb128 (data, &bytes_read, 1));
+         data += bytes_read;
+         break;
+
+       case DW_OP_regx:
+         printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
+         data += bytes_read;
+         break;
+       case DW_OP_fbreg:
+         printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
+         data += bytes_read;
+         break;
+       case DW_OP_bregx:
+         uvalue = read_leb128 (data, &bytes_read, 0);
+         data += bytes_read;
+         printf ("DW_OP_bregx: %lu %ld", uvalue,
+                 read_leb128 (data, &bytes_read, 1));
+         data += bytes_read;
+         break;
+       case DW_OP_piece:
+         printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
+         data += bytes_read;
+         break;
+       case DW_OP_deref_size:
+         printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
+         break;
+       case DW_OP_xderef_size:
+         printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
+         break;
+       case DW_OP_nop:
+         printf ("DW_OP_nop");
+         break;
+
+       default:
+         if (op >= DW_OP_lo_user
+             && op <= DW_OP_hi_user)
+           printf (_("(User defined location op)"));
+         else
+           printf (_("(Unknown location op)"));
+         /* No way to tell where the next op is, so just bail.  */
+         return;
+       }
     }
 }
 
@@ -6153,28 +5998,24 @@ read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
       uvalue = read_leb128 (data, & bytes_read, 0);
       block_start = data + bytes_read;
       data = display_block (block_start, uvalue);
-      uvalue = * block_start;
       break;
 
     case DW_FORM_block1:
       uvalue = byte_get (data, 1);
       block_start = data + 1;
       data = display_block (block_start, uvalue);
-      uvalue = * block_start;
       break;
 
     case DW_FORM_block2:
       uvalue = byte_get (data, 2);
       block_start = data + 2;
       data = display_block (block_start, uvalue);
-      uvalue = * block_start;
       break;
 
     case DW_FORM_block4:
       uvalue = byte_get (data, 4);
       block_start = data + 4;
       data = display_block (block_start, uvalue);
-      uvalue = * block_start;
       break;
 
     case DW_FORM_strp:
@@ -6204,11 +6045,6 @@ read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
        }
       break;
 
-    case DW_AT_frame_base:
-      if (uvalue >= DW_OP_reg0 && uvalue <= DW_OP_reg31)
-       printf ("(reg %ld)", uvalue - DW_OP_reg0);
-      break;
-
     case DW_AT_language:
       switch (uvalue)
        {
@@ -6305,12 +6141,16 @@ read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
        }
       break;
 
+    case DW_AT_frame_base:
     case DW_AT_location:
     case DW_AT_data_member_location:
     case DW_AT_vtable_elem_location:
-      printf ("(");
-      decode_location_expression (block_start, pointer_size);
-      printf (")");
+      if (block_start)
+       {
+         printf ("(");
+         decode_location_expression (block_start, pointer_size, uvalue);
+         printf (")");
+       }
       break;
 
     default: