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]

Re: RFC: Dumping of .pdata/.xdata for x64 PE+


2009/4/16 H.J. Lu <hjl.tools@gmail.com>:
> On Thu, Apr 16, 2009 at 10:04 AM, Kai Tietz <ktietz70@googlemail.com> wrote:
>> 2009/4/16 H.J. Lu <hjl.tools@gmail.com>:
>>> On Thu, Apr 16, 2009 at 9:41 AM, Kai Tietz <ktietz70@googlemail.com> wrote:
>>>> 2009/4/16 Dave Korn <dave.korn.cygwin@googlemail.com>:
>>>>> Kai Tietz wrote:
>>>>>> 2009/4/16 Dave Korn <dave.korn.cygwin@googlemail.com>:
>>>>>
>>>>>>> ?Although it's not used a lot, there is at least precedent (bfd/pe-mips.c)
>>>>>>> for putting such format-and-arch specific functions into the master back-end
>>>>>>> file. ?How would you feel about putting this function into bfd/pei-x86_64.c?
>>>>>>
>>>>>> Well, in general the implementation could be in pei-x86_64.c file. I
>>>>>> am just not sure if the EFI versions possible want to use this, too.
>>>>>> If so, it has to be at in common file.
>>>>>
>>>>> ?Hey, you should talk to HJ; he's planning to refactor EFI to use PEI
>>>>> vectors[*]. ?Yes, if this function can be used directly (or more-or-less)
>>>>> directly for EFI formats too, then it should have an XX in the name and go
>>>>> into peXXigen.c, that would be fine.
>>>>>
>>>>>>> Index: src/bfd/pei-x86_64.c
>>>>>>> ===================================================================
>>>>>>> --- src.orig/bfd/pei-x86_64.c
>>>>>>> +++ src/bfd/pei-x86_64.c
>>>>>>> @@ -25,9 +25,9 @@
>>>>>>>
>>>>>>> ?#define TARGET_SYM ? ? ? ? ? ? x86_64pei_vec
>>>>>>> ?#define TARGET_NAME ? ? ? ? ? ?"pei-x86-64"
>>>>>>> -#define COFF_IMAGE_WITH_PE
>>>>>>> ?#define COFF_WITH_PE
>>>>>>> ?#define COFF_WITH_pex64
>>>>>>> +#define COFF_IMAGE_WITH_PE
>>>>>>> ?#define PCRELOFFSET ? ? ? ? ? ?TRUE
>>>>>>>
>>>>>>> ?That change is not really necessary :)
>>>>>> Ups, I missed to update the patch. Of course it is not necessary ;)
>>>>>> Instead the macro #define bfd_pe_print_pdata ? _bfd_pex64_print_pdata
>>>>>> has to be added.
>>>>>
>>>>> ?Sorry, I trimmed that bit; it was present in your patch but I had no comment
>>>>> to make about it since it is obviously correct!
>>>>>
>>>>>> I meant the flag value in UNWIND_INFO. It appears to exists value 3
>>>>>> for it (UNW_FLAG_EHANDLER|UNW_FLAG_UHANDLER). And the corresponding
>>>>>> data (after the array of unwind codes) is different. It contains a
>>>>>> frame pointer (relative to frame offset+frameRegister) AFAIU. I was
>>>>>> asking if somebody has an idea what the pointer points to on stack. I
>>>>>> assume it is an object pointer, or the establisher frame itself.
>>>>>
>>>>> ?Ah, so in terms of the description at
>>>>> http://msdn.microsoft.com/en-us/library/ddssxxy8(VS.80).aspx:
>>>>>
>>>>> ---------------------------------<snip>---------------------------------
>>>>> (1) Exception Handler
>>>>>
>>>>> ULONG ? ? ? ? ? Address of exception handler
>>>>> variable ? ? ? ?Language-specific handler data (optional)
>>>>>
>>>>> ?Address of exception handler
>>>>>
>>>>> ? ?This is an image-relative pointer to either the function's
>>>>> language-specific exception/termination handler (if flag UNW_FLAG_CHAININFO is
>>>>> clear and one of the flags UNW_FLAG_EHANDLER or UNW_FLAG_UHANDLER is set).
>>>>>
>>>>> Language-specific handler data
>>>>>
>>>>> ? ?This is the function's language-specific exception handler data. The
>>>>> format of this data is unspecified and completely determined by the specific
>>>>> exception handler in use.
>>>>> ---------------------------------<snip>---------------------------------
>>>>>
>>>>> ... you've got the function pointer OK, and you want to know about the
>>>>> language-specific data? ?I would imagine that the establisher frame is
>>>>> computed by the unwinder using the prolog unwind codes, and so does not need
>>>>> to be present in the language-specific data; the most obvious thing I can
>>>>> think of is that this language-specific data ought to in some fashion point to
>>>>> some information that tells what kind of exceptions to catch, e.g. in C++,
>>>>> where the runtime is using SEH to catch C++ exception types, I would suppose
>>>>> the exception handler pointer points to a function in MSVC that's the
>>>>> modern-day equivalent of except_handler3, and the language-specific data would
>>>>> point in some fashion to a list of the exception types for which catch(){...}
>>>>> blocks exist. ?I imagine we'll have to do some fancy reverse engineering to
>>>>> figure it all out.
>>>>>
>>>>> ? ?cheers,
>>>>> ? ? ?DaveK
>>>>> --
>>>>> [*] - http://sourceware.org/ml/binutils/2009-04/msg00230.html
>>>>>
>>>>
>>>> Hello HJ,
>>>>
>>>> as I read that you want to refactor EFI to use PEI. What is your
>>>> opinion about the place for the xdata dumping for x64?
>>>>
>>>
>>> Can you put it in pei-x86_64.c?
>>>
>>> --
>>> H.J.
>>>
>>
>> Ok, put the complete code from peXXigen.c into pei-x86_64.c and make it static.
>>
>> Is this ok for you and the refactoring?
>>
>
> That is fine with me.
>
> Thanks.
>
>
> --
> H.J.
>

