This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Add .cfi_val_offset GAS command.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=084303b8c636944564d7be3b85dde55e8c371e91

commit 084303b8c636944564d7be3b85dde55e8c371e91
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date:   Wed Sep 28 17:54:06 2016 +0200

    Add .cfi_val_offset GAS command.
    
    This patch adds support for .cfi_val_offset GAS pseudo command which
    maps to DW_CFA_val_offset and DW_CFA_val_offset_sf.
    
    gas/ChangeLog:
    
    2016-09-29  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
    
    	* doc/as.texinfo: Add docu for .cfi_val_offset.
    	* dw2gencfi.c (cfi_add_CFA_val_offset): New function.
    	(dot_cfi): Add case for DW_CFA_val_offset.
    	(output_cfi_insn): Likewise.
    	(cfi_pseudo_table): Add entry for cfi_val_offset.
    	* dw2gencfi.h: Add prototype for cfi_add_CFA_val_offset.
    	* testsuite/gas/cfi/cfi-common-8.d: New test.
    	* testsuite/gas/cfi/cfi-common-8.s: New test.
    	* testsuite/gas/cfi/cfi.exp: Run cfi-common-8 testcase.
    
    binutils/ChangeLog:
    
    2016-09-29  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
    
    	* dwarf.c (display_debug_frames): Adjust output line.

Diff:
---
 binutils/dwarf.c                     |  4 ++--
 gas/doc/as.texinfo                   |  3 +++
 gas/dw2gencfi.c                      | 42 ++++++++++++++++++++++++++++++++++++
 gas/dw2gencfi.h                      |  1 +
 gas/testsuite/gas/cfi/cfi-common-8.d | 23 ++++++++++++++++++++
 gas/testsuite/gas/cfi/cfi-common-8.s |  6 ++++++
 gas/testsuite/gas/cfi/cfi.exp        |  1 +
 7 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index e07f661..95b33a8 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -6418,7 +6418,7 @@ display_debug_frames (struct dwarf_section *section,
 	      if (reg >= (unsigned int) fc->ncols)
 		reg_prefix = bad_reg;
 	      if (! do_debug_frames_interp || *reg_prefix != '\0')
-		printf ("  DW_CFA_val_offset: %s%s at cfa%+ld\n",
+		printf ("  DW_CFA_val_offset: %s%s is cfa%+ld\n",
 			reg_prefix, regname (reg, 0),
 			roffs * fc->data_factor);
 	      if (*reg_prefix == '\0')
@@ -6653,7 +6653,7 @@ display_debug_frames (struct dwarf_section *section,
 	      if (frame_need_space (fc, reg) < 0)
 		reg_prefix = bad_reg;
 	      if (! do_debug_frames_interp || *reg_prefix != '\0')
-		printf ("  DW_CFA_val_offset_sf: %s%s at cfa%+ld\n",
+		printf ("  DW_CFA_val_offset_sf: %s%s is cfa%+ld\n",
 			reg_prefix, regname (reg, 0),
 			(long)(l * fc->data_factor));
 	      if (*reg_prefix == '\0')
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index cdaeb6b..82cc72d 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -4831,6 +4831,9 @@ value that is added/substracted from the previous offset.
 Previous value of @var{register} is saved at offset @var{offset} from
 CFA.
 
+@subsection @code{.cfi_val_offset @var{register}, @var{offset}}
+Previous value of @var{register} is CFA + @var{offset}.
+
 @subsection @code{.cfi_rel_offset @var{register}, @var{offset}}
 Previous value of @var{register} is saved at offset @var{offset} from
 the current CFA register.  This is transformed to @code{.cfi_offset}
diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c
index fb3e302..4fbdf42 100644
--- a/gas/dw2gencfi.c
+++ b/gas/dw2gencfi.c
@@ -600,6 +600,22 @@ cfi_add_CFA_offset (unsigned regno, offsetT offset)
     as_bad (_("register save offset not a multiple of %u"), abs_data_align);
 }
 
+/* Add a DW_CFA_val_offset record to the CFI data.  */
+
+void
+cfi_add_CFA_val_offset (unsigned regno, offsetT offset)
+{
+  unsigned int abs_data_align;
+
+  gas_assert (DWARF2_CIE_DATA_ALIGNMENT != 0);
+  cfi_add_CFA_insn_reg_offset (DW_CFA_val_offset, regno, offset);
+
+  abs_data_align = (DWARF2_CIE_DATA_ALIGNMENT < 0
+		    ? -DWARF2_CIE_DATA_ALIGNMENT : DWARF2_CIE_DATA_ALIGNMENT);
+  if (offset % abs_data_align)
+    as_bad (_("register save offset not a multiple of %u"), abs_data_align);
+}
+
 /* Add a DW_CFA_def_cfa record to the CFI data.  */
 
 void
@@ -727,6 +743,7 @@ const pseudo_typeS cfi_pseudo_table[] =
     { "cfi_val_encoded_addr", dot_cfi_val_encoded_addr, 0 },
     { "cfi_inline_lsda", dot_cfi_inline_lsda, 0 },
     { "cfi_label", dot_cfi_label, 0 },
+    { "cfi_val_offset", dot_cfi, DW_CFA_val_offset },
     { NULL, NULL, 0 }
   };
 
@@ -827,6 +844,13 @@ dot_cfi (int arg)
       cfi_add_CFA_offset (reg1, offset);
       break;
 
+    case DW_CFA_val_offset:
+      reg1 = cfi_parse_reg ();
+      cfi_parse_separator ();
+      offset = cfi_parse_const ();
+      cfi_add_CFA_val_offset (reg1, offset);
+      break;
+
     case CFI_rel_offset:
       reg1 = cfi_parse_reg ();
       cfi_parse_separator ();
@@ -1680,6 +1704,23 @@ output_cfi_insn (struct cfi_insn_data *insn)
 	}
       break;
 
+    case DW_CFA_val_offset:
+      regno = insn->u.ri.reg;
+      offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
+      if (offset < 0)
+	{
+	  out_one (DW_CFA_val_offset_sf);
+	  out_uleb128 (regno);
+	  out_sleb128 (offset);
+	}
+      else
+	{
+	  out_one (DW_CFA_val_offset);
+	  out_uleb128 (regno);
+	  out_uleb128 (offset);
+	}
+      break;
+
     case DW_CFA_register:
       out_one (DW_CFA_register);
       out_uleb128 (insn->u.rr.reg1);
@@ -2516,6 +2557,7 @@ const pseudo_typeS cfi_pseudo_table[] =
     { "cfi_val_encoded_addr", dot_cfi_dummy, 0 },
     { "cfi_label", dot_cfi_dummy, 0 },
     { "cfi_inline_lsda", dot_cfi_dummy, 0 },
+    { "cfi_val_offset", dot_cfi_dummy, 0 },
     { NULL, NULL, 0 }
   };
 
