aboutsummaryrefslogtreecommitdiff
path: root/bfd/peXXigen.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/peXXigen.c')
-rw-r--r--bfd/peXXigen.c210
1 files changed, 210 insertions, 0 deletions
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index 287e4a2..b720668 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -1991,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
@@ -2165,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;
}