Ok, here is the patch

ChangeLog

2009-04-16  Kai Tietz  <kai.tietz@onevision.com>

	* coff-x86_64.c (PEI_HEADERS): Protect includes.
	(PE): Remove macro name checks.
	* pei-x86_64.c (PEI_HEADERS): Define to prevent double
	include in coff-x86_64.c of headers.
	(pex_regs): New static variable.
	(pep_xdata_print_uwd_codes): New static function.
	(pep_get_section_by_rva): Likewise.
	(pep_dump_xdata):
	(_xx_bfd_print_pdata): Likewise.
	(bfd_pe_print_pdata): Define as _xx_bfd_print_pdata.
	* peXXigen.c (_bfd_pex64_print_pdata): Removed implementation.
	* libpei.h (_bfd_pex64_print_pdata): : Removed declaration.

Tested for x86_64-pc-mingw32 target. Is this patch ok to apply?

Cheers,
Kai
-- 
|  (\_/) This is Bunny. Copy and paste
| (='.'=) Bunny into your signature to help
| (")_(") him gain world domination
Index: src/bfd/coff-x86_64.c
===================================================================
--- src.orig/bfd/coff-x86_64.c
+++ src/bfd/coff-x86_64.c
@@ -24,6 +24,10 @@
 #define COFF_WITH_pex64
 #endif
 
+/* Note we have to make sure not all headers are protected
+   by closurs, so we check define PEI_HEADERS to prevent
+   double including in pei-x86_64.c.  */
+#ifndef PEI_HEADERS
 #include "sysdep.h"
 #include "bfd.h"
 #include "libbfd.h"
@@ -32,6 +36,7 @@
 #include "coff/pe.h"
 #include "libcoff.h"
 #include "libiberty.h"
+#endif
 
 #define BADMAG(x) AMD64BADMAG(x)
 
@@ -711,14 +716,9 @@ coff_amd64_is_local_label_name (bfd *abf
 
 #endif /* TARGET_UNDERSCORE */
 
-#ifdef PE
-#undef  bfd_pe_print_pdata
-#define bfd_pe_print_pdata   _bfd_pex64_print_pdata
-#else  /* PE */
 #ifndef bfd_pe_print_pdata
 #define bfd_pe_print_pdata   NULL
 #endif
-#endif /* PE */
 
 #include "coffcode.h"
 
Index: src/bfd/peXXigen.c
===================================================================
--- src.orig/bfd/peXXigen.c
+++ src/bfd/peXXigen.c
@@ -1895,87 +1895,6 @@ _bfd_XX_print_ce_compressed_pdata (bfd *
 #undef PDATA_ROW_SIZE
 }
 
-#ifdef COFF_WITH_pex64
-/* The PE+ x64 variant.  */
-bfd_boolean
-_bfd_pex64_print_pdata (bfd *abfd, void *vfile)
-{
-# define PDATA_ROW_SIZE	(3 * 4)
-  FILE *file = (FILE *) vfile;
-  bfd_byte *data = NULL;
-  asection *section = bfd_get_section_by_name (abfd, ".pdata");
-  bfd_size_type datasize = 0;
-  bfd_size_type i;
-  bfd_size_type start, stop;
-  int onaline = PDATA_ROW_SIZE;
-  struct sym_cache sym_cache = {0, 0};
-
-  if (section == NULL
-      || coff_section_data (abfd, section) == NULL
-      || pei_section_data (abfd, section) == NULL)
-    return TRUE;
-
-  stop = pei_section_data (abfd, section)->virt_size;
-  if ((stop % onaline) != 0)
-    fprintf (file,
-             _("warning: .pdata section size (%ld) is not a multiple of %d\n"),
-	     (long) stop, onaline);
-
-  fprintf (file,
-	   _("\nThe Function Table (interpreted .pdata section contents)\n"));
-
-  fprintf (file, _("vma:\t\t\tBeginAddress\t EndAddress\t  UnwindData\n"));
-
-  datasize = section->size;
-  if (datasize == 0)
-    return TRUE;
-
-  if (!bfd_malloc_and_get_section (abfd, section, &data))
-    {
-      if (data != NULL)
-	free (data);
-      return FALSE;
-    }
-
-  start = 0;
-
-  for (i = start; i < stop; i += onaline)
-    {
-      bfd_vma begin_addr;
-      bfd_vma end_addr;
-      bfd_vma unwind_data_addr;
-
-      if (i + PDATA_ROW_SIZE > stop)
-	break;
-
-      begin_addr = bfd_get_32 (abfd, data + i);
-      end_addr = bfd_get_32 (abfd, data + i + 4);
-      unwind_data_addr = bfd_get_32 (abfd, data + i +  8);
-
-      if (begin_addr == 0 && end_addr == 0 && unwind_data_addr == 0)
-	/* We are probably into the padding of the section now.  */
-	break;
-
-      fputc (' ', file);
-      fprintf_vma (file, i + section->vma);
-      fprintf (file, ":\t");
-      fprintf_vma (file, begin_addr);
-      fputc (' ', file);
-      fprintf_vma (file, end_addr);
-      fputc (' ', file);
-      fprintf_vma (file, unwind_data_addr);
-
-      fprintf (file, "\n");
-    }
-
-  free (data);
-
-  cleanup_syms (&sym_cache);
-
-  return TRUE;
-#undef PDATA_ROW_SIZE
-}
-#endif
 
 #define IMAGE_REL_BASED_HIGHADJ 4
 static const char * const tbl[] =
Index: src/bfd/pei-x86_64.c
===================================================================
--- src.orig/bfd/pei-x86_64.c
+++ src/bfd/pei-x86_64.c
@@ -25,9 +25,9 @@
 
 #define TARGET_SYM 		x86_64pei_vec
 #define TARGET_NAME 		"pei-x86-64"
-#define COFF_IMAGE_WITH_PE
 #define COFF_WITH_PE
 #define COFF_WITH_pex64
+#define COFF_IMAGE_WITH_PE
 #define PCRELOFFSET 		TRUE
 #define TARGET_UNDERSCORE 	'_'
 /* Long section names not allowed in executable images, only object files.  */
@@ -53,4 +53,434 @@
 { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
   COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
 
+/* Note we have to make sure not all headers are
+   protected by closurs, so define PEI_HEADERS to
+   prevent double including in coff-x86_64.c */
+#define PEI_HEADERS
+#include "sysdep.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "coff/x86_64.h"
+#include "coff/internal.h"
+#include "coff/pe.h"
+#include "libcoff.h"
+#include "libpei.h"
+#include "libiberty.h"
+
+#undef AOUTSZ
+#define AOUTSZ		PEPAOUTSZ
+#define PEAOUTHDR	PEPAOUTHDR
+
+static const char *pex_regs[16] = {
+  "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
+  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+};
+
+static void
+pep_xdata_print_uwd_codes(bfd_byte *dta, bfd_vma count, FILE *file, bfd_vma pc_addr)
+{
+  bfd_vma i;
+  bfd_vma tmp = 0;
+  bfd_byte *insns[256];
+  bfd_vma insns_count = 0;
+
+  if (!count || !dta)
+    return;
+  /* Sort array ascending. Note: it is stored in reveresed order.  */
+  for (i = 0; i < count; i++)
+    {
+      bfd_byte *t;
+
+      t = insns[insns_count++] = &dta[i * 2];
+      switch (t[1] & 0xf)
+        {
+        case 0: case 2:
+	case 3: case 10:
+	  break;
+	case 1:
+	  if (((t[1]>>4)&0xf)==0)
+	    {
+	      i += 1;
+	      break;
+	    }
+	  else if (((t[1]>>4)&0xf)==1)
+	    {
+	      i += 2;
+	      break;
+	    }
+	  /* fall through.  */
+	default:
+	  fprintf (file, "\t contains unknown code (%u).\n", (unsigned int) (t[1]&0xf));
+	  return;
+	case 4: case 6: case 8:
+	  i++;
+	  break;
+	case 5: case 7: case 9:
+	  i += 2;
+	  break;
+        }
+    }
+  fprintf (file, "\t At pc 0x");
+  fprintf_vma (file, pc_addr);
+  fprintf (file, " there are the following saves (in logical order).\n");
+  for (i = insns_count; i > 0;)
+    {
+      --i;
+      dta = insns[i];
+      fprintf (file, "\t  insn ends at pc+0x%02x: ", (unsigned int) dta[0]);
+      switch (dta[1]&0xf) {
+	case 0: /* UWOP_PUSH_NONVOL.  */
+	  fprintf (file, "push %s.\n", pex_regs[((dta[1]>>4)&0xf)]);
+	  break;
+	case 1: /* UWOP_ALLOC_LARGE.  */
+	  if (((dta[1]>>4)&0xf) == 0)
+	    tmp = (bfd_vma) (*((unsigned short *)&dta[2]));
+	  else
+	    tmp = (bfd_vma) (*((unsigned int *)&dta[2]));
+	  tmp *= 8;
+	  fprintf (file, "save stack region of size 0x");
+	  fprintf_vma (file, tmp);
+	  fprintf (file,".\n");
+	  break;
+	case 2: /* UWOP_ALLOC_SMALL.  */
+	  tmp = (bfd_vma) ((dta[1]>>4)&0xf);
+	  tmp += 1;
+	  tmp *= 8;
+	  fprintf (file, "save stack region of size 0x");
+	  fprintf_vma (file, tmp);
+	  fprintf (file,".\n");
+	  break;
+	case 3:  /* UWOP_SET_FPREG.  */
+	  tmp = (bfd_vma) ((dta[1]>>4)&0xf);
+	  tmp *= 16;
+	  fprintf (file, "FPReg = (FrameReg) + 0x");
+	  fprintf_vma (file, tmp);
+	  fprintf (file, ".\n");
+	  break;
+	case 4: /* UWOP_SAVE_NONVOL.  */
+	  fprintf (file, "mov %s at 0x", pex_regs[((dta[1]>>4)&0xf)]);
+	  tmp = (bfd_vma) (*((unsigned short *) &dta[2]));
+	  tmp *= 8;
+	  fprintf_vma (file, tmp);
+	  fprintf (file, ".\n");
+	  break;
+	case 5: /* UWOP_SAVE_NONVOL_FAR.  */
+	  fprintf (file, "mov %s at 0x", pex_regs[((dta[1]>>4)&0xf)]);
+	  tmp = (bfd_vma) (*((unsigned int *) &dta[2]));
+	  fprintf_vma (file, tmp);
+	  fprintf (file, ".\n");
+	  break;
+	case 6: /* UWOP_SAVE_XMM.  */
+	  tmp = (bfd_vma) (*((unsigned short *) &dta[2]));
+	  tmp *= 8;
+	  fprintf (file, "mov mm%u at 0x", (unsigned int)((dta[1]>>4)&0xf));
+	  fprintf_vma (file, tmp);
+	  fprintf (file, ".\n");
+	  break;
+	case 7: /* UWOP_SAVE_XMM_FAR.  */
+	  tmp = (bfd_vma) (*((unsigned int *) &dta[2]));
+	  fprintf (file, "mov mm%u at 0x", (unsigned int)((dta[1]>>4)&0xf));
+	  fprintf_vma (file, tmp);
+	  fprintf (file, ".\n");
+	  break;
+	case 8: /* UWOP_SAVE_XMM128.  */
+	  tmp = (bfd_vma) (*((unsigned short *) &dta[2]));
+	  tmp *= 16;
+	  fprintf (file, "mov xmm%u at 0x", (unsigned int)((dta[1]>>4)&0xf));
+	  fprintf_vma (file, tmp);
+	  fprintf (file, ".\n");
+	  break;
+	case 9: /* UWOP_SAVE_XMM128_FAR.  */
+	  tmp = (bfd_vma) (*((unsigned int *) &dta[2]));
+	  fprintf (file, "mov xmm%u at 0x", (unsigned int)((dta[1]>>4)&0xf));
+	  fprintf_vma (file, tmp);
+	  fprintf (file, ".\n");
+	  break;
+	case 10: /* UWOP_PUSH_MACHFRAME.  */
+	  fprintf (file, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP");
+	  if (((dta[1]>>4)&0xf) == 0)
+	    {
+	      fprintf (file, ")");
+	    }
+	  else if (((dta[1]>>4)&0xf) == 1)
+	    {
+	      fprintf (file, ",ErrorCode)");
+	    }
+	  else
+	    {
+	      fprintf (file, ", unknown(%u))", ((dta[1]>>4)&0xf));
+	    }
+	  fprintf (file,".\n");
+	  break;
+	default:
+	  fprintf (file, "unknown code %u.\n", (unsigned int) (dta[1]&0xf));
+	  break;
+      }
+    }
+}
+
+static asection *
+pep_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name)
+{
+  asection *section = bfd_get_section_by_name (abfd, sec_name);
+  bfd_vma vsize;
+  bfd_size_type datasize = 0;
+
+  if (section == NULL
+      || coff_section_data (abfd, section) == NULL
+      || pei_section_data (abfd, section) == NULL)
+    return NULL;
+  vsize = section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
+  datasize = section->size;
+  if (!datasize || vsize > addr || (vsize + datasize) < addr)
+    return NULL;
+  return section;
+}
+
+static void
+pep_dump_xdata (FILE *file, bfd *abfd, bfd_vma addr, bfd_vma pc_addr)
+{
+  asection *section = pep_get_section_by_rva (abfd, addr, ".rdata");
+  bfd_vma vsize;
+  bfd_byte *data = NULL;
+
+  if (!section)
+    section = pep_get_section_by_rva (abfd, addr, ".data");
+  if (!section)
+    section = pep_get_section_by_rva (abfd, addr, ".xdata");
+  if (!section)
+    {
+      section = pep_get_section_by_rva (abfd, addr, ".pdata");
+      if (section)
+        {
+	  addr &= ~1;
+	  fprintf (file, "\t Shares information with pdata element at 0x");
+	  fprintf_vma (file, addr + pe_data (abfd)->pe_opthdr.ImageBase);
+	  fprintf (file, ".\n");
+        }
+      return;
+    }
+  vsize = section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
+  addr -= vsize;
+  if (bfd_malloc_and_get_section (abfd, section, &data))
+    {
+      bfd_vma version;
+      bfd_vma flags;
+      bfd_vma sizeof_prologue;
+      bfd_vma count_of_codes;
+      bfd_vma frame_register;
+      bfd_vma frame_offset;
+
+      /* Array of UNWIND_CODE with count_of_codes elements. This
+         this structure has byte size and the following definition:
+	  UBYTE CodeOffset;
+	  UBYTE UnwindOperationCode : 4;
+	  UBYTE OperationInfo : 4;
+       */
+      bfd_byte *unwind_code;
+      /* if flag has bit 0 set, there is an exception hander.  */
+      bfd_vma exception_handler = 0;
+      /* if flag has bit 2 set, there is a function entry present.  */
+      bfd_vma function_entry = 0;
+      /* if flag has bit 0 set, there is an additionally exception data present.  */
+
+      if (!data) return;
+      version = (bfd_vma) data[addr];
+      flags = (version >> 3) & 0x1f;
+      version &= 3;
+      sizeof_prologue = (bfd_vma) data[addr + 1];
+      count_of_codes = (bfd_vma) data[addr + 2];
+      frame_register = (bfd_vma) data[addr + 3];
+      frame_offset = (frame_register >> 4) & 0xf;
+      frame_register &= 0xf;
+      addr += 4;
+      unwind_code = &data[addr];
+      addr += ((count_of_codes + 1) & ~1) * 2;
+
+      if (version != 1)
+	fprintf (file, "\tVersion %u (unknown).\n", (unsigned int) version);
+      fprintf (file, "\tFlags: ");
+      switch ((flags & 0x1f))
+        {
+          case 0:
+	    fprintf (file, "none");
+	    break;
+	  case 1:
+	    fprintf (file, "UNW_FLAG_EHANDLER");
+	    break;
+	  case 2:
+	    fprintf (file, "UNW_FLAG_UHANDLER");
+	    break;
+	  case 3:
+	    fprintf (file, "UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER");
+	    break;
+	  case 4:
+	    fprintf (file, "UNW_FLAG_CHAININFO");
+	    break;
+	  default:
+	    fprintf (file, "unknown flags 0x%x", (unsigned int) flags);
+	    break;
+        }
+      fprintf (file, ".\n");
+      if (count_of_codes != 0)
+	fprintf (file, "\tEntry has %u codes.", (unsigned int) count_of_codes);
+      fprintf (file, "\tPrologue size: %u, Frame offset = 0x%x.\n",
+	       (unsigned int) sizeof_prologue, (unsigned int) frame_offset);
+      fprintf (file, "\tFrame register is %s.\n",
+	frame_register == 0 ? "CFA" : pex_regs[(unsigned int) frame_register]);
+
+      pep_xdata_print_uwd_codes (unwind_code, count_of_codes, file, pc_addr);
+
+      if ((flags & 1) != 0)
+        {
+	  exception_handler = bfd_get_32 (abfd, data + addr);
+          addr += 4;
+        }
+      else if ((flags & 2) != 0)
+	{
+	  exception_handler = bfd_get_32 (abfd, data + addr);
+          addr += 4;
+	}
+      else if ((flags & 4) != 0)
+        {
+	  function_entry = bfd_get_32 (abfd, data + addr);
+	  addr += 4; /* RUNTIME_FUNCTION * */
+        }
+      if ((flags & 3) == 3)
+	{
+	  fprintf (file, "\t Argument at Framebase + 0x%x",
+	    (unsigned int) bfd_get_32 (abfd, data + addr));
+	  if (bfd_get_32 (abfd, data + addr + 4) != 0
+	      || bfd_get_32 (abfd, data + addr + 8) != 0)
+	    fprintf (file, " and unknown data 0x%x, 0x%x",
+	    (unsigned int) bfd_get_32 (abfd, data + addr + 4),
+	    (unsigned int) bfd_get_32 (abfd, data + addr + 8));
+	  fprintf (file, ".\n");
+	  addr += 12; /* RUNTIME_FUNCTION */
+	}
+
+      if ((flags & 3) == 1)
+	fprintf (file, "\texception_handler at 0x%x.\n", (unsigned int) exception_handler);
+      else if ((flags & 4) != 0)
+	fprintf (file, "\tFunction Entry: 0x%x\n", (unsigned int) function_entry);
+      if ((flags & 2) != 0)
+	{
+	  fprintf (file, "\texception_handler/terminate at 0x%x.\n", (unsigned int) exception_handler);
+	}
+      if ((flags & 3) == 1 || (flags & 3) == 2)
+	{
+	  bfd_vma i;
+	  bfd_vma count = bfd_get_32 (abfd, data + addr);
+	  addr += 4;
+	  fprintf (file, "\t 0x%x # of scope(s)\n", (unsigned int) count);
+	  for (i = 0; i < count && i < 255; i++)
+	    {
+	      fprintf (file, "\t scope #%u: BeginAddress: 0x%x, EndAddress: 0x%x,\n"
+		"\t\tHandlerAddress:0x%x, JumpTarget:0x%x\n",(unsigned int) (i+1),
+		(unsigned int) bfd_get_32 (abfd, data + addr),
+		(unsigned int) bfd_get_32 (abfd, data + addr + 4),
+		(unsigned int) bfd_get_32 (abfd, data + addr + 8),
+		(unsigned int) bfd_get_32 (abfd, data + addr + 12));
+	      addr += 16;
+	    }
+	  if (i < count)
+	    fprintf (file, "\t ...\n");
+	}
+    }
+  if (data != NULL)
+    free (data);
+}
+
+static bfd_boolean
+_xx_bfd_print_pdata (bfd *abfd, void *vfile)
+{
+# define PDATA_ROW_SIZE	(3 * 4)
+  FILE *file = (FILE *) vfile;
+  bfd_byte *data = NULL;
+  asection *section = bfd_get_section_by_name (abfd, ".pdata");
+  bfd_size_type datasize = 0;
+  bfd_size_type i;
+  bfd_size_type start, stop;
+  int onaline = PDATA_ROW_SIZE;
+
+  if (section == NULL
+      || coff_section_data (abfd, section) == NULL
+      || pei_section_data (abfd, section) == NULL)
+    return TRUE;
+
+  stop = pei_section_data (abfd, section)->virt_size;
+  if ((stop % onaline) != 0)
+    fprintf (file,
+             _("warning: .pdata section size (%ld) is not a multiple of %d\n"),
+	     (long) stop, onaline);
+
+  fprintf (file,
+	   _("\nThe Function Table (interpreted .pdata section contents)\n"));
+
+  fprintf (file, _("vma:\t\t\tBeginAddress\t EndAddress\t  UnwindData\n"));
+
+  datasize = section->size;
+  if (datasize == 0)
+    return TRUE;
+
+  if (!bfd_malloc_and_get_section (abfd, section, &data))
+    {
+      if (data != NULL)
+	free (data);
+      return FALSE;
+    }
+
+  start = 0;
+
+  for (i = start; i < stop; i += onaline)
+    {
+      bfd_vma begin_addr;
+      bfd_vma end_addr;
+      bfd_vma unwind_data_addr;
+
+      if (i + PDATA_ROW_SIZE > stop)
+	break;
+
+      begin_addr = bfd_get_32 (abfd, data + i);
+      end_addr = bfd_get_32 (abfd, data + i + 4);
+      unwind_data_addr = bfd_get_32 (abfd, data + i +  8);
+
+      if (begin_addr == 0 && end_addr == 0 && unwind_data_addr == 0)
+	/* We are probably into the padding of the section now.  */
+	break;
+
+      fputc (' ', file);
+      fprintf_vma (file, i + section->vma);
+      fprintf (file, ":\t");
+      begin_addr += pe_data (abfd)->pe_opthdr.ImageBase;
+      fprintf_vma (file, begin_addr);
+      fputc (' ', file);
+      end_addr += pe_data (abfd)->pe_opthdr.ImageBase;
+      fprintf_vma (file, end_addr);
+      fputc (' ', file);
+      fprintf_vma (file, unwind_data_addr);
+      fprintf (file, "\n");
+
+      if (unwind_data_addr != 0)
+	{
+	  if ((unwind_data_addr & 1) != 0)
+	    {
+	      unwind_data_addr &= ~1;
+	      fprintf (file, "\t shares information with pdata element at 0x");
+	      fprintf_vma (file, unwind_data_addr + pe_data (abfd)->pe_opthdr.ImageBase);
+	      fprintf (file, ".\n");
+	    }
+	  else
+	    pep_dump_xdata (file, abfd, unwind_data_addr, begin_addr);
+	}
+    }
+
+  free (data);
+
+  return TRUE;
+#undef PDATA_ROW_SIZE
+}
+
+#define bfd_pe_print_pdata   _xx_bfd_print_pdata
+
 #include "coff-x86_64.c"
Index: src/bfd/libpei.h
===================================================================
--- src.orig/bfd/libpei.h
+++ src/bfd/libpei.h
@@ -394,4 +394,3 @@ bfd_boolean _bfd_pe64_print_ce_compresse
 bfd_boolean _bfd_pex64_print_ce_compressed_pdata (bfd *, void *);
 bfd_boolean _bfd_pep_print_ce_compressed_pdata (bfd *, void *);
 
-bfd_boolean _bfd_pex64_print_pdata (bfd *, void *);

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