From e309974ca263a5e8452336c36e3dd7cad43d615b Mon Sep 17 00:00:00 2001 From: guenther Date: Sat, 9 Aug 2014 20:08:44 +0000 Subject: [PATCH] Fix readelf --debug-dump=frames-interp output: once a register is given 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 | 14 ++++++++++++-- gnu/usr.bin/binutils/binutils/readelf.c | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/gnu/usr.bin/binutils-2.17/binutils/dwarf.c b/gnu/usr.bin/binutils-2.17/binutils/dwarf.c index c69cab224b2..a969760f045 100644 --- a/gnu/usr.bin/binutils-2.17/binutils/dwarf.c +++ b/gnu/usr.bin/binutils-2.17/binutils/dwarf.c @@ -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; diff --git a/gnu/usr.bin/binutils/binutils/readelf.c b/gnu/usr.bin/binutils/binutils/readelf.c index eb217351590..f5fc740e0b7 100644 --- a/gnu/usr.bin/binutils/binutils/readelf.c +++ b/gnu/usr.bin/binutils/binutils/readelf.c @@ -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; -- 2.20.1