Fix readelf --debug-dump=frames-interp output: once a register is given
authorguenther <guenther@openbsd.org>
Sat, 9 Aug 2014 20:08:44 +0000 (20:08 +0000)
committerguenther <guenther@openbsd.org>
Sat, 9 Aug 2014 20:08:44 +0000 (20:08 +0000)
a column, it needs to included in all rows, even after the register is
restored.

ok jsg@

gnu/usr.bin/binutils-2.17/binutils/dwarf.c
gnu/usr.bin/binutils/binutils/readelf.c

index c69cab2..a969760 100644 (file)
@@ -2770,6 +2770,9 @@ Frame_Chunk;
 /* A marker for a col_type that means this column was never referenced
    in the frame info.  */
 #define DW_CFA_unreferenced (-1)
+/* Like DW_CFA_unreferenced, except indicating that it was referenced before
+   (and therefore needs space in the columnar output). */
+#define DW_CFA_placeholder  (-2)
 
 static void
 frame_need_space (Frame_Chunk *fc, int reg)
@@ -2852,6 +2855,9 @@ frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
            case DW_CFA_val_expression:
              strcpy (tmp, "vexp");
              break;
+           case DW_CFA_placeholder:
+             tmp[0] = '\0';
+             break;
            default:
              strcpy (tmp, "n/a");
              break;
@@ -3311,7 +3317,9 @@ display_debug_frames (struct dwarf_section *section,
            case DW_CFA_restore:
              if (! do_debug_frames_interp)
                printf ("  DW_CFA_restore: r%d\n", opa);
-             fc->col_type[opa] = cie->col_type[opa];
+             if ((fc->col_type[opa] = cie->col_type[opa]) ==
+                 DW_CFA_unreferenced)
+               fc->col_type[opa] = DW_CFA_placeholder;
              fc->col_offset[opa] = cie->col_offset[opa];
              break;
 
@@ -3385,7 +3393,9 @@ display_debug_frames (struct dwarf_section *section,
              reg = LEB ();
              if (! do_debug_frames_interp)
                printf ("  DW_CFA_restore_extended: r%ld\n", reg);
-             fc->col_type[reg] = cie->col_type[reg];
+             if ((fc->col_type[opa] = cie->col_type[opa]) ==
+                 DW_CFA_unreferenced)
+               fc->col_type[opa] = DW_CFA_placeholder;
              fc->col_offset[reg] = cie->col_offset[reg];
              break;
 
index eb21735..f5fc740 100644 (file)
@@ -8549,6 +8549,9 @@ Frame_Chunk;
 /* A marker for a col_type that means this column was never referenced
    in the frame info.  */
 #define DW_CFA_unreferenced (-1)
+/* Like DW_CFA_unreferenced, except indicating that it was referenced before
+   (and therefore needs space in the columnar output). */
+#define DW_CFA_placeholder  (-2)
 
 static void
 frame_need_space (Frame_Chunk *fc, int reg)
@@ -8625,6 +8628,9 @@ frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
            case DW_CFA_expression:
              strcpy (tmp, "exp");
              break;
+           case DW_CFA_placeholder:
+             tmp[0] = '\0';
+             break;
            default:
              strcpy (tmp, "n/a");
              break;
@@ -9056,7 +9062,9 @@ display_debug_frames (Elf_Internal_Shdr *section,
            case DW_CFA_restore:
              if (! do_debug_frames_interp)
                printf ("  DW_CFA_restore: r%d\n", opa);
-             fc->col_type[opa] = cie->col_type[opa];
+             if ((fc->col_type[opa] = cie->col_type[opa]) ==
+                 DW_CFA_unreferenced)
+               fc->col_type[opa] = DW_CFA_placeholder;
              fc->col_offset[opa] = cie->col_offset[opa];
              break;
 
@@ -9119,7 +9127,9 @@ display_debug_frames (Elf_Internal_Shdr *section,
              reg = LEB ();
              if (! do_debug_frames_interp)
                printf ("  DW_CFA_restore_extended: r%ld\n", reg);
-             fc->col_type[reg] = cie->col_type[reg];
+             if ((fc->col_type[opa] = cie->col_type[opa]) ==
+                 DW_CFA_unreferenced)
+               fc->col_type[opa] = DW_CFA_placeholder;
              fc->col_offset[reg] = cie->col_offset[reg];
              break;