* peXXigen.c (pe_print_resource_entries): New function: Displays
an entry in a .rsrc section. (pe_print_resource_directory): New function: Displays a directory in a .rsrc section. (pe_print_rsrc): New function: Displays the contents of .rsrc section. (_bfd_XX_print_private_bfd_data_common): Call pe_print_rsrc. * binutils-all/windres/windres.exp: Run for x86_64-pc-cygwin. Add test of "objump -p" output.
This commit is contained in:
parent
ca8941bbd0
commit
11a6da5617
|
@ -1,3 +1,13 @@
|
|||
2013-12-03 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* peXXigen.c (pe_print_resource_entries): New function: Displays
|
||||
an entry in a .rsrc section.
|
||||
(pe_print_resource_directory): New function: Displays a directory
|
||||
in a .rsrc section.
|
||||
(pe_print_rsrc): New function: Displays the contents of .rsrc
|
||||
section.
|
||||
(_bfd_XX_print_private_bfd_data_common): Call pe_print_rsrc.
|
||||
|
||||
2013-12-03 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* elf64-ppc.c (ppc_build_one_stub <ppc_stub_plt_branch_r2off>):
|
||||
|
|
210
bfd/peXXigen.c
210
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2013-12-03 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* binutils-all/windres/windres.exp: Run for x86_64-pc-cygwin.
|
||||
Add test of "objump -p" output.
|
||||
|
||||
2013-11-27 Matthew Fortune <matthew.fortune@imgtec.com>
|
||||
|
||||
* binutils-all/objcopy.exp: Consider mips-mti-elf the same as
|
||||
|
|
|
@ -19,15 +19,18 @@
|
|||
|
||||
# Written by DJ Delorie <dj@redhat.com>
|
||||
|
||||
if {![istarget "i*86-*-*"] && ![istarget "x86_64-*-mingw*"] } {
|
||||
if {![istarget "i*86-*-*"] && ![istarget "x86_64-*-mingw*"] && ![istarget "x86_64-*-cygwin"] } {
|
||||
verbose "Not a Cygwin/Mingw target" 1
|
||||
return
|
||||
}
|
||||
|
||||
if {![info exists WINDRES]} then {
|
||||
verbose "WINDRES not defined" 1
|
||||
return
|
||||
}
|
||||
|
||||
if {[which $WINDRES] == 0} then {
|
||||
verbose "$WINDRES not found" 1
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -139,3 +142,37 @@ foreach res $res_list {
|
|||
file delete "tmpdir/$broot.dump"
|
||||
}
|
||||
}
|
||||
|
||||
# Test objdump -p
|
||||
|
||||
if {[which $OBJDUMP] == 0} then {
|
||||
unsupported "objdump -p"
|
||||
return
|
||||
}
|
||||
|
||||
verbose "$wr $cpp_opts -J rc $srcdir/$subdir/version.rc tmpdir/version.o" 1
|
||||
catch "exec $wr $cpp_opts -J rc $srcdir/$subdir/version.rc tmpdir/version.o" err
|
||||
|
||||
if ![string match "" $err] then {
|
||||
send_log "$err\n"
|
||||
verbose "$err" 1
|
||||
if [string match "*windows.h: No such file*" $err] then {
|
||||
unsupported "objdump -p (no header files found)"
|
||||
} else {
|
||||
fail "objdump -p (build)"
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -p tmpdir/version.o"]
|
||||
|
||||
# FIXME: We should extend this regexp to check for more information.
|
||||
set want ".*The .rsrc Resource Directory section.*Type Table:.*Entry: ID:.*Name Table:.*Entry: ID:.*Language Table:.*Entry: ID:.*"
|
||||
|
||||
if ![regexp $want $got] then {
|
||||
fail "objdump -p"
|
||||
} else {
|
||||
pass "objdump -p"
|
||||
}
|
||||
|
||||
# file delete "tmpdir/version.o"
|
||||
|
|
Loading…
Reference in New Issue