This has been on my todo-list for far too long, apologies.

I've tried to tackle the conditional compilation part, and would like
your renewed input on it, I may have missed some points. Naming for
instance.

Diffs in the attachment are relative to the cegcc svn, I've checked and
they patch cleanly in a binutils 2.18 tree.

So, please tell me what I'm missing and I'll change my patch.

        Danny

On Mon, 2007-08-06 at 16:22 +0100, Nick Clifton wrote:
> Hi Danny,
> 
> 
> > 2. Cleanup in my_symbol_for_address. There's none now. Should there be?
> 
> Yes. :-)
> 
> Also it looks like my_symbol_for_address is going to quite slow for large 
> symbol tables.  You might want to consider ensuring that the symbol time is 
> sorted by address and then performing some kind of binary search on it.  (Or 
> do 
> you know that my_symbol_for_address will always be called with incrementally 
> increasing addresses, in which case you could just cache the last returned 
> value and start your search there).
> 
> > 3. Which macros should be used for the conditional compilation ? I've
> > used
> > #if defined(ARM_WINCE) || defined(SH4)
> > in my code. This happens to work for me because our build chain defines
> > ARM_WINCE, but I don't suppose this is right.
> 
> The correct way to handle this is to add a new function pointer field to the 
> bfd_coff_backend_data structure.  Arrange for this field to be initialized by 
> the various backends that need it (IA64, ARM, MIPS, SH) pointing at static 
> functions defined in the appropriate target specific source file (pe-arm.c 
> etc), and otherwise for it to be empty(*).  Then in 
> _bfd_XX_print_private_bfd_data_common test the field and call it if it is not 
> empty.
> 
> Cheers
>    Nick
> 
> (*) Or maybe to point at a default pdata display function which does not try 
> to 
> provide any target specific interpretation.
Index: pe-arm-wince.c
===================================================================
--- pe-arm-wince.c	(revision 1151)
+++ pe-arm-wince.c	(working copy)
@@ -35,4 +35,179 @@
 
 #define LOCAL_LABEL_PREFIX "."
 
+#include "sysdep.h"
+#include "bfd.h"
+
+#undef bfd_pe_print_pdata
+#define	bfd_pe_print_pdata pe_print_compressed_pdata
+extern bfd_boolean pe_print_compressed_pdata (bfd * abfd, void * vfile);
+
 #include "pe-arm.c"
