Ravenscar port for RISC-V
[deliverable/binutils-gdb.git] / bfd / pei-x86_64.c
index fdc6205f5a6d9405a0c5d9dc0be2aaa8628bc241..c0b97351defb044a4498fc70908ed89dfc83526e 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD back-end for Intel 386 PE IMAGE COFF files.
 /* BFD back-end for Intel 386 PE IMAGE COFF files.
-   Copyright 2006, 2007, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2006-2019 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
 
    This file is part of BFD, the Binary File Descriptor library.
 
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.
-   
+
    Written by Kai Tietz, OneVision Software GmbH&CoKg.  */
 
 #include "sysdep.h"
 #include "bfd.h"
 
    Written by Kai Tietz, OneVision Software GmbH&CoKg.  */
 
 #include "sysdep.h"
 #include "bfd.h"
 
-#define TARGET_SYM             x86_64pei_vec
-#define TARGET_NAME            "pei-x86-64"
+#define TARGET_SYM             x86_64_pei_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 COFF_WITH_PE
 #define COFF_WITH_pex64
-#define PCRELOFFSET            TRUE
+#define PCRELOFFSET            TRUE
 #if defined (USE_MINGW64_LEADING_UNDERSCORES)
 #if defined (USE_MINGW64_LEADING_UNDERSCORES)
-#define TARGET_UNDERSCORE      '_'
+#define TARGET_UNDERSCORE      '_'
 #else
 #else
-#define TARGET_UNDERSCORE      0
+#define TARGET_UNDERSCORE      0
 #endif
 /* Long section names not allowed in executable images, only object files.  */
 #define COFF_LONG_SECTION_NAMES 0
 #endif
 /* Long section names not allowed in executable images, only object files.  */
 #define COFF_LONG_SECTION_NAMES 0
 #define AOUTSZ         PEPAOUTSZ
 #define PEAOUTHDR      PEPAOUTHDR
 
 #define AOUTSZ         PEPAOUTSZ
 #define PEAOUTHDR      PEPAOUTHDR
 
-static const char *pex_regs[16] = {
+/* Name of registers according to SEH conventions.  */
+
+static const char * const pex_regs[16] = {
   "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
 };
 
   "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
 };
 
+/* Swap in a runtime function.  */
+
 static void
 pex64_get_runtime_function (bfd *abfd, struct pex64_runtime_function *rf,
                            const void *data)
 static void
 pex64_get_runtime_function (bfd *abfd, struct pex64_runtime_function *rf,
                            const void *data)
@@ -90,18 +94,24 @@ pex64_get_runtime_function (bfd *abfd, struct pex64_runtime_function *rf,
   rf->rva_BeginAddress = bfd_get_32 (abfd, ex_rf->rva_BeginAddress);
   rf->rva_EndAddress = bfd_get_32 (abfd, ex_rf->rva_EndAddress);
   rf->rva_UnwindData = bfd_get_32 (abfd, ex_rf->rva_UnwindData);
   rf->rva_BeginAddress = bfd_get_32 (abfd, ex_rf->rva_BeginAddress);
   rf->rva_EndAddress = bfd_get_32 (abfd, ex_rf->rva_EndAddress);
   rf->rva_UnwindData = bfd_get_32 (abfd, ex_rf->rva_UnwindData);
-  rf->isChained = PEX64_IS_RUNTIME_FUNCTION_CHAINED (rf);
-  rf->rva_UnwindData = PEX64_GET_UNWINDDATA_UNIFIED_RVA (rf);
 }
 
 }
 
-static void
-pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui, void *data)
+/* Swap in unwind info header.  */
+
+static bfd_boolean
+pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui,
+                      void *data, void *data_end)
 {
   struct external_pex64_unwind_info *ex_ui =
     (struct external_pex64_unwind_info *) data;
   bfd_byte *ex_dta = (bfd_byte *) data;
 {
   struct external_pex64_unwind_info *ex_ui =
     (struct external_pex64_unwind_info *) data;
   bfd_byte *ex_dta = (bfd_byte *) data;
+  bfd_byte *ex_dta_end = (bfd_byte *) data_end;
 
   memset (ui, 0, sizeof (struct pex64_unwind_info));
 
   memset (ui, 0, sizeof (struct pex64_unwind_info));
+
+  if (ex_dta >= ex_dta_end || ex_dta + 4 >= ex_dta_end)
+    return FALSE;
+
   ui->Version = PEX64_UWI_VERSION (ex_ui->Version_Flags);
   ui->Flags = PEX64_UWI_FLAGS (ex_ui->Version_Flags);
   ui->SizeOfPrologue = (bfd_vma) ex_ui->SizeOfPrologue;
   ui->Version = PEX64_UWI_VERSION (ex_ui->Version_Flags);
   ui->Flags = PEX64_UWI_FLAGS (ex_ui->Version_Flags);
   ui->SizeOfPrologue = (bfd_vma) ex_ui->SizeOfPrologue;
@@ -110,181 +120,262 @@ pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui, void *data)
   ui->FrameOffset = PEX64_UWI_FRAMEOFF (ex_ui->FrameRegisterOffset);
   ui->sizeofUnwindCodes = PEX64_UWI_SIZEOF_UWCODE_ARRAY (ui->CountOfCodes);
   ui->SizeOfBlock = ui->sizeofUnwindCodes + 4;
   ui->FrameOffset = PEX64_UWI_FRAMEOFF (ex_ui->FrameRegisterOffset);
   ui->sizeofUnwindCodes = PEX64_UWI_SIZEOF_UWCODE_ARRAY (ui->CountOfCodes);
   ui->SizeOfBlock = ui->sizeofUnwindCodes + 4;
-  ui->rawUnwindCodes = &ex_dta[4];
+  ui->rawUnwindCodes = ex_dta + 4;
+  ui->rawUnwindCodesEnd = ex_dta_end;
+
   ex_dta += ui->SizeOfBlock;
   ex_dta += ui->SizeOfBlock;
+  if (ex_dta >= ex_dta_end)
+    return FALSE;
+
   switch (ui->Flags)
     {
     case UNW_FLAG_CHAININFO:
   switch (ui->Flags)
     {
     case UNW_FLAG_CHAININFO:
-      ui->rva_FunctionEntry = bfd_get_32 (abfd, ex_dta);
+      if (ex_dta + 12 >= ex_dta_end)
+       return FALSE;
+      ui->rva_BeginAddress = bfd_get_32 (abfd, ex_dta + 0);
+      ui->rva_EndAddress = bfd_get_32 (abfd, ex_dta + 4);
+      ui->rva_UnwindData = bfd_get_32 (abfd, ex_dta + 8);
+      ui->SizeOfBlock += 12;
+      return TRUE;
+    case UNW_FLAG_EHANDLER:
+    case UNW_FLAG_UHANDLER:
+    case UNW_FLAG_FHANDLER:
+      if (ex_dta + 4 >= ex_dta_end)
+       return FALSE;
+      ui->rva_ExceptionHandler = bfd_get_32 (abfd, ex_dta);
       ui->SizeOfBlock += 4;
       ui->SizeOfBlock += 4;
-      return;
+      return TRUE;
     default:
     default:
-      return;
+      return TRUE;
     }
 }
 
     }
 }
 
