Index: bfd/peXXigen.c =================================================================== --- bfd/peXXigen.c (revision 1020) +++ bfd/peXXigen.c (working copy) @@ -1561,16 +1561,63 @@ return TRUE; } +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; isection->vma + syms[i]->value == func) + return syms[i]->name; + } + return NULL; +} + /* 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 . + */ static bfd_boolean pe_print_pdata (bfd * abfd, void * vfile) { #if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) # define PDATA_ROW_SIZE (3 * 8) +#elif defined(ARM_WINCE) || defined(SH4) +# define PDATA_ROW_SIZE (2 * 4) #else # define PDATA_ROW_SIZE (5 * 4) #endif @@ -1598,6 +1645,10 @@ #if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) fprintf (file, _(" vma:\t\t\tBegin Address End Address Unwind Info\n")); +#elif defined(ARM_WINCE) || defined(SH4) + fprintf (file, _("\ + vma:\t\tBegin Prolog Function Flags Exception EH\n\ + \t\tAddress Length Length 32b exc Handler Data\n")); #else fprintf (file, _("\ vma:\t\tBegin End EH EH PrologEnd Exception\n\ @@ -1620,16 +1671,75 @@ for (i = start; i < stop; i += onaline) { bfd_vma begin_addr; +#if defined(ARM_WINCE) || defined(SH4) + bfd_vma other_data; + bfd_vma prolog_length, function_length; + int flag32bit, exception_flag; + bfd_byte *tdata = 0; + asection *tsection; +#else bfd_vma end_addr; bfd_vma eh_handler; bfd_vma eh_data; bfd_vma prolog_end_addr; int em_data; +#endif if (i + PDATA_ROW_SIZE > stop) break; +#if defined(ARM_WINCE) || defined(SH4) 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); + } + } +#else + begin_addr = GET_PDATA_ENTRY (abfd, data + i ); end_addr = GET_PDATA_ENTRY (abfd, data + i + 4); eh_handler = GET_PDATA_ENTRY (abfd, data + i + 8); eh_data = GET_PDATA_ENTRY (abfd, data + i + 12); @@ -1655,6 +1765,7 @@ fprintf_vma (file, prolog_end_addr); fprintf (file, " %x", em_data); #endif +#endif #ifdef POWERPC_LE_PE if (eh_handler == 0 && eh_data != 0)