+
+static int symcount=0;
+static asymbol **
+slurp_symtab (bfd *abfd)
+{
+  asymbol **sy = NULL;
+  long storage;
+
+  if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
+    {
+      symcount = 0;
+      return NULL;
+    }
+
+  storage = bfd_get_symtab_upper_bound (abfd);
+  if (storage < 0)
+    return NULL;
+  if (storage)
+    sy = bfd_malloc (storage);
+
+  symcount = bfd_canonicalize_symtab (abfd, sy);
+  if (symcount < 0)
+    return NULL;
+  return sy;
+}
+
+static const char *
+my_symbol_for_address(bfd *abfd, bfd_vma func)
+{
+	static asymbol **syms = 0;
+	int i;
+
+	if (syms == 0)
+		syms = slurp_symtab (abfd);
+	for (i=0; i<symcount; i++) {
+		if (syms[i]->section->vma + syms[i]->value == func)
+			return syms[i]->name;
+	}
+	return NULL;
+}
+
+/* Copied from peXXigen.c , then modified for compressed pdata.
+
+   This really is architecture dependent.  On IA-64, a .pdata entry
+   consists of three dwords containing relative virtual addresses that
+   specify the start and end address of the code range the entry
+   covers and the address of the corresponding unwind info data. 
+
+   On ARM and SH-4, a compressed PDATA structure is used :
+   _IMAGE_CE_RUNTIME_FUNCTION_ENTRY, whereas MIPS is documented to use
+   _IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY.
+   See http://msdn2.microsoft.com/en-us/library/ms253988(VS.80).aspx .
+   */
+
+/* This is the version for "compressed" pdata.  */
+bfd_boolean
+pe_print_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;
+
+  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);
+				      if (s)
+					      fprintf(file, " (%s) ", s);
+			      }
+		      }
+		      free (tdata);
+	      } else {
+		      if (tdata)
+			      free(tdata);
+	      }
+      }
+
+      fprintf (file, "\n");
+    }
+
+  free (data);
+
+  return TRUE;
+#undef PDATA_ROW_SIZE
+}
Index: pei-arm.c
===================================================================
--- pei-arm.c	(revision 1151)
+++ pei-arm.c	(working copy)
@@ -51,4 +51,8 @@
 { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
   COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
 
+#undef bfd_pe_print_pdata
+#define	bfd_pe_print_pdata pe_print_compressed_pdata
+extern bfd_boolean pe_print_compressed_pdata (bfd * abfd, void * vfile);
+
 #include "coff-arm.c"
Index: pei-arm-wince.c
===================================================================
--- pei-arm-wince.c	(revision 1151)
+++ pei-arm-wince.c	(working copy)
@@ -28,4 +28,11 @@
 
 #define LOCAL_LABEL_PREFIX "."
 
+#include "sysdep.h"
+#include "bfd.h"
+
+#undef bfd_pe_print_pdata
+#define	bfd_pe_print_pdata pe_print_compressed_pdata
+extern bfd_boolean pe_print_compressed_pdata (bfd * abfd, void * vfile);
+
 #include "pei-arm.c"
Index: pe-arm.c
===================================================================
--- pe-arm.c	(revision 1151)
+++ pe-arm.c	(working copy)
@@ -63,4 +63,8 @@
 { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
   COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
 
+#undef bfd_pe_print_pdata
+#define	bfd_pe_print_pdata pe_print_compressed_pdata
+extern bfd_boolean pe_print_compressed_pdata (bfd * abfd, void * vfile);
+
 #include "coff-arm.c"
Index: coff-sh.c
===================================================================
--- coff-sh.c	(revision 1151)
+++ coff-sh.c	(working copy)
@@ -3149,7 +3149,8 @@
   coff_classify_symbol, coff_compute_section_file_positions,
   coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
   coff_adjust_symndx, coff_link_add_one_symbol,
-  coff_link_output_has_begun, coff_final_link_postscript
+  coff_link_output_has_begun, coff_final_link_postscript,
+  bfd_pe_print_pdata
 };
 
 #define coff_small_close_and_cleanup \
Index: libcoff.h
===================================================================
--- libcoff.h	(revision 1151)
+++ libcoff.h	(working copy)
@@ -802,6 +802,8 @@
   bfd_boolean (*_bfd_coff_final_link_postscript)
     (bfd *, struct coff_final_link_info *);
 
+  bfd_boolean (*_bfd_coff_print_pdata)
+    (bfd *, void *);
 } bfd_coff_backend_data;
 
 #define coff_backend_info(abfd) \
@@ -934,3 +936,7 @@
 #define bfd_coff_final_link_postscript(a,p) \
   ((coff_backend_info (a)->_bfd_coff_final_link_postscript) (a, p))
 
+#define bfd_coff_have_print_pdata(a) \
+  (coff_backend_info (a)->_bfd_coff_print_pdata)
+#define bfd_coff_print_pdata(a,p) \
+  ((coff_backend_info (a)->_bfd_coff_print_pdata) (a, p))
Index: coffcode.h
===================================================================
--- coffcode.h	(revision 1151)
+++ coffcode.h	(working copy)
@@ -5263,7 +5263,8 @@
   coff_classify_symbol, coff_compute_section_file_positions,
   coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
   coff_adjust_symndx, coff_link_add_one_symbol,
-  coff_link_output_has_begun, coff_final_link_postscript
+  coff_link_output_has_begun, coff_final_link_postscript,
+  bfd_pe_print_pdata
 };
 
 #ifdef TICOFF
@@ -5306,7 +5307,8 @@
   coff_classify_symbol, coff_compute_section_file_positions,
   coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
   coff_adjust_symndx, coff_link_add_one_symbol,