+/* Display unwind codes.  */
+
 static void
 static void
-pex64_xdata_print_uwd_codes (FILE *file, struct pex64_unwind_info *ui,
-                            bfd_vma pc_addr)
+pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd,
+                            struct pex64_unwind_info *ui,
+                            struct pex64_runtime_function *rf)
 {
 {
-  bfd_vma i;
-  bfd_vma tmp = 0;
-  const bfd_byte *insns[256];
-  bfd_vma insns_count = 0;
-  const bfd_byte *dta = ui->rawUnwindCodes;
+  unsigned int i;
+  unsigned int tmp; /* At least 32 bits.  */
+  int save_allowed;
 
 
-  if (ui->CountOfCodes == 0 || !dta)
+  if (ui->CountOfCodes == 0 || ui->rawUnwindCodes == NULL)
     return;
 
     return;
 
-  /* Sort array ascending. Note: it is stored in reversed order.  */
-  for (i = 0; i < ui->CountOfCodes; i++)
+  /* According to UNWIND_CODE documentation:
+      If an FP reg is used, the any unwind code taking an offset must only be
+      used after the FP reg is established in the prolog.
+     But there are counter examples of that in system dlls...  */
+  save_allowed = TRUE;
+
+  i = 0;
+
+  if (ui->rawUnwindCodes + 1 >= ui->rawUnwindCodesEnd)
     {
     {
-      const bfd_byte *t;
+      fprintf (file, _("warning: corrupt unwind data\n"));
+      return;
+    }
 
 
-      t = insns[insns_count++] = &dta[i * 2];
-      switch (PEX64_UNWCODE_CODE (t[1]))
+  if (ui->Version == 2
+      && PEX64_UNWCODE_CODE (ui->rawUnwindCodes[1]) == UWOP_EPILOG)
+    {
+      /* 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;
+
+      if (ui->rawUnwindCodes + 1 + (ui->CountOfCodes * 2) >= ui->rawUnwindCodesEnd)
        {
        {
-       case UWOP_PUSH_NONVOL:
-       case UWOP_ALLOC_SMALL:
-       case UWOP_SET_FPREG:
-       case UWOP_PUSH_MACHFRAME:
-         break;
-       case UWOP_ALLOC_LARGE:
-         if (PEX64_UNWCODE_INFO (t[1]) == 0)
-           {
-             i += 1;
-             break;
-           }
-         else if (PEX64_UNWCODE_INFO (t[1]) == 1)
-           {
-             i += 2;
-             break;
-           }
-         /* fall through.  */
-       default:
-         fprintf (file, "\t contains unknown code (%u).\n",
-                  (unsigned int) PEX64_UNWCODE_CODE (t[1]));
+         fprintf (file, _("warning: corrupt unwind data\n"));
          return;
          return;
-       case UWOP_SAVE_NONVOL:
-       case UWOP_SAVE_XMM:
-       case UWOP_SAVE_XMM128:
-         i++;
-         break;
-       case UWOP_SAVE_NONVOL_FAR:
-       case UWOP_SAVE_XMM_FAR:
-       case UWOP_SAVE_XMM128_FAR:
-         i += 2;
-         break;
        }
        }
+
+      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]) != UWOP_EPILOG)
+           break;
+         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);
     }
     }
