Index: bfd/peXXigen.c |
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c |
index e5065464c05f36cac182f857c23184be55790131..b7206688a61e477ce2611a7bdbde46c0c229af3d 100644 |
--- a/bfd/peXXigen.c |
+++ b/bfd/peXXigen.c |
@@ -1,6 +1,5 @@ |
/* Support for the generic parts of PE/PEI; the common executable parts. |
- Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, |
- 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. |
+ Copyright 1995-2013 Free Software Foundation, Inc. |
Written by Cygnus Solutions. |
This file is part of BFD, the Binary File Descriptor library. |
@@ -461,7 +460,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd, |
{ |
int idx; |
- for (idx = 0; idx < 16; idx++) |
+ for (idx = 0; idx < a->NumberOfRvaAndSizes; idx++) |
{ |
/* If data directory is empty, rva also should be 0. */ |
int size = |
@@ -591,9 +590,6 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out) |
extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; |
- /* First null out all data directory entries. */ |
- memset (extra->DataDirectory, 0, sizeof (extra->DataDirectory)); |
- |
add_data_entry (abfd, extra, 0, ".edata", ib); |
add_data_entry (abfd, extra, 2, ".rsrc", ib); |
add_data_entry (abfd, extra, 3, ".pdata", ib); |
@@ -796,7 +792,10 @@ _bfd_XXi_only_swap_filehdr_out (bfd * abfd, void * in, void * out) |
H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic); |
H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns); |
- H_PUT_32 (abfd, time (0), filehdr_out->f_timdat); |
+ /* Only use a real timestamp if the option was chosen. */ |
+ if ((pe_data (abfd)->insert_timestamp)) |
+ H_PUT_32 (abfd, time(0), filehdr_out->f_timdat); |
+ |
PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr, |
filehdr_out->f_symptr); |
H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms); |
@@ -1992,6 +1991,214 @@ pe_print_reloc (bfd * abfd, void * vfile) |
return TRUE; |
} |
+static bfd_byte * |
+pe_print_resource_directory (FILE * , bfd *, unsigned int, |
+ bfd_byte *, bfd_byte *, bfd_byte *, bfd_vma); |
+ |
+static bfd_byte * |
+pe_print_resource_entries (FILE * file, |
+ bfd * abfd, |
+ unsigned int indent, |
+ bfd_boolean is_name, |
+ bfd_byte * data, |
+ bfd_byte * datastart, |
+ bfd_byte * dataend, |
+ bfd_vma rva_bias) |
+{ |
+ unsigned long entry, addr, size; |
+ |
+ if (data + 8 >= dataend) |
+ return dataend + 1; |
+ |
+ fprintf (file, _("%*.s Entry: "), indent, " "); |
+ |
+ entry = (long) bfd_get_32 (abfd, data); |
+ if (is_name) |
+ { |
+ if (datastart + entry < dataend) |
+ { |
+ unsigned int len; |
+ len = bfd_get_16 (abfd, datastart + entry); |
+ |
+ fprintf (file, _("name: %08lx [%d:]"), entry, len); |
+ if (datastart + entry - rva_bias + 2 + len < dataend) |
+ fprintf (file, "%.*s", len, (char *) (datastart + entry - rva_bias + 2)); |
+ else |
+ fprintf (file, _("<corrupt>")); |
+ } |
+ else |
+ fprintf (file, _("<corrupt>")); |
+ } |
+ else |
+ fprintf (file, _("ID: %#08lx"), entry); |
+ |
+ entry = (long) bfd_get_32 (abfd, data + 4); |
+ fprintf (file, _(", Value: %#08lx"), entry); |
+ |
+ if (entry & 0x80000000) |
+ { |
+ fprintf (file, _(" sub-table:\n")); |
+ return pe_print_resource_directory (file, abfd, indent + 1, |
+ datastart + (entry & 0x7fffffff), |
+ datastart, dataend, rva_bias); |
+ } |
+ |
+ if (datastart + entry + 16 >= dataend) |
+ { |
+ fprintf (file, "\n"); |
+ return dataend + 1; |
+ } |
+ |
+ fprintf (file, _(" leaf: Addr: %#08lx, Size: %#08lx, Codepage: %d\n"), |
+ addr = (long) bfd_get_32 (abfd, datastart + entry), |
+ size = (long) bfd_get_32 (abfd, datastart + entry + 4), |
+ (int) bfd_get_32 (abfd, datastart + entry + 8)); |
+ |
+ /* Check that the reserved entry is 0. */ |
+ if (bfd_get_32 (abfd, datastart + entry + 12) != 0 |
+ /* And that the data address/size is valid too. */ |
+ || (datastart + addr - rva_bias + size > dataend)) |
+ return dataend + 1; |
+ |
+ return datastart + addr - rva_bias + size; |
+} |
+ |
+static bfd_byte * |
+pe_print_resource_directory (FILE * file, |
+ bfd * abfd, |
+ unsigned int indent, |
+ bfd_byte * data, |
+ bfd_byte * datastart, |
+ bfd_byte * dataend, |
+ bfd_vma rva_bias) |
+{ |
+ unsigned int num_names, num_ids; |
+ bfd_byte * enddata = data; |
+ |
+ if (data + 16 >= dataend) |
+ return dataend + 1; |
+ |
+ fprintf (file, "%*.s ", indent, " "); |
+ switch (indent) |
+ { |
+ case 0: fprintf (file, "Type"); break; |
+ case 2: fprintf (file, "Name"); break; |
+ case 4: fprintf (file, "Language"); break; |
+ default: fprintf (file, "<unknown>"); break; |
+ } |
+ |
+ fprintf (file, _(" Table: Char: %d, Time: %08lx, Ver: %d/%d, Num Names: %d, IDs: %d\n"), |
+ (int) bfd_get_32 (abfd, data), |
+ (long) bfd_get_32 (abfd, data + 4), |
+ (int) bfd_get_16 (abfd, data + 8), |
+ (int) bfd_get_16 (abfd, data + 10), |
+ num_names = (int) bfd_get_16 (abfd, data + 12), |
+ num_ids = (int) bfd_get_16 (abfd, data + 14)); |
+ data += 16; |
+ |
+ if (num_names) |
+ { |
+ while (num_names --) |
+ { |
+ bfd_byte * ndata; |
+ ndata = pe_print_resource_entries (file, abfd, indent + 1, TRUE, |
+ data, datastart, dataend, rva_bias); |
+ data += 8; |
+ if (ndata > enddata) |
+ enddata = ndata; |
+ if (ndata >= dataend) |
+ break; |
+ } |
+ } |
+ |
+ if (num_ids) |
+ { |
+ while (num_ids --) |
+ { |
+ bfd_byte * ndata; |
+ ndata = pe_print_resource_entries (file, abfd, indent + 1, FALSE, |
+ data, datastart, dataend, rva_bias); |
+ data += 8; |
+ if (ndata > enddata) |
+ enddata = ndata; |
+ if (ndata >= dataend) |
+ break; |
+ } |
+ } |
+ |
+ return enddata > data ? enddata : data; |
+} |
+ |
+/* Display the contents of a .rsrc section. We do not try to |
+ reproduce the resources, windres does that. Instead we dump |
+ the tables in a human readable format. */ |
+ |
+static bfd_boolean |
+pe_print_rsrc (bfd * abfd, void * vfile) |
+{ |
+ bfd_vma rva_bias; |
+ pe_data_type * pe; |
+ FILE * file = (FILE *) vfile; |
+ bfd_size_type datasize; |
+ asection * section; |
+ bfd_byte * data; |
+ bfd_byte * dataend; |
+ bfd_byte * datastart; |
+ |
+ |
+ pe = pe_data (abfd); |
+ if (pe == NULL) |
+ return TRUE; |
+ |
+ section = bfd_get_section_by_name (abfd, ".rsrc"); |
+ if (section == NULL) |
+ return TRUE; |
+ |
+ rva_bias = section->vma - pe->pe_opthdr.ImageBase; |
+ |
+ datasize = section->size; |
+ if (datasize == 0) |
+ return TRUE; |
+ |
+ if (! bfd_malloc_and_get_section (abfd, section, &data)) |
+ { |
+ if (data != NULL) |
+ free (data); |
+ return FALSE; |
+ } |
+ datastart = data; |
+ dataend = data + datasize; |
+ |
+ fflush (file); |
+ fprintf (file, "\nThe .rsrc Resource Directory section:\n"); |
+ |
+ while (data < dataend) |
+ { |
+ data = pe_print_resource_directory (file, abfd, 0, data, data, dataend, rva_bias); |
+ |
+ if (data == dataend + 1) |
+ fprintf (file, _("Corrupt .rsrc section detected!\n")); |
+ else |
+ { |
+ /* Align data before continuing. */ |
+ int align = (1 << section->alignment_power) - 1; |
+ data = (bfd_byte *) (((long) (data + align)) & ~ align); |
+ rva_bias += data - datastart; |
+ |
+ /* For reasons that are unclear .rsrc sections are sometimes created |
+ aligned to a 1^3 boundary even when their alignment is set at |
+ 1^2. Catch that case here before we issue a spurious warning |
+ message. */ |
+ if (data == (dataend - 4)) |
+ data = dataend; |
+ else if (data < dataend) |
+ fprintf (file, _("\nWARNING: Extra data in .rsrc section - it will be ignored by Windows:\n")); |
+ } |
+ } |
+ |
+ return TRUE; |
+} |
+ |
/* Print out the program headers. */ |
bfd_boolean |
@@ -2166,6 +2373,8 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile) |
pe_print_pdata (abfd, vfile); |
pe_print_reloc (abfd, vfile); |
+ pe_print_rsrc (abfd, vfile); |
+ |
return TRUE; |
} |
@@ -2442,7 +2651,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo) |
/* According to PECOFF sepcifications by Microsoft version 8.2 |
the TLS data directory consists of 4 pointers, followed |
by two 4-byte integer. This implies that the total size |
- is different for 32-bit and 64-bit executables. */ |
+ is different for 32-bit and 64-bit executables. */ |
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) |
pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x18; |
#else |