-  coff_link_output_has_begun, coff_final_link_postscript
+  coff_link_output_has_begun, coff_final_link_postscript,
+  bfd_pe_print_pdata
 };
 #endif
 
@@ -5350,7 +5352,8 @@
   coff_classify_symbol, coff_compute_section_file_positions,
   coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
   coff_adjust_symndx, coff_link_add_one_symbol,
-  coff_link_output_has_begun, coff_final_link_postscript
+  coff_link_output_has_begun, coff_final_link_postscript,
+  bfd_pe_print_pdata
 };
 #endif
 
Index: coff64-rs6000.c
===================================================================
--- coff64-rs6000.c	(revision 1151)
+++ coff64-rs6000.c	(working copy)
@@ -2584,7 +2584,8 @@
       NULL,			/* _bfd_coff_adjust_symndx */
       _bfd_generic_link_add_one_symbol,
       coff_link_output_has_begun,
-      coff_final_link_postscript
+      coff_final_link_postscript,
+      NULL			/* print_pdata */
     },
 
     0x01EF,			/* magic number */
@@ -2837,7 +2838,8 @@
       NULL,			/* _bfd_coff_adjust_symndx */
       _bfd_generic_link_add_one_symbol,
       coff_link_output_has_begun,
-      coff_final_link_postscript
+      coff_final_link_postscript,
+      NULL			/* print_pdata */
     },
 
     U64_TOCMAGIC,		/* magic number */
Index: coff-rs6000.c
===================================================================
--- coff-rs6000.c	(revision 1151)
+++ coff-rs6000.c	(working copy)
@@ -4034,7 +4034,8 @@
       NULL,			/* _bfd_coff_adjust_symndx */
       _bfd_generic_link_add_one_symbol,
       coff_link_output_has_begun,
-      coff_final_link_postscript
+      coff_final_link_postscript,
+      NULL			/* print_pdata */
     },
 
     0x01DF,			/* magic number */
@@ -4285,7 +4286,8 @@
       NULL,			/* _bfd_coff_adjust_symndx */
       _bfd_generic_link_add_one_symbol,
       coff_link_output_has_begun,
-      coff_final_link_postscript
+      coff_final_link_postscript,
+      NULL			/* print_pdata */
     },
 
     0x01DF,			/* magic number */
Index: peXXigen.c
===================================================================
--- peXXigen.c	(revision 1151)
+++ peXXigen.c	(working copy)
@@ -1581,8 +1581,17 @@
 /* This really is architecture dependent.  On IA-64, a .pdata entry
    consists of three dwords containing relative virtual addresses that
    specify the start and end address of the code range the entry
-   covers and the address of the corresponding unwind info data.  */
+   covers and the address of the corresponding unwind info data. 
 
+   On ARM and SH-4, a compressed PDATA structure is used :
+   _IMAGE_CE_RUNTIME_FUNCTION_ENTRY, whereas MIPS is documented to use
+   _IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY.
+   See http://msdn2.microsoft.com/en-us/library/ms253988(VS.80).aspx .
+
+   The version of this function to deal with compressed pdata is moved to
+   pe-arm-wince.c .
+   */
+
 static bfd_boolean
 pe_print_pdata (bfd * abfd, void * vfile)
 {
@@ -1705,6 +1714,7 @@
   free (data);
 
   return TRUE;
+#undef PDATA_ROW_SIZE
 }
 
 #define IMAGE_REL_BASED_HIGHADJ 4
@@ -1975,7 +1985,10 @@
 
   pe_print_idata (abfd, vfile);
   pe_print_edata (abfd, vfile);
-  pe_print_pdata (abfd, vfile);
+  if (bfd_coff_have_print_pdata (abfd))
+	  bfd_coff_print_pdata (abfd, vfile);
+  else
+	  pe_print_pdata (abfd, vfile);
   pe_print_reloc (abfd, vfile);
 
   return TRUE;

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
bug-binutils mailing list
bug-binutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-binutils

Reply via email to