-  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;)
+
+  if (ui->rawUnwindCodes + 2 + (ui->CountOfCodes * 2) >= ui->rawUnwindCodesEnd)
     {
     {
-      --i;
-      dta = insns[i];
-      fprintf (file, "\t  insn ends at pc+0x%02x: ", (unsigned int) dta[0]);
+      fprintf (file, _("warning: corrupt unwind data\n"));
+      return;
+    }
+
+  for (; i < ui->CountOfCodes; i++)
+    {
+      const bfd_byte *dta = ui->rawUnwindCodes + 2 * i;
+      unsigned int info = PEX64_UNWCODE_INFO (dta[1]);
+      int unexpected = FALSE;
+
+      fprintf (file, "\t  pc+0x%02x: ", (unsigned int) dta[0]);
+
       switch (PEX64_UNWCODE_CODE (dta[1]))
        {
        case UWOP_PUSH_NONVOL:
       switch (PEX64_UNWCODE_CODE (dta[1]))
        {
        case UWOP_PUSH_NONVOL:
-         fprintf (file, "push %s.\n", pex_regs[PEX64_UNWCODE_INFO (dta[1])]);
+         fprintf (file, "push %s", pex_regs[info]);
          break;
          break;
+
        case UWOP_ALLOC_LARGE:
        case UWOP_ALLOC_LARGE:
-         if (PEX64_UNWCODE_INFO (dta[1]) == 0)
+         if (info == 0)
            {
            {
-             tmp = (bfd_vma) (*((unsigned short *) &dta[2]));
-             tmp *= 8;
+             if (dta + 4 > ui->rawUnwindCodesEnd)
+               {
+                 fprintf (file, _("warning: corrupt unwind data\n"));
+                 return;
+               }
+             tmp = bfd_get_16 (abfd, dta + 2) * 8;
+             i++;
            }
          else
            }
          else
-           tmp = (bfd_vma) (*((unsigned int *)&dta[2]));
-         fprintf (file, "save stack region of size 0x");
-         fprintf_vma (file, tmp);
-         fprintf (file,".\n");
+           {
+             if (dta + 6 > ui->rawUnwindCodesEnd)
+               {
+                 fprintf (file, _("warning: corrupt unwind data\n"));
+                 return;
+               }
+             tmp = bfd_get_32 (abfd, dta + 2);
+             i += 2;
+           }
+         fprintf (file, "alloc large area: rsp = rsp - 0x%x", tmp);
          break;
          break;
+
        case UWOP_ALLOC_SMALL:
        case UWOP_ALLOC_SMALL:
-         tmp = (bfd_vma) PEX64_UNWCODE_INFO (dta[1]);
-         tmp += 1;
-         tmp *= 8;
-         fprintf (file, "save stack region of size 0x");
-         fprintf_vma (file, tmp);
-         fprintf (file,".\n");
+         fprintf (file, "alloc small area: rsp = rsp - 0x%x", (info + 1) * 8);
          break;
          break;
+
        case UWOP_SET_FPREG:
        case UWOP_SET_FPREG:
-         tmp = (bfd_vma) PEX64_UNWCODE_INFO (dta[1]);
-         tmp *= 16;
-         fprintf (file, "FPReg = (FrameReg) + 0x");
-         fprintf_vma (file, tmp);
-         fprintf (file, ".\n");
+         /* According to the documentation, info field is unused.  */
+         fprintf (file, "FPReg: %s = rsp + 0x%x (info = 0x%x)",
+                  pex_regs[ui->FrameRegister],
+                  (unsigned int) ui->FrameOffset * 16, info);
+         unexpected = ui->FrameRegister == 0;
+         save_allowed = FALSE;
          break;
          break;
+
        case UWOP_SAVE_NONVOL:
        case UWOP_SAVE_NONVOL:
-         fprintf (file, "mov %s at 0x",
-                  pex_regs[PEX64_UNWCODE_INFO (dta[1])]);
-         tmp = (bfd_vma) (*((unsigned short *) &dta[2]));
-         tmp *= 8;
-         fprintf_vma (file, tmp);
-         fprintf (file, ".\n");
+         if (dta + 4 > ui->rawUnwindCodesEnd)
+           {
+             fprintf (file, _("warning: corrupt unwind data\n"));
+             return;
+           }
+         tmp = bfd_get_16 (abfd, dta + 2) * 8;
+         i++;
+         fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
+         unexpected = !save_allowed;
          break;
          break;
+
        case UWOP_SAVE_NONVOL_FAR:
        case UWOP_SAVE_NONVOL_FAR:
-         fprintf (file, "mov %s at 0x",
-                  pex_regs[PEX64_UNWCODE_INFO (dta[1])]);
-         tmp = (bfd_vma) (*((unsigned int *) &dta[2]));
-         fprintf_vma (file, tmp);
-         fprintf (file, ".\n");
+         if (dta + 6 > ui->rawUnwindCodesEnd)
+           {
+             fprintf (file, _("warning: corrupt unwind data\n"));
+             return;
+           }
+         tmp = bfd_get_32 (abfd, dta + 2);
+         i += 2;
+         fprintf (file, "save %s at rsp + 0x%x", pex_regs[info], tmp);
+         unexpected = !save_allowed;
          break;
          break;
+
        case UWOP_SAVE_XMM:
        case UWOP_SAVE_XMM:
-         tmp = (bfd_vma) (*((unsigned short *) &dta[2]));
-         tmp *= 8;
-         fprintf (file, "mov mm%u at 0x",
-                  (unsigned int) PEX64_UNWCODE_INFO (dta[1]));
-         fprintf_vma (file, tmp);
-         fprintf (file, ".\n");
+         if (ui->Version == 1)
+           {
+             if (dta + 4 > ui->rawUnwindCodesEnd)
+               {
+                 fprintf (file, _("warning: corrupt unwind data\n"));
+                 return;
+               }
+             tmp = bfd_get_16 (abfd, dta + 2) * 8;
+             i++;
+             fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
+             unexpected = !save_allowed;
+           }
+         else if (ui->Version == 2)
+           {
+             fprintf (file, "epilog %02x %01x", dta[0], info);
+             unexpected = TRUE;
+           }
          break;
          break;
+
        case UWOP_SAVE_XMM_FAR:
        case UWOP_SAVE_XMM_FAR:
-         tmp = (bfd_vma) (*((unsigned int *) &dta[2]));
-         fprintf (file, "mov mm%u at 0x",
-                  (unsigned int) PEX64_UNWCODE_INFO (dta[1]));
-         fprintf_vma (file, tmp);
-         fprintf (file, ".\n");
+         if (dta + 6 > ui->rawUnwindCodesEnd)
+           {
+             fprintf (file, _("warning: corrupt unwind data\n"));
+             return;
+           }
+         tmp = bfd_get_32 (abfd, dta + 2) * 8;
+         i += 2;
+         fprintf (file, "save mm%u at rsp + 0x%x", info, tmp);
+         unexpected = !save_allowed;
          break;
          break;
+
        case UWOP_SAVE_XMM128:
        case UWOP_SAVE_XMM128:
-         tmp = (bfd_vma) (*((unsigned short *) &dta[2]));
-         tmp *= 16;
-         fprintf (file, "mov xmm%u at 0x",
-                  (unsigned int) PEX64_UNWCODE_INFO ( dta[1]));
-         fprintf_vma (file, tmp);
-         fprintf (file, ".\n");
+         if (dta + 4 > ui->rawUnwindCodesEnd)
+           {
+             fprintf (file, _("warning: corrupt unwind data\n"));
+             return;
+           }
+         tmp = bfd_get_16 (abfd, dta + 2) * 16;
+         i++;
+         fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
+         unexpected = !save_allowed;
          break;
          break;
+
        case UWOP_SAVE_XMM128_FAR:
        case UWOP_SAVE_XMM128_FAR:
-         tmp = (bfd_vma) (*((unsigned int *) &dta[2]));
-         fprintf (file, "mov xmm%u at 0x",
-                  (unsigned int) PEX64_UNWCODE_INFO (dta[1]));
-         fprintf_vma (file, tmp);
-         fprintf (file, ".\n");
+         if (dta + 6 > ui->rawUnwindCodesEnd)
+           {
+             fprintf (file, _("warning: corrupt unwind data\n"));
+             return;
+           }
+         tmp = bfd_get_32 (abfd, dta + 2) * 16;
+         i += 2;
+         fprintf (file, "save xmm%u at rsp + 0x%x", info, tmp);
+         unexpected = !save_allowed;
          break;
          break;
+
        case UWOP_PUSH_MACHFRAME:
          fprintf (file, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP");
        case UWOP_PUSH_MACHFRAME:
          fprintf (file, "interrupt entry (SS, old RSP, EFLAGS, CS, RIP");
-         if (PEX64_UNWCODE_INFO (dta[1]) == 0)
-           {
-             fprintf (file, ")");
-           }
-         else if (PEX64_UNWCODE_INFO (dta[1]) == 1)
-           {
-             fprintf (file, ",ErrorCode)");
-           }
+         if (info == 0)
+           fprintf (file, ")");
+         else if (info == 1)
+           fprintf (file, ",ErrorCode)");
          else
          else
-           fprintf (file, ", unknown(%u))",
-                    (unsigned int) PEX64_UNWCODE_INFO (dta[1]));
-         fprintf (file,".\n");
+           fprintf (file, ", unknown(%u))", info);
          break;
          break;
+
        default:
        default:
-         fprintf (file, "unknown code %u.\n",
-                  (unsigned int) PEX64_UNWCODE_INFO (dta[1]));
+         /* PR 17512: file: 2245-7442-0.004.  */
+         fprintf (file, _("Unknown: %x"), PEX64_UNWCODE_CODE (dta[1]));
          break;
          break;
-      }
+       }
+
+      if (unexpected)
+       fprintf (file, " [Unexpected!]");
+      fputc ('\n', file);
     }
 }
 
     }
 }
 
