From: <dan...@us...> - 2008-03-29 13:30:54
|
Revision: 1155 http://cegcc.svn.sourceforge.net/cegcc/?rev=1155&view=rev Author: dannybackx Date: 2008-03-29 06:30:52 -0700 (Sat, 29 Mar 2008) Log Message: ----------- This fixes decoding the pdata field (for exception handlers) so e.g. objdump does the right thing. This "compressed" pdata format is published on MSDN and is what ARM and SH-4 use. This fix is submitted to binutils, I expect that they'll want the details to be tweaked (it's already modified so the strange conditional compilation is gone). Modified Paths: -------------- trunk/cegcc/src/binutils/ChangeLog.ce trunk/cegcc/src/binutils/bfd/coff-rs6000.c trunk/cegcc/src/binutils/bfd/coff-sh.c trunk/cegcc/src/binutils/bfd/coff64-rs6000.c trunk/cegcc/src/binutils/bfd/coffcode.h trunk/cegcc/src/binutils/bfd/libcoff.h trunk/cegcc/src/binutils/bfd/pe-arm-wince.c trunk/cegcc/src/binutils/bfd/pe-arm.c trunk/cegcc/src/binutils/bfd/peXXigen.c trunk/cegcc/src/binutils/bfd/pei-arm-wince.c trunk/cegcc/src/binutils/bfd/pei-arm.c Modified: trunk/cegcc/src/binutils/ChangeLog.ce =================================================================== --- trunk/cegcc/src/binutils/ChangeLog.ce 2008-03-27 17:22:16 UTC (rev 1154) +++ trunk/cegcc/src/binutils/ChangeLog.ce 2008-03-29 13:30:52 UTC (rev 1155) @@ -1,3 +1,19 @@ +2008-03-29 Danny Backx <dan...@us...> + + * pe-arm-wince.c (pe_print_compressed_pdata): Define new function to + print compressed pdata structure as described on MSDN. This only + applies to a limited set of architectures (ARM, SH4). + * pe-arm-wince.c (slurp_symtab, my_symbol_for_address): Define static + helper functions for pe_print_compressed_pdata. + * coffcode.h (bfd_coff_backend_data): Add _bfd_coff_print_pdata field. + * coffcode.h (bfd_coff_have_print_pdata, bfd_coff_print_pdata) : + Define. + * bfd/peXXigen.c (_bfd_XX_print_private_bfd_data_common): add check on + bfd_coff_backend_data, call the function if non-null. + * libcoff.h, pei-arm.c, pei-arm-wince.c, pe-arm.c, coff-sh.c, + coff64-rs6000.c, coff-rs6000.c: Add target dependent initialisation for + bfd_coff_backend_data. + 2008-01-10 Pedro Alves <ped...@po...> binutils/ Modified: trunk/cegcc/src/binutils/bfd/coff-rs6000.c =================================================================== --- trunk/cegcc/src/binutils/bfd/coff-rs6000.c 2008-03-27 17:22:16 UTC (rev 1154) +++ trunk/cegcc/src/binutils/bfd/coff-rs6000.c 2008-03-29 13:30:52 UTC (rev 1155) @@ -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 */ Modified: trunk/cegcc/src/binutils/bfd/coff-sh.c =================================================================== --- trunk/cegcc/src/binutils/bfd/coff-sh.c 2008-03-27 17:22:16 UTC (rev 1154) +++ trunk/cegcc/src/binutils/bfd/coff-sh.c 2008-03-29 13:30:52 UTC (rev 1155) @@ -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 \ Modified: trunk/cegcc/src/binutils/bfd/coff64-rs6000.c =================================================================== --- trunk/cegcc/src/binutils/bfd/coff64-rs6000.c 2008-03-27 17:22:16 UTC (rev 1154) +++ trunk/cegcc/src/binutils/bfd/coff64-rs6000.c 2008-03-29 13:30:52 UTC (rev 1155) @@ -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 */ Modified: trunk/cegcc/src/binutils/bfd/coffcode.h =================================================================== --- trunk/cegcc/src/binutils/bfd/coffcode.h 2008-03-27 17:22:16 UTC (rev 1154) +++ trunk/cegcc/src/binutils/bfd/coffcode.h 2008-03-29 13:30:52 UTC (rev 1155) @@ -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 Modified: trunk/cegcc/src/binutils/bfd/libcoff.h =================================================================== --- trunk/cegcc/src/binutils/bfd/libcoff.h 2008-03-27 17:22:16 UTC (rev 1154) +++ trunk/cegcc/src/binutils/bfd/libcoff.h 2008-03-29 13:30:52 UTC (rev 1155) @@ -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)) Modified: trunk/cegcc/src/binutils/bfd/pe-arm-wince.c =================================================================== --- trunk/cegcc/src/binutils/bfd/pe-arm-wince.c 2008-03-27 17:22:16 UTC (rev 1154) +++ trunk/cegcc/src/binutils/bfd/pe-arm-wince.c 2008-03-29 13:30:52 UTC (rev 1155) @@ -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 +} Modified: trunk/cegcc/src/binutils/bfd/pe-arm.c =================================================================== --- trunk/cegcc/src/binutils/bfd/pe-arm.c 2008-03-27 17:22:16 UTC (rev 1154) +++ trunk/cegcc/src/binutils/bfd/pe-arm.c 2008-03-29 13:30:52 UTC (rev 1155) @@ -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" Modified: trunk/cegcc/src/binutils/bfd/peXXigen.c =================================================================== --- trunk/cegcc/src/binutils/bfd/peXXigen.c 2008-03-27 17:22:16 UTC (rev 1154) +++ trunk/cegcc/src/binutils/bfd/peXXigen.c 2008-03-29 13:30:52 UTC (rev 1155) @@ -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; Modified: trunk/cegcc/src/binutils/bfd/pei-arm-wince.c =================================================================== --- trunk/cegcc/src/binutils/bfd/pei-arm-wince.c 2008-03-27 17:22:16 UTC (rev 1154) +++ trunk/cegcc/src/binutils/bfd/pei-arm-wince.c 2008-03-29 13:30:52 UTC (rev 1155) @@ -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" Modified: trunk/cegcc/src/binutils/bfd/pei-arm.c =================================================================== --- trunk/cegcc/src/binutils/bfd/pei-arm.c 2008-03-27 17:22:16 UTC (rev 1154) +++ trunk/cegcc/src/binutils/bfd/pei-arm.c 2008-03-29 13:30:52 UTC (rev 1155) @@ -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" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |