diff options
author | Pierre Muller <muller@sourceware.org> | 2014-12-24 10:06:57 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2014-12-24 10:06:57 +0000 |
commit | 854399ea9d0d5d5c14b4035bbc0adfe891f26a3d (patch) | |
tree | 2edc46b1db5218e2cecaee551378b734303e525d /bfd/pei-x86_64.c | |
parent | c361b9ac1ffcf62fb5d4c031c55e60cea963a85d (diff) | |
download | fsf-binutils-gdb-854399ea9d0d5d5c14b4035bbc0adfe891f26a3d.zip fsf-binutils-gdb-854399ea9d0d5d5c14b4035bbc0adfe891f26a3d.tar.gz fsf-binutils-gdb-854399ea9d0d5d5c14b4035bbc0adfe891f26a3d.tar.bz2 |
This patch adds support for printing out the pdata section of PE objects.
* pe-x86_64.c (pex64_bfd_print_pdata): Add external
declaration.
(bfd_pe_print_data): Set macro to pex64_bfd_print_data.
* pei-x86_64.c (pex64_bfd_print_pdata): Changed to
global function. Now handles multiple .pdata sections.
(pex_bfd_print_pdata_section): New static helper function,
using most of old pex_bfd_print_pdata function code, but adding
support for coff pe objects, which might have some fields
starting at zero offset.
(pex64_print_all_pdata_sections) : New static helper function,
used in call to bfd_map_over_sections inside new
pex66_bfd_print_pdata function.
(bfd_boolean pdata_count): New static variable, used to return
bfd_boolean value for pex64_bfd_print_pdata function.
Diffstat (limited to 'bfd/pei-x86_64.c')
-rw-r--r-- | bfd/pei-x86_64.c | 127 |
1 files changed, 102 insertions, 25 deletions
diff --git a/bfd/pei-x86_64.c b/bfd/pei-x86_64.c index ccb5774..16d8899 100644 --- a/bfd/pei-x86_64.c +++ b/bfd/pei-x86_64.c @@ -115,6 +115,7 @@ pex64_get_unwind_info (bfd *abfd, struct pex64_unwind_info *ui, void *data) ui->sizeofUnwindCodes = PEX64_UWI_SIZEOF_UWCODE_ARRAY (ui->CountOfCodes); ui->SizeOfBlock = ui->sizeofUnwindCodes + 4; ui->rawUnwindCodes = &ex_dta[4]; + ex_dta += ui->SizeOfBlock; switch (ui->Flags) { @@ -396,7 +397,7 @@ pex64_dump_xdata (FILE *file, bfd *abfd, : pex_regs[(unsigned int) ui.FrameRegister]); /* PR 17512: file: 2245-7442-0.004. */ - if (ui.CountOfCodes * 2 + ui.rawUnwindCodes + addr >= xdata + xdata_section->size) + if (ui.CountOfCodes * 2 + ui.rawUnwindCodes > xdata + xdata_section->size) fprintf (file, _("Too many unwind codes (%ld)\n"), (long) ui.CountOfCodes); else pex64_xdata_print_uwd_codes (file, abfd, &ui, rf); @@ -458,23 +459,24 @@ sort_xdata_arr (const void *l, const void *r) /* Display unwind tables for x86-64. */ static bfd_boolean -pex64_bfd_print_pdata (bfd *abfd, void *vfile) +pex64_bfd_print_pdata_section (bfd *abfd, void *vfile, asection *pdata_section) { FILE *file = (FILE *) vfile; bfd_byte *pdata = NULL; bfd_byte *xdata = NULL; - asection *pdata_section = bfd_get_section_by_name (abfd, ".pdata"); - asection *xdata_section; + asection *xdata_section = NULL; bfd_vma xdata_base; bfd_size_type i; + bfd_size_type datasize; bfd_size_type stop; - bfd_vma prev_beginaddress = 0; - bfd_vma prev_unwinddata_rva = 0; + bfd_vma prev_beginaddress = (bfd_vma) -1; + bfd_vma prev_unwinddata_rva = (bfd_vma) -1; bfd_vma imagebase; int onaline = PDATA_ROW_SIZE; int seen_error = 0; bfd_vma *xdata_arr = NULL; int xdata_arr_cnt; + bfd_boolean virt_size_is_zero = FALSE; /* Sanity checks. */ if (pdata_section == NULL @@ -483,20 +485,39 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile) return TRUE; stop = pei_section_data (abfd, pdata_section)->virt_size; - /* PR 17512: file: 005-181405-0.004. */ - if (stop == 0 || pdata_section->size == 0) + if ((stop % onaline) != 0) + fprintf (file, + _("Warning: %s section size (%ld) is not a multiple of %d\n"), + pdata_section->name, (long) stop, onaline); + + datasize = pdata_section->size; + if (datasize == 0) { - fprintf (file, _("No unwind data in .pdata section\n")); + if (stop) + fprintf (file, _("Warning: %s section size is zero\n"), + pdata_section->name); return TRUE; } - if ((stop % onaline) != 0) - fprintf (file, - _("warning: .pdata section size (%ld) is not a multiple of %d\n"), - (long) stop, onaline); + + /* virt_size might be zero for objects. */ + if (stop == 0 && strcmp (abfd->xvec->name, "pe-x86-64") == 0) + { + stop = (datasize / onaline) * onaline; + virt_size_is_zero = TRUE; + } + else if (datasize < stop) + { + fprintf (file, + _("Warning: %s section size (%ld) is smaller than virtual size (%ld)\n"), + pdata_section->name, datasize, stop); + /* Be sure not to read passed datasize. */ + stop = datasize / onaline; + } /* Display functions table. */ fprintf (file, - _("\nThe Function Table (interpreted .pdata section contents)\n")); + _("\nThe Function Table (interpreted %s section contents)\n"), + pdata_section->name); fprintf (file, _("vma:\t\t\tBeginAddress\t EndAddress\t UnwindData\n")); @@ -507,7 +528,10 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile) xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1)); xdata_arr_cnt = 0; - imagebase = pe_data (abfd)->pe_opthdr.ImageBase; + if (strcmp (abfd->xvec->name, "pei-x86-64") == 0) + imagebase = pe_data (abfd)->pe_opthdr.ImageBase; + else + imagebase = 0; for (i = 0; i < stop; i += onaline) { @@ -554,8 +578,9 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile) seen_error = 1; fprintf (file, " has negative unwind address\n"); } - if (rf.rva_UnwindData && !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf)) - xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData; + else if ((rf.rva_UnwindData && !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf)) + || virt_size_is_zero) + xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData; } if (seen_error) @@ -571,20 +596,41 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile) /* Find the section containing the unwind data (.xdata). */ xdata_base = xdata_arr[0]; - xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".rdata"); - - if (!xdata_section) - xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".data"); + /* For sections with long names, first look for the same + section name, replacing .pdata by .xdata prefix. */ + if (strcmp (pdata_section->name, ".pdata") != 0) + { + char *xdata_name = alloca (strlen (pdata_section->name + 1)); + + xdata_name = strcpy (xdata_name, pdata_section->name); + /* Transform .pdata prefix into .xdata prefix. */ + if (strlen (xdata_name) > 1) + xdata_name [1] = 'x'; + xdata_section = pex64_get_section_by_rva (abfd, xdata_base, + xdata_name); + } + /* Second, try the .xdata section itself. */ if (!xdata_section) xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".xdata"); - if (!xdata_section) + /* Otherwise, if xdata_base is non zero, search also inside + other standard sections. */ + if (!xdata_section && xdata_base) + xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".rdata"); + if (!xdata_section && xdata_base) + xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".data"); + if (!xdata_section && xdata_base) xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".pdata"); - if (!xdata_section) + if (!xdata_section && xdata_base) xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".text"); + /* Transfer xdata section into xdata array. */ if (!xdata_section || !bfd_malloc_and_get_section (abfd, xdata_section, &xdata)) goto done; + /* Avoid "also used "... ouput for single unwind info + in object file. */ + prev_unwinddata_rva = (bfd_vma) -1; + /* Do dump of pdata related xdata. */ for (i = 0; i < stop; i += onaline) { @@ -600,7 +646,7 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile) /* We are probably into the padding of the section now. */ break; if (i == 0) - fprintf (file, "\nDump of .xdata\n"); + fprintf (file, _("\nDump of %s\n"), xdata_section->name); fputc (' ', file); fprintf_vma (file, rf.rva_UnwindData + imagebase); @@ -623,7 +669,7 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile) fprintf_vma (file, rf.rva_EndAddress + imagebase); fputc ('\n', file); - if (rf.rva_UnwindData != 0) + if (rf.rva_UnwindData != 0 || virt_size_is_zero) { if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf)) { @@ -679,6 +725,37 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile) return TRUE; } +/* Static counter of number of found pdata sections. */ +static bfd_boolean pdata_count; + +/* Functionn prototype. */ +bfd_boolean pex64_bfd_print_pdata (bfd *, void *); + +/* Helper function for bfd_map_over_section. */ +static void +pex64_print_all_pdata_sections (bfd *abfd, asection *pdata, void *obj) +{ + if (CONST_STRNEQ (pdata->name, ".pdata")) + { + if (pex64_bfd_print_pdata_section (abfd, obj, pdata)) + pdata_count++; + } +} + +bfd_boolean +pex64_bfd_print_pdata (bfd *abfd, void *vfile) +{ + asection *pdata_section = bfd_get_section_by_name (abfd, ".pdata"); + + if (pdata_section) + return pex64_bfd_print_pdata_section (abfd, vfile, pdata_section); + + pdata_count = 0; + bfd_map_over_sections (abfd, pex64_print_all_pdata_sections, vfile); + return (pdata_count > 0); +} + #define bfd_pe_print_pdata pex64_bfd_print_pdata +#define bfd_coff_std_swap_table bfd_coff_pei_swap_table #include "coff-x86_64.c" |