+/* Check wether section SEC_NAME contains the xdata at address ADDR.  */
+
 static asection *
 pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name)
 {
 static asection *
 pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name)
 {
@@ -303,110 +394,148 @@ pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name)
   return section;
 }
 
   return section;
 }
 
+/* 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
 static void
-pex64_dump_xdata (FILE *file, bfd *abfd, bfd_vma addr, bfd_vma pc_addr,
-                 bfd_vma *endx)
+pex64_dump_xdata (FILE *file, bfd *abfd,
+                 asection *xdata_section, bfd_byte *xdata, bfd_vma *endx,
+                 struct pex64_runtime_function *rf)
 {
 {
-  asection *section = pex64_get_section_by_rva (abfd, addr, ".rdata");
-  bfd_vma vsize;
-  bfd_byte *data = NULL;
+  bfd_vma vaddr;
   bfd_vma end_addr;
   bfd_vma end_addr;
+  bfd_vma addr = rf->rva_UnwindData;
+  bfd_size_type sec_size = xdata_section->rawsize > 0 ? xdata_section->rawsize : xdata_section->size;
+  struct pex64_unwind_info ui;
+
+  vaddr = xdata_section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
+  addr -= vaddr;
 
 
-  if (!section)
-    section = pex64_get_section_by_rva (abfd, addr, ".data");
-  if (!section)
-    section = pex64_get_section_by_rva (abfd, addr, ".xdata");
-  if (!section)
+  /* PR 17512: file: 2245-7442-0.004.  */
+  if (addr >= sec_size)
     {
     {
-      section = pex64_get_section_by_rva (abfd, addr, ".pdata");
-      if (section)
-       {
-         fprintf (file, "\t Shares information with pdata element at 0x");
-         fprintf_vma (file, addr + pe_data (abfd)->pe_opthdr.ImageBase);
-         fprintf (file, ".\n");
-       }
+      fprintf (file, _("warning: xdata section corrupt\n"));
+      return;
     }
     }
-  if (!section)
-    return;
-
-  vsize = section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
-  addr -= vsize;
 
   if (endx)
 
   if (endx)
