This is the mail archive of the binutils@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]

[Patch] pe/coff x86-64: improve dump of unwind v2


Hello,

thanks to Corinna (https://sourceware.org/ml/gdb-patches/2013-12/msg00097.html),
we got hints about the newly added unwind opcode on Windows 8.1.

The official name is UWOP_EPILOG, so I added a define in coff/pe.h

>From what I could deduce, the first EPILOG opcode contains the length of the
epilog, while following EPILOG opcodes describe the location of the epilogs, using
offset from the end (a function can have multiple epilogs, but they must have the
same size).

I am not sure about the meaning of the info of the first EPILOG opcode. It looks like
it is set to 1 if there is an epilog at the end of the function. The info of other
EPILOG opcodes is the MSB of the offset, the LSB is given by the first byte.

Given that, I enhanced pei-x86_64.c to display this opcode.

No regressions for x86_64-pc-mingw32.

Ok for trunk ?

Tristan.

include/
2013-12-04  Tristan Gingold  <gingold@adacore.com>

	* pe.h (UWOP_EPILOG, UWOP_PARE): Define.

bfd/
2013-12-04  Tristan Gingold  <gingold@adacore.com>

	* pei-x86_64.c (pex64_xdata_print_uwd_codes): Add argument rf.
	Display epilog opcode.
	(pex64_dump_xdata): Add argument rf; make addr a local variable.
	Adjust call to pex64_xdata_print_uwd_codes.
	(pex64_bfd_print_pdata): Display code range, adjust call to
	pex64_dump_xdata.

diff --git a/bfd/pei-x86_64.c b/bfd/pei-x86_64.c
index ecbef47..40ca4a6 100644
--- a/bfd/pei-x86_64.c
+++ b/bfd/pei-x86_64.c
@@ -139,7 +139,8 @@ pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui, void *data)
 
 static void
 pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd,
-			     struct pex64_unwind_info *ui)
+			     struct pex64_unwind_info *ui,
+			     struct pex64_runtime_function *rf)
 {
   unsigned int i;
   unsigned int tmp; /* At least 32 bits.  */
@@ -156,17 +157,31 @@ pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd,
 
   i = 0;
 
-  if (ui->Version == 2 && PEX64_UNWCODE_CODE (ui->rawUnwindCodes[1]) == 6)
+  if (ui->Version == 2
+      && PEX64_UNWCODE_CODE (ui->rawUnwindCodes[1]) == UWOP_EPILOG)
     {
-      /* Display opcodes 6 (whose meaning is not documented).  */
-      fprintf (file, "\tv2 opcode6:");
+      /* Display epilog opcode (whose docoding is not fully documented).
+         Looks to be designed to speed-up unwinding, as there is no need
+	 to decode instruction flow if outside an epilog.  */
+      unsigned int func_size = rf->rva_EndAddress - rf->rva_BeginAddress;
+
+      fprintf (file, "\tv2 epilog (length: %02x) at pc+:",
+	       ui->rawUnwindCodes[0]);
+      if (PEX64_UNWCODE_INFO (ui->rawUnwindCodes[1]))
+	fprintf (file, " 0x%x", func_size - ui->rawUnwindCodes[0]);
+      i++;
       for (; i < ui->CountOfCodes; i++)
 	{
 	  const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
+	  unsigned int off;
 
-	  if (PEX64_UNWCODE_CODE (dta[1]) != 6)
+	  if (PEX64_UNWCODE_CODE (dta[1]) != UWOP_EPILOG)
 	    break;
-	  fprintf (file, " %02x %01x", dta[0], PEX64_UNWCODE_INFO (dta[1]));
+	  off = dta[0] | (PEX64_UNWCODE_INFO (dta[1]) << 8);
+	  if (off == 0)
+	    fprintf (file, " [pad]");
+	  else
+	    fprintf (file, " 0x%x", func_size - off);
 	}
       fputc ('\n', file);
     }
@@ -229,7 +244,7 @@ pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd,
 	    }
 	  else if (ui->Version == 2)
 	    {
-	      fprintf (file, "v2-opc6 %02x %01x", dta[0], info);
+	      fprintf (file, "epilog %02x %01x", dta[0], info);
 	      unexpected = TRUE;
 	    }
 	  break;
@@ -290,15 +305,18 @@ pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name)
   return section;
 }
 
-/* Dump xdata at rva ADDR to FILE for ABFD.  */
+/* Dump xdata at for function RF to FILE.  The argument XDATA_SECTION
+   designate the bfd section containing the xdata, XDATA is its content,
+   and ENDX the size if known (or NULL).  */
 
 static void
 pex64_dump_xdata (FILE *file, bfd *abfd,
-		  asection *xdata_section, bfd_byte *xdata,
-		  bfd_vma addr, bfd_vma *endx)
+		  asection *xdata_section, bfd_byte *xdata, bfd_vma *endx,
+		  struct pex64_runtime_function *rf)
 {
   bfd_vma vaddr;
   bfd_vma end_addr;
+  bfd_vma addr = rf->rva_UnwindData;
   struct pex64_unwind_info ui;
 
   vaddr = xdata_section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
@@ -362,7 +380,7 @@ pex64_dump_xdata (FILE *file, bfd *abfd,
 	   ui.FrameRegister == 0 ? "none"
 	   : pex_regs[(unsigned int) ui.FrameRegister]);
 
-  pex64_xdata_print_uwd_codes (file, abfd, &ui);
+  pex64_xdata_print_uwd_codes (file, abfd, &ui, rf);
 
   switch (ui.Flags)
     {
@@ -571,9 +589,11 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
       else
 	prev_unwinddata_rva = rf.rva_UnwindData;
 
-      fprintf (file, " (rva: %08x): for function at ",
+      fprintf (file, " (rva: %08x): ",
 	       (unsigned int) rf.rva_UnwindData);
       fprintf_vma (file, rf.rva_BeginAddress + imagebase);
+      fprintf (file, " - ");
+      fprintf_vma (file, rf.rva_EndAddress + imagebase);
       fputc ('\n', file);
 
       if (rf.rva_UnwindData != 0)
@@ -618,8 +638,7 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
 	      if (p[0] == ~((bfd_vma) 0))
 		p = NULL;
 
-	      pex64_dump_xdata (file, abfd, xdata_section, xdata,
-				rf.rva_UnwindData, p);
+	      pex64_dump_xdata (file, abfd, xdata_section, xdata, p, &rf);
 	    }
 	}
     }
diff --git a/include/coff/pe.h b/include/coff/pe.h
index 3b37276..5e2b37e 100644
--- a/include/coff/pe.h
+++ b/include/coff/pe.h
@@ -392,8 +392,10 @@ struct external_pex64_runtime_function
 #define UWOP_SET_FPREG	      3
 #define UWOP_SAVE_NONVOL      4
 #define UWOP_SAVE_NONVOL_FAR  5
-#define UWOP_SAVE_XMM	      6	/* Deprecated, redefined in version 2.  */
-#define UWOP_SAVE_XMM_FAR     7	/* Deprecated.  */
+#define UWOP_SAVE_XMM         6 /* For version 1.  */
+#define UWOP_EPILOG           6 /* For version 2.  */
+#define UWOP_SAVE_XMM_FAR     7 /* For version 1 (deprecated).  */
+#define UWOP_SPARE            7 /* For version 2.  */
 #define UWOP_SAVE_XMM128      8
 #define UWOP_SAVE_XMM128_FAR  9
 #define UWOP_PUSH_MACHFRAME   10


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