2010-09-15 Kai Tietz <kai.tietz@onevision.com>
authorKai Tietz <kai.tietz@onevision.com>
Wed, 15 Sep 2010 17:27:30 +0000 (17:27 +0000)
committerKai Tietz <kai.tietz@onevision.com>
Wed, 15 Sep 2010 17:27:30 +0000 (17:27 +0000)
        * pei-x86_64.c (pex64_get_unwind_info): Reorgnized.
        (pex64_get_scope_entry): Removed.
        (find_next_xdata_or_end): New helper.
        (pex64_dump_xdata): Reworked.
        (pex64_bfd_print_pdata): Add checking for
        valid pdata sorting and values. Reworked
        output.

bfd/ChangeLog
bfd/pei-x86_64.c

index 84b6be633a4a799c9f198e1929201edadc96391f..f5f69258f3db231e87e48829e0721b1fbeb9cf1d 100644 (file)
@@ -1,3 +1,13 @@
+2010-09-15  Kai Tietz  <kai.tietz@onevision.com>
+
+       * pei-x86_64.c (pex64_get_unwind_info): Reorgnized.
+       (pex64_get_scope_entry): Removed.
+       (find_next_xdata_or_end): New helper.
+       (pex64_dump_xdata): Reworked.
+       (pex64_bfd_print_pdata): Add checking for
+       valid pdata sorting and values. Reworked
+       output.
+
 2010-09-15  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR binutils/12004
index f5070049b3cf9d9775eacac67de0794ecc446e88..76009f3915557800a78561e3ef1c284a72636501 100644 (file)
@@ -114,17 +114,6 @@ pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui, void *data)
   ex_dta += ui->SizeOfBlock;
   switch (ui->Flags)
     {
-    case UNW_FLAG_EHANDLER:
-      ui->rva_ExceptionHandler = bfd_get_32 (abfd, ex_dta);
-      break;
-    case UNW_FLAG_UHANDLER:
-      ui->rva_TerminationHandler = bfd_get_32 (abfd, ex_dta);
-      break;
-    case UNW_FLAG_FHANDLER:
-      ui->rva_FrameHandler = bfd_get_32 (abfd, ex_dta);
-      ui->FrameHandlerArgument = bfd_get_32 (abfd, ex_dta + 4);
-      ui->SizeOfBlock += 8;
-      return;
     case UNW_FLAG_CHAININFO:
       ui->rva_FunctionEntry = bfd_get_32 (abfd, ex_dta);
       ui->SizeOfBlock += 4;
@@ -132,26 +121,6 @@ pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui, void *data)
     default:
       return;
     }
-  ex_dta += 4;
-  ui->SizeOfBlock += 8;
-  ui->CountOfScopes = bfd_get_32 (abfd, ex_dta);
-  ex_dta += 4;
-  ui->rawScopeEntries = ex_dta;
-  ui->SizeOfBlock += (ui->CountOfScopes * PEX64_SCOPE_ENTRY_SIZE);
-}
-
-static void
-pex64_get_scope_entry (bfd *abfd, struct pex64_scope_entry *se,
-                      bfd_vma idx, const bfd_byte *x)
-{
-  const struct external_pex64_scope_entry *ex_se;
-  x += (idx * PEX64_SCOPE_ENTRY_SIZE);
-  ex_se = (const struct external_pex64_scope_entry *) x;
-  memset (se, 0, sizeof (struct pex64_scope_entry));
-  se->rva_BeginAddress = bfd_get_32 (abfd, ex_se->rva_BeginAddress);
-  se->rva_EndAddress = bfd_get_32 (abfd, ex_se->rva_EndAddress);
-  se->rva_HandlerAddress = bfd_get_32 (abfd, ex_se->rva_HandlerAddress);
-  se->rva_JumpAddress = bfd_get_32 (abfd, ex_se->rva_JumpAddress);
 }
 
 static void
@@ -334,13 +303,46 @@ pex64_get_section_by_rva (bfd *abfd, bfd_vma addr, const char *sec_name)
   return section;
 }
 
+static bfd_vma
+find_next_xdata_or_end (bfd *abfd, bfd_byte *pdata, bfd_size_type stop,
+                       int onaline, bfd_vma cur_address, bfd_vma max_size)
+{
+  bfd_size_type i;
+  bfd_vma ret = 0;
+
+  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, &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 (rf.rva_UnwindData != 0 && !rf.isChained)
+        {
+         if (!ret && rf.rva_UnwindData > cur_address)
+           ret = rf.rva_UnwindData;
+         else if (rf.rva_UnwindData > cur_address && ret > rf.rva_UnwindData)
+           ret = rf.rva_UnwindData;
+       }
+    }
+  if (!ret)
+    return max_size;
+  return ret;
+}
+
 static void
-pex64_dump_xdata (FILE *file, bfd *abfd, bfd_vma addr, bfd_vma pc_addr)
+pex64_dump_xdata (FILE *file, bfd *abfd, bfd_vma addr, bfd_vma pc_addr,
+                 bfd_size_type stop, int onaline, bfd_byte *pdata)
 {
   asection *section = pex64_get_section_by_rva (abfd, addr, ".rdata");
   bfd_vma vsize;
   bfd_byte *data = NULL;
-  bfd_vma i;
+  bfd_vma end_addr;
 
   if (!section)
     section = pex64_get_section_by_rva (abfd, addr, ".data");
@@ -358,8 +360,14 @@ pex64_dump_xdata (FILE *file, bfd *abfd, bfd_vma addr, bfd_vma pc_addr)
     }
   if (!section)
     return;
+
   vsize = section->vma - pe_data (abfd)->pe_opthdr.ImageBase;
   addr -= vsize;
+
+  end_addr = find_next_xdata_or_end (abfd, pdata, stop, onaline, addr + vsize,
+                                    vsize + (section->rawsize != 0 ? section->rawsize : section->size));
+
+  end_addr -= vsize;
   if (bfd_malloc_and_get_section (abfd, section, &data))
     {
       struct pex64_unwind_info ui;
@@ -408,40 +416,23 @@ pex64_dump_xdata (FILE *file, bfd *abfd, bfd_vma addr, bfd_vma pc_addr)
 
       pex64_xdata_print_uwd_codes (file, &ui, pc_addr);
       
-      switch (ui.Flags)
-       {
-       case UNW_FLAG_NHANDLER:
-         return;
-       case UNW_FLAG_EHANDLER:
-         fprintf (file, "\texception_handler at 0x%x.\n", (unsigned int) ui.rva_ExceptionHandler);
-         break;
-       case UNW_FLAG_UHANDLER:
-         fprintf (file, "\ttermination_handler at 0x%x.\n", (unsigned int) ui.rva_TerminationHandler);
-       case UNW_FLAG_FHANDLER:
-         fprintf (file, "\tframe_handler at 0x%x.\n", (unsigned int) ui.rva_FrameHandler);
-         fprintf (file, "\t Argument for FrameHandler: 0x%x.\n",
-                  (unsigned int) ui.FrameHandlerArgument);
-         return;
-       case UNW_FLAG_CHAININFO:
-         fprintf (file, "\t Function Entry: 0x%x\n", (unsigned int) ui.rva_FunctionEntry);
-         return;
-       default:
-         fprintf (file, "\t Unknown flag value of 0x%x\n", (unsigned int) ui.Flags);
-         return;
-       }
-      fprintf (file, "\t 0x%x # of scope(s)\n", (unsigned int) ui.CountOfScopes);
-      for (i = 0; i < ui.CountOfScopes; i++)
-       {
-         struct pex64_scope_entry se;
-         pex64_get_scope_entry (abfd, &se, i, ui.rawScopeEntries);
-         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) se.rva_BeginAddress,
-                  (unsigned int) se.rva_EndAddress,
-                  (unsigned int) se.rva_HandlerAddress,
-                  (unsigned int) se.rva_JumpAddress);
-       }
+      /* 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)
+           fprintf (file, "\n");
+        }
     }
   if (data != NULL)
     free (data);
@@ -455,8 +446,10 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
   asection *section = bfd_get_section_by_name (abfd, ".pdata");
   bfd_size_type datasize = 0;
   bfd_size_type i;
-  bfd_size_type start, stop;
+  bfd_size_type stop;
+  bfd_vma prev_beginaddress = 0;
   int onaline = PDATA_ROW_SIZE;
+  int seen_error = 0;
 
   if (section == NULL
       || coff_section_data (abfd, section) == NULL
@@ -485,9 +478,8 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
       return FALSE;
     }
 
-  start = 0;
-
-  for (i = start; i < stop; i += onaline)
+  /* Do sanity check of pdata.  */
+  for (i = 0; i < stop; i += onaline)
     {
       struct pex64_runtime_function rf;
 
@@ -499,29 +491,80 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile)
          && rf.rva_UnwindData == 0)
        /* We are probably into the padding of the section now.  */
        break;
-
       fputc (' ', file);
       fprintf_vma (file, i + section->vma);
       fprintf (file, ":\t");
-      rf.rva_BeginAddress += pe_data (abfd)->pe_opthdr.ImageBase;
       fprintf_vma (file, rf.rva_BeginAddress);
       fputc (' ', file);
-      rf.rva_EndAddress += pe_data (abfd)->pe_opthdr.ImageBase;
       fprintf_vma (file, rf.rva_EndAddress);
       fputc (' ', file);
       fprintf_vma (file, 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"));
+        }
+      prev_beginaddress = rf.rva_BeginAddress;
+      /* Now we check for negative addresses.  */
+      if ((prev_beginaddress & 0x80000000) != 0)
+       {
+         seen_error = 1;
+         fprintf (file, "  has negative begin address\n");
+       }
+      if ((rf.rva_EndAddress & 0x80000000) != 0)
+       {
+         seen_error = 1;
+         fprintf (file, "  has negative end address\n");
+       }
+      if ((rf.rva_UnwindData & 0x80000000) != 0)
+       {
+         seen_error = 1;
+         fprintf (file, "  has negative unwind address\n");
+       }
+    }
+
+  if (seen_error)
+    {
+      free (data);
+
+      return TRUE;
+    }
+  /* 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;
+      pex64_get_runtime_function (abfd, &rf, &data[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)
+        fprintf (file, "\nDump of .xdata\n");
+      fputc (' ', file);
+      fprintf_vma (file, rf.rva_UnwindData);
+      fprintf (file, ":\n");
+
+      rf.rva_BeginAddress += pe_data (abfd)->pe_opthdr.ImageBase;
+      rf.rva_EndAddress += pe_data (abfd)->pe_opthdr.ImageBase;
 
       if (rf.rva_UnwindData != 0)
        {
          if (rf.isChained)
            {
              fprintf (file, "\t shares information with pdata element at 0x");
-             fprintf_vma (file, rf.rva_UnwindData + pe_data (abfd)->pe_opthdr.ImageBase);
+             fprintf_vma (file, rf.rva_UnwindData);
              fprintf (file, ".\n");
            }
          else
-           pex64_dump_xdata (file, abfd, rf.rva_UnwindData, rf.rva_BeginAddress);
+           pex64_dump_xdata (file, abfd, rf.rva_UnwindData, rf.rva_BeginAddress,
+                             stop, onaline, data);
        }
     }