-    end_addr = endx[0] - vsize;
+    {
+      end_addr = endx[0] - vaddr;
+      /* PR 17512: file: 2245-7442-0.004.  */
+      if (end_addr > sec_size)
+       {
+         fprintf (file, _("warning: xdata section corrupt\n"));
+         end_addr = sec_size;
+       }
+    }
   else
   else
-    end_addr = (section->rawsize != 0 ? section->rawsize : section->size);
+    end_addr = sec_size;
 
 
-  if (bfd_malloc_and_get_section (abfd, section, &data))
+  if (! pex64_get_unwind_info (abfd, &ui, xdata + addr, xdata + end_addr))
     {
     {
-      struct pex64_unwind_info ui;
-
-      if (!data)
-       return;
-
-      pex64_get_unwind_info (abfd, &ui, &data[addr]);
+      fprintf (file, _("warning: xdata section corrupt\n"));
+      return;
+    }
 
 
-      if (ui.Version != 1)
+  if (ui.Version != 1 && ui.Version != 2)
+    {
+      unsigned int i;
+      fprintf (file, "\tVersion %u (unknown).\n",
+              (unsigned int) ui.Version);
+      for (i = 0; addr < end_addr; addr += 1, i++)
        {
        {
-         fprintf (file, "\tVersion %u (unknown).\n", (unsigned int) ui.Version);
-         return;
+         if ((i & 15) == 0)
+           fprintf (file, "\t  %03x:", i);
+         fprintf (file, " %02x", xdata[addr]);
+         if ((i & 15) == 15)
+           fprintf (file, "\n");
        }
        }
+      if ((i & 15) != 0)
+       fprintf (file, "\n");
+      return;
+    }
 
 
-      fprintf (file, "\tFlags: ");
-      switch (ui.Flags)
-       {
-       case UNW_FLAG_NHANDLER:
-         fprintf (file, "UNW_FLAG_NHANDLER");
-         break;
-       case UNW_FLAG_EHANDLER:
-         fprintf (file, "UNW_FLAG_EHANDLER");
-         break;
-       case UNW_FLAG_UHANDLER:
-         fprintf (file, "UNW_FLAG_UHANDLER");
-         break;
-       case UNW_FLAG_FHANDLER:
-         fprintf (file, "UNW_FLAG_FHANDLER = (UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER)");
-         break;
-       case UNW_FLAG_CHAININFO:
-         fprintf (file, "UNW_FLAG_CHAININFO");
-         break;
-       default:
-         fprintf (file, "unknown flags value 0x%x", (unsigned int) ui.Flags);
-         break;
-       }
+  fprintf (file, "\tVersion: %d, Flags: ", ui.Version);
+  switch (ui.Flags)
+    {
+    case UNW_FLAG_NHANDLER:
+      fprintf (file, "none");
+      break;
+    case UNW_FLAG_EHANDLER:
+      fprintf (file, "UNW_FLAG_EHANDLER");
+      break;
+    case UNW_FLAG_UHANDLER:
+      fprintf (file, "UNW_FLAG_UHANDLER");
+      break;
+    case UNW_FLAG_FHANDLER:
+      fprintf
+       (file, "UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER");
+      break;
+    case UNW_FLAG_CHAININFO:
+      fprintf (file, "UNW_FLAG_CHAININFO");
+      break;
+    default:
+      fprintf (file, "unknown flags value 0x%x", (unsigned int) ui.Flags);
+      break;
+    }
+  fputc ('\n', file);
+  fprintf (file, "\tNbr codes: %u, ", (unsigned int) ui.CountOfCodes);
+  fprintf (file, "Prologue size: 0x%02x, Frame offset: 0x%x, ",
+          (unsigned int) ui.SizeOfPrologue, (unsigned int) ui.FrameOffset);
+  fprintf (file, "Frame reg: %s\n",
+          ui.FrameRegister == 0 ? "none"
+          : pex_regs[(unsigned int) ui.FrameRegister]);
+
+  /* PR 17512: file: 2245-7442-0.004.  */
+  if (ui.CountOfCodes * 2 + ui.rawUnwindCodes > xdata + xdata_section->size)
+    fprintf (file, _("Too many unwind codes (%ld)\n"), (long) ui.CountOfCodes);
+  else
+    pex64_xdata_print_uwd_codes (file, abfd, &ui, rf);
+
+  switch (ui.Flags)
+    {
+    case UNW_FLAG_EHANDLER:
+    case UNW_FLAG_UHANDLER:
+    case UNW_FLAG_FHANDLER:
+      fprintf (file, "\tHandler: ");
+      fprintf_vma (file, (ui.rva_ExceptionHandler
+                         + pe_data (abfd)->pe_opthdr.ImageBase));
       fprintf (file, ".\n");
       fprintf (file, ".\n");
-      if (ui.CountOfCodes != 0)
-       fprintf (file, "\tEntry has %u codes.", (unsigned int) ui.CountOfCodes);
-      fprintf (file, "\tPrologue size: %u, Frame offset = 0x%x.\n",
-              (unsigned int) ui.SizeOfPrologue, (unsigned int) ui.FrameOffset);
-      fprintf (file, "\tFrame register is %s.\n",
-       ui.FrameRegister == 0 ? "none"
-                             : pex_regs[(unsigned int) ui.FrameRegister]);
-
-      pex64_xdata_print_uwd_codes (file, &ui, pc_addr);
-      
-      /* Now we need end of this xdata block.  */
-      addr += ui.SizeOfBlock;
-      if (addr < end_addr)
-        {
-         unsigned int i;
-         fprintf (file,"\tUser data:\n");
-         for (i = 0; addr < end_addr; addr += 1, i++)
-           {
-             if ((i & 15) == 0)
-               fprintf (file, "\t  %03x:", i);
-             fprintf (file, " %02x", data[addr]);
-             if ((i & 15) == 15)
-               fprintf (file, "\n");
-           }
-         if ((i & 15) != 0)
+      break;
+    case UNW_FLAG_CHAININFO:
+      fprintf (file, "\tChain: start: ");
+      fprintf_vma (file, ui.rva_BeginAddress);
+      fprintf (file, ", end: ");
+      fprintf_vma (file, ui.rva_EndAddress);
+      fprintf (file, "\n\t unwind data: ");
+      fprintf_vma (file, ui.rva_UnwindData);
+      fprintf (file, ".\n");
+      break;
+    }
+
+  /* Now we need end of this xdata block.  */
+  addr += ui.SizeOfBlock;
+  if (addr < end_addr)
+    {
+      unsigned int i;
+      fprintf (file,"\tUser data:\n");
+      for (i = 0; addr < end_addr; addr += 1, i++)
+       {
+         if ((i & 15) == 0)
+           fprintf (file, "\t  %03x:", i);
+         fprintf (file, " %02x", xdata[addr]);
+         if ((i & 15) == 15)
            fprintf (file, "\n");
            fprintf (file, "\n");
-        }
+       }
+      if ((i & 15) != 0)
+       fprintf (file, "\n");
     }
     }
-  if (data != NULL)
-    free (data);
 }
 
 }
 
+/* Helper function to sort xdata.  The entries of xdata are sorted to know
+   the size of each entry.  */
+
 static int
 sort_xdata_arr (const void *l, const void *r)
 {
 static int
 sort_xdata_arr (const void *l, const void *r)
 {
@@ -418,78 +547,114 @@ sort_xdata_arr (const void *l, const void *r)
   return (*lp < *rp ? -1 : 1);
 }
 
   return (*lp < *rp ? -1 : 1);
 }
 
+/* Display unwind tables for x86-64.  */
+
 static bfd_boolean
 static bfd_boolean
-pex64_bfd_print_pdata (bfd *abfd, void *vfile)
+pex64_bfd_print_pdata_section (bfd *abfd, void *vfile, asection *pdata_section)
 {
   FILE *file = (FILE *) vfile;
 {
   FILE *file = (FILE *) vfile;
-  bfd_byte *data = NULL;
-  asection *section = bfd_get_section_by_name (abfd, ".pdata");
-  bfd_size_type datasize = 0;
+  bfd_byte *pdata = NULL;
+  bfd_byte *xdata = NULL;
+  asection *xdata_section = NULL;
+  bfd_vma xdata_base;
   bfd_size_type i;
   bfd_size_type i;
+  bfd_size_type datasize;
   bfd_size_type stop;
   bfd_size_type stop;
-  bfd_vma prev_beginaddress = 0;
+  bfd_vma prev_beginaddress = (bfd_vma) -1;
+  bfd_vma prev_unwinddata_rva = (bfd_vma) -1;
+  bfd_vma imagebase;
   int onaline = PDATA_ROW_SIZE;
   int seen_error = 0;
   int onaline = PDATA_ROW_SIZE;
   int seen_error = 0;
-  bfd_vma *xdata_arr;
+  bfd_vma *xdata_arr = NULL;
   int xdata_arr_cnt;
   int xdata_arr_cnt;
+  bfd_boolean virt_size_is_zero = FALSE;
 
 
-  if (section == NULL
-      || coff_section_data (abfd, section) == NULL
-      || pei_section_data (abfd, section) == NULL)
+  /* Sanity checks.  */
+  if (pdata_section == NULL
+      || coff_section_data (abfd, pdata_section) == NULL
+      || pei_section_data (abfd, pdata_section) == NULL)
     return TRUE;
 
     return TRUE;
 
-  stop = pei_section_data (abfd, section)->virt_size;
+  stop = pei_section_data (abfd, pdata_section)->virt_size;
   if ((stop % onaline) != 0)
     fprintf (file,
   if ((stop % onaline) != 0)
     fprintf (file,
-            _("warning: .pdata section size (%ld) is not a multiple of %d\n"),
-            (long) stop, onaline);
+            /* xgettext:c-format */
+            _("Warning: %s section size (%ld) is not a multiple of %d\n"),
+            pdata_section->name, (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;
+  datasize = pdata_section->size;
   if (datasize == 0)
   if (datasize == 0)
-    return TRUE;
+    {
+      if (stop)
+       fprintf (file, _("Warning: %s section size is zero\n"),
+                pdata_section->name);
+      return TRUE;
+    }
 
 
-  if (!bfd_malloc_and_get_section (abfd, section, &data))
+  /* virt_size might be zero for objects.  */
+  if (stop == 0 && strcmp (abfd->xvec->name, "pe-x86-64") == 0)
     {
     {
-      if (data != NULL)
-       free (data);
-      return FALSE;
+      stop = datasize;
+      virt_size_is_zero = TRUE;
     }
     }
+  else if (datasize < stop)
+      {
+       fprintf (file,
+                /* xgettext:c-format */
+                _("Warning: %s section size (%ld) is smaller than virtual size (%ld)\n"),
+                pdata_section->name, (unsigned long) datasize,
+                (unsigned long) stop);
+       /* Be sure not to read past datasize.  */
+       stop = datasize;
+      }
 
 
+  /* Display functions table.  */
+  fprintf (file,
+          _("\nThe Function Table (interpreted %s section contents)\n"),
+          pdata_section->name);
+
+  fprintf (file, _("vma:\t\t\tBeginAddress\t EndAddress\t  UnwindData\n"));
+
+  if (!bfd_malloc_and_get_section (abfd, pdata_section, &pdata))
+    goto done;
+
+  /* Table of xdata entries.  */
   xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1));
   xdata_arr_cnt = 0;
   xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1));
   xdata_arr_cnt = 0;
