* pe-arm-wince.c (pe_print_compressed_pdata): Define new function to
[deliverable/binutils-gdb.git] / bfd / pe-arm-wince.c
index 90a53a35fad8be8e9bb3e9395d1e020d804d00d5..e0013f378d58bd8b0f8bd7c9d00b81409bd0a49b 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD back-end for ARM WINCE PE files.
-   Copyright 2006, 2007 Free Software Foundation, Inc.
+   Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
 
 #define LOCAL_LABEL_PREFIX "."
 
+#include "sysdep.h"
+#include "bfd.h"
+
+#undef  bfd_pe_print_pdata
+#define        bfd_pe_print_pdata   pe_print_ce_compressed_pdata
+extern bfd_boolean pe_print_ce_compressed_pdata (bfd *, void *);
+
 #include "pe-arm.c"
+
+typedef struct sym_cache
+{
+  int symcount;
+  asymbol **syms;
+} sym_cache;
+
+static asymbol **
+slurp_symtab (bfd *abfd, sym_cache *psc)
+{
+  asymbol **sy = NULL;
+  long storage;
+
+  if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
+    {
+      psc->symcount = 0;
+      return NULL;
+    }
+
+  storage = bfd_get_symtab_upper_bound (abfd);
+  if (storage < 0)
+    return NULL;
+  if (storage)
+    sy = bfd_malloc (storage);
+
+  psc->symcount = bfd_canonicalize_symtab (abfd, sy);
+  if (psc->symcount < 0)
+    return NULL;
+  return sy;
+}
+
+static const char *
+my_symbol_for_address (bfd *abfd, bfd_vma func, sym_cache *psc)
+{
+  int i;
+
+  if (psc->syms == 0)
+    psc->syms = slurp_symtab (abfd, psc);
+
+  for (i = 0; i < psc->symcount; i++)
+    {
+      if (psc->syms[i]->section->vma + psc->syms[i]->value == func)
+       return psc->syms[i]->name;
+    }
+
+  return NULL;
+}
+
+static void
+cleanup_syms (sym_cache *psc)
+{
+  psc->symcount = 0;
+  free (psc->syms);
+  psc->syms = NULL;
+}
+
+/* This is the version for "compressed" pdata.  */
+
+bfd_boolean
+pe_print_ce_compressed_pdata (bfd * abfd, void * vfile)
+{
+# define PDATA_ROW_SIZE        (2 * 4)
+  FILE *file = (FILE *) vfile;
+  bfd_byte *data = 0;
+  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\tBegin    Prolog   Function Flags    Exception EH\n\
+     \t\tAddress  Length   Length   32b exc  Handler   Data\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 other_data;
+      bfd_vma prolog_length, function_length;
+      int flag32bit, exception_flag;
+      bfd_byte *tdata = 0;
+      asection *tsection;
+
+      if (i + PDATA_ROW_SIZE > stop)
+       break;
+
+      begin_addr = GET_PDATA_ENTRY (abfd, data + i     );
+      other_data = GET_PDATA_ENTRY (abfd, data + i +  4);
+
+      if (begin_addr == 0 && other_data == 0)
+       /* We are probably into the padding of the section now.  */
+       break;
+
+      prolog_length = (other_data & 0x000000FF);
+      function_length = (other_data & 0x3FFFFF00) >> 8;
+      flag32bit = (int)((other_data & 0x40000000) >> 30);
+      exception_flag = (int)((other_data & 0x80000000) >> 31);
+
+      fputc (' ', file);
+      fprintf_vma (file, i + section->vma); fputc ('\t', file);
+      fprintf_vma (file, begin_addr); fputc (' ', file);
+      fprintf_vma (file, prolog_length); fputc (' ', file);
+      fprintf_vma (file, function_length); fputc (' ', file);
+      fprintf (file, "%2d  %2d   ", flag32bit, exception_flag);
+
+      /* Get the exception handler's address and the data passed from the
+         .text section. This is really the data that belongs with the .pdata
+         but got "compressed" out for the ARM and SH4 architectures.  */
+      tsection = bfd_get_section_by_name (abfd, ".text");
+      if (tsection && coff_section_data (abfd, tsection)
+         && pei_section_data (abfd, tsection))
+       {
+         if (bfd_malloc_and_get_section (abfd, tsection, & tdata))
+           {
+             int xx = (begin_addr - 8) - tsection->vma;
+
+             tdata = bfd_malloc (8);
+             if (bfd_get_section_contents (abfd, tsection, tdata, (bfd_vma) xx, 8))
+               {
+                 bfd_vma eh, eh_data;
+
+                 eh = bfd_get_32 (abfd, tdata);
+                 eh_data = bfd_get_32 (abfd, tdata + 4);
+                 fprintf (file, "%08x  ", (unsigned int) eh);
+                 fprintf (file, "%08x", (unsigned int) eh_data);
+                 if (eh != 0)
+                   {
+                     const char *s = my_symbol_for_address (abfd, eh, &sym_cache);
+
+                     if (s)
+                       fprintf (file, " (%s) ", s);
+                   }
+               }
+             free (tdata);
+           }
+         else
+           {
+             if (tdata)
+               free (tdata);
+           }
+       }
+
+      fprintf (file, "\n");
+    }
+
+  free (data);
+
+  cleanup_syms (& sym_cache);
+
+  return TRUE;
+#undef PDATA_ROW_SIZE
+}
This page took 0.024409 seconds and 4 git commands to generate.