diff --git a/gas/dw2gencfi.h b/gas/dw2gencfi.h
index 9ef1020..cbc4233 100644
--- a/gas/dw2gencfi.h
+++ b/gas/dw2gencfi.h
@@ -41,6 +41,7 @@ extern void cfi_add_advance_loc (struct symbol *);
 extern void cfi_add_label (const char *);
 
 extern void cfi_add_CFA_offset (unsigned, offsetT);
+extern void cfi_add_CFA_val_offset (unsigned, offsetT);
 extern void cfi_add_CFA_def_cfa (unsigned, offsetT);
 extern void cfi_add_CFA_register (unsigned, unsigned);
 extern void cfi_add_CFA_def_cfa_register (unsigned);
diff --git a/gas/testsuite/gas/cfi/cfi-common-8.d b/gas/testsuite/gas/cfi/cfi-common-8.d
new file mode 100644
index 0000000..6155690
--- /dev/null
+++ b/gas/testsuite/gas/cfi/cfi-common-8.d
@@ -0,0 +1,23 @@
+#objdump: -Wf
+#name: CFI common 8
+#...
+Contents of the .eh_frame section:
+
+00000000 0+0010 0+0000 CIE
+  Version:               1
+  Augmentation:          "zR"
+  Code alignment factor: .*
+  Data alignment factor: .*
+  Return address column: .*
+  Augmentation data:     [01]b
+
+  DW_CFA_nop
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000014 0+00(18|1c|20) 0+0018 FDE cie=0+0000 pc=.*
+  DW_CFA_advance_loc: 4 to .*
+  DW_CFA_def_cfa: r0( \([er]ax\)|) ofs 16
+  DW_CFA_val_offset(_sf|): r1( \((rdx|ecx)\)|) is cfa\+8
+  DW_CFA_val_offset(_sf|): r2( \((rcx|edx)\)|) is cfa-32
+#...
diff --git a/gas/testsuite/gas/cfi/cfi-common-8.s b/gas/testsuite/gas/cfi/cfi-common-8.s
new file mode 100644
index 0000000..8477ff0
--- /dev/null
+++ b/gas/testsuite/gas/cfi/cfi-common-8.s
@@ -0,0 +1,6 @@
+	.cfi_startproc simple
+	.long 0
+	.cfi_def_cfa 0, 16
+	.cfi_val_offset 1, 8
+	.cfi_val_offset 2, -32
+	.cfi_endproc
diff --git a/gas/testsuite/gas/cfi/cfi.exp b/gas/testsuite/gas/cfi/cfi.exp
index 9b6012e..3056856 100644
--- a/gas/testsuite/gas/cfi/cfi.exp
+++ b/gas/testsuite/gas/cfi/cfi.exp
@@ -135,4 +135,5 @@ if { ![istarget "hppa64*-*"] } then {
     run_dump_test "cfi-common-6"
   }
   run_dump_test "cfi-common-7"
+  run_dump_test "cfi-common-8"
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]