-  /* Do sanity check of pdata.  */
+
+  if (strcmp (abfd->xvec->name, "pei-x86-64") == 0)
+    imagebase = pe_data (abfd)->pe_opthdr.ImageBase;
+  else
+    imagebase = 0;
+
   for (i = 0; i < stop; i += onaline)
     {
       struct pex64_runtime_function rf;
 
       if (i + PDATA_ROW_SIZE > stop)
        break;
   for (i = 0; i < stop; i += onaline)
     {
       struct pex64_runtime_function rf;
 
       if (i + PDATA_ROW_SIZE > stop)
        break;
-      pex64_get_runtime_function (abfd, &rf, &data[i]);
+
+      pex64_get_runtime_function (abfd, &rf, &pdata[i]);
 
       if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
          && rf.rva_UnwindData == 0)
        /* We are probably into the padding of the section now.  */
        break;
       fputc (' ', file);
 
       if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
          && rf.rva_UnwindData == 0)
        /* We are probably into the padding of the section now.  */
        break;
       fputc (' ', file);
-      fprintf_vma (file, i + section->vma);
+      fprintf_vma (file, i + pdata_section->vma);
       fprintf (file, ":\t");
       fprintf (file, ":\t");
-      fprintf_vma (file, rf.rva_BeginAddress);
-      fputc (' ', file);
-      fprintf_vma (file, rf.rva_EndAddress);
-      fputc (' ', file);
-      fprintf_vma (file, rf.rva_UnwindData);
+      fprintf_vma (file, imagebase + rf.rva_BeginAddress);
+      fprintf (file, " ");
+      fprintf_vma (file, imagebase + rf.rva_EndAddress);
+      fprintf (file, " ");
+      fprintf_vma (file, imagebase + rf.rva_UnwindData);
       fprintf (file, "\n");
       if (i != 0 && rf.rva_BeginAddress <= prev_beginaddress)
        {
          seen_error = 1;
          fprintf (file, "  has %s begin address as predecessor\n",
            (rf.rva_BeginAddress < prev_beginaddress ? "smaller" : "same"));
       fprintf (file, "\n");
       if (i != 0 && rf.rva_BeginAddress <= prev_beginaddress)
        {
          seen_error = 1;
          fprintf (file, "  has %s begin address as predecessor\n",
            (rf.rva_BeginAddress < prev_beginaddress ? "smaller" : "same"));
-        }
+       }
       prev_beginaddress = rf.rva_BeginAddress;
       /* Now we check for negative addresses.  */
       if ((prev_beginaddress & 0x80000000) != 0)
       prev_beginaddress = rf.rva_BeginAddress;
       /* Now we check for negative addresses.  */
       if ((prev_beginaddress & 0x80000000) != 0)
@@ -507,17 +672,13 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
          seen_error = 1;
          fprintf (file, "  has negative unwind address\n");
        }
          seen_error = 1;
          fprintf (file, "  has negative unwind address\n");
        }
-      if (rf.rva_UnwindData && !rf.isChained)
-        xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData;
+      else if ((rf.rva_UnwindData && !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
+               || virt_size_is_zero)
+       xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData;
     }
 
   if (seen_error)
     }
 
   if (seen_error)
-    {
-      free (data);
-      free (xdata_arr);
-
-      return TRUE;
-    }
+    goto done;
 
   /* Add end of list marker.  */
   xdata_arr[xdata_arr_cnt++] = ~((bfd_vma) 0);
 
   /* Add end of list marker.  */
   xdata_arr[xdata_arr_cnt++] = ~((bfd_vma) 0);
@@ -527,35 +688,104 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
     qsort (xdata_arr, (size_t) xdata_arr_cnt, sizeof (bfd_vma),
           sort_xdata_arr);
 
     qsort (xdata_arr, (size_t) xdata_arr_cnt, sizeof (bfd_vma),
           sort_xdata_arr);
 
-  /* Do dump of pdata related xdata.  */
+  /* Find the section containing the unwind data (.xdata).  */
+  xdata_base = xdata_arr[0];
+  /* For sections with long names, first look for the same
+     section name, replacing .pdata by .xdata prefix.  */
+  if (strcmp (pdata_section->name, ".pdata") != 0)
+    {
+      size_t len = strlen (pdata_section->name);
+      char *xdata_name = xmalloc (len + 1);
+
+      xdata_name = memcpy (xdata_name, pdata_section->name, len + 1);
+      /* Transform .pdata prefix into .xdata prefix.  */
+      if (len > 1)
+       xdata_name [1] = 'x';
+      xdata_section = pex64_get_section_by_rva (abfd, xdata_base,
+                                               xdata_name);
+      free (xdata_name);
+    }
+  /* Second, try the .xdata section itself.  */
+  if (!xdata_section)
+    xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".xdata");
+  /* Otherwise, if xdata_base is non zero, search also inside
+     other standard sections.  */
+  if (!xdata_section && xdata_base)
+    xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".rdata");
+  if (!xdata_section && xdata_base)
+    xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".data");
+  if (!xdata_section && xdata_base)
+    xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".pdata");
+  if (!xdata_section && xdata_base)
+    xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".text");
+  /* Transfer xdata section into xdata array.  */
+  if (!xdata_section
+      || !bfd_malloc_and_get_section (abfd, xdata_section, &xdata))
+    goto done;
+
+  /* Avoid "also used "... ouput for single unwind info
+     in object file.  */
+  prev_unwinddata_rva = (bfd_vma) -1;
 
 
+  /* Do dump of pdata related xdata.  */
   for (i = 0; i < stop; i += onaline)
     {
       struct pex64_runtime_function rf;
 
       if (i + PDATA_ROW_SIZE > stop)
        break;
   for (i = 0; i < stop; i += onaline)
     {
       struct pex64_runtime_function rf;
 
       if (i + PDATA_ROW_SIZE > stop)
        break;
-      pex64_get_runtime_function (abfd, &rf, &data[i]);
+
+      pex64_get_runtime_function (abfd, &rf, &pdata[i]);
 
       if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
          && rf.rva_UnwindData == 0)
        /* We are probably into the padding of the section now.  */
        break;
       if (i == 0)
 
       if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
          && rf.rva_UnwindData == 0)
        /* We are probably into the padding of the section now.  */
        break;
       if (i == 0)
-        fprintf (file, "\nDump of .xdata\n");
+       fprintf (file, _("\nDump of %s\n"), xdata_section->name);
+
       fputc (' ', file);
       fputc (' ', file);
-      fprintf_vma (file, rf.rva_UnwindData);
-      fprintf (file, ":\n");
+      fprintf_vma (file, rf.rva_UnwindData + imagebase);
 
 
-      rf.rva_BeginAddress += pe_data (abfd)->pe_opthdr.ImageBase;
-      rf.rva_EndAddress += pe_data (abfd)->pe_opthdr.ImageBase;
+      if (prev_unwinddata_rva == rf.rva_UnwindData)
+       {
+         /* Do not dump again the xdata for the same entry.  */
+         fprintf (file, " also used for function at ");
+         fprintf_vma (file, rf.rva_BeginAddress + imagebase);
+         fputc ('\n', file);
+         continue;
+       }
+      else
+       prev_unwinddata_rva = rf.rva_UnwindData;
+
+      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)
+      if (rf.rva_UnwindData != 0 || virt_size_is_zero)
        {
        {
-         if (rf.isChained)
+         if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
            {
            {
-             fprintf (file, "\t shares information with pdata element at 0x");
-             fprintf_vma (file, rf.rva_UnwindData);
+             bfd_vma altent = PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf);
+             bfd_vma pdata_vma = bfd_section_vma (pdata_section);
+             struct pex64_runtime_function arf;
+
+             fprintf (file, "\t shares information with ");
+             altent += imagebase;
+
+             if (altent >= pdata_vma
+                 && altent - pdata_vma + PDATA_ROW_SIZE <= stop)
+               {
+                 pex64_get_runtime_function
+                   (abfd, &arf, &pdata[altent - pdata_vma]);
+                 fprintf (file, "pdata element at 0x");
+                 fprintf_vma (file, arf.rva_UnwindData);
+               }
+             else
+               fprintf (file, "unknown pdata element");
              fprintf (file, ".\n");
            }
          else
              fprintf (file, ".\n");
            }
          else
@@ -564,7 +794,7 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
 
              /* Search for the current entry in the sorted array.  */
              p = (bfd_vma *)
 
              /* Search for the current entry in the sorted array.  */
              p = (bfd_vma *)
-                 bsearch (&rf.rva_UnwindData, xdata_arr,
+                 bsearch (&rf.rva_UnwindData, xdata_arr,
                           (size_t) xdata_arr_cnt, sizeof (bfd_vma),
                           sort_xdata_arr);
 
                           (size_t) xdata_arr_cnt, sizeof (bfd_vma),
                           sort_xdata_arr);
 
@@ -573,21 +803,54 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
                 identical pointers in the array; advance past all of them.  */
              while (p[0] <= rf.rva_UnwindData)
                ++p;
                 identical pointers in the array; advance past all of them.  */
              while (p[0] <= rf.rva_UnwindData)
                ++p;
+
              if (p[0] == ~((bfd_vma) 0))
                p = NULL;
 
              if (p[0] == ~((bfd_vma) 0))
                p = NULL;
 
-             pex64_dump_xdata (file, abfd, rf.rva_UnwindData,
-                               rf.rva_BeginAddress, p);
+             pex64_dump_xdata (file, abfd, xdata_section, xdata, p, &rf);
            }
        }
     }
 
            }
        }
     }
 
-  free (data);
+ done:
+  free (pdata);
   free (xdata_arr);
   free (xdata_arr);
+  free (xdata);
 
   return TRUE;
 }
 
 
   return TRUE;
 }
 
+/* Static counter of number of found pdata sections.  */
+static bfd_boolean pdata_count;
+
+/* Functionn prototype.  */
+bfd_boolean pex64_bfd_print_pdata (bfd *, void *);
+
+/* Helper function for bfd_map_over_section.  */
+static void
+pex64_print_all_pdata_sections (bfd *abfd, asection *pdata, void *obj)
+{
+  if (CONST_STRNEQ (pdata->name, ".pdata"))
+    {
+      if (pex64_bfd_print_pdata_section (abfd, obj, pdata))
+       pdata_count++;
+    }
+}
+
+bfd_boolean
+pex64_bfd_print_pdata (bfd *abfd, void *vfile)
+{
+  asection *pdata_section = bfd_get_section_by_name (abfd, ".pdata");
+
+  if (pdata_section)
+    return pex64_bfd_print_pdata_section (abfd, vfile, pdata_section);
+
+  pdata_count = 0;
+  bfd_map_over_sections (abfd, pex64_print_all_pdata_sections, vfile);
+  return (pdata_count > 0);
+}
+
 #define bfd_pe_print_pdata   pex64_bfd_print_pdata
 #define bfd_pe_print_pdata   pex64_bfd_print_pdata
+#define bfd_coff_std_swap_table bfd_coff_pei_swap_table
 
 #include "coff-x86_64.c"
 
 #include "coff-x86_64.c"
This page took 0.050826 seconds and 4 git commands to generate.