Improve .rsrc section merging again. This time with an algorithm that
should work for all types of input .rsrc section. * peXXigen.c (rsrc_process_section): Add code to scan input sections and record their lengths. Use these lengths to find the start of each merged .rsrc section. * scripttempl/pe.sc (R_RSRC): Fix default-manifest exclusion. (.rsrc): Add SUBALIGN(4). Remove SORT. * scripttempl/pep.sc: Likewise.
This commit is contained in:
parent
288c6b306e
commit
6caf711179
@ -1,8 +1,8 @@
|
|||||||
2014-03-19 Nick Clifton <nickc@redhat.com>
|
2014-03-19 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* peXXigen.c (rsrc_align): New function. Attempts to cope with
|
* peXXigen.c (rsrc_process_section): Add code to scan input
|
||||||
alignment variances when .rsrc sections are merged.
|
sections and record their lengths. Use these lengths to find the
|
||||||
(rsrc_process_section): Use rsrc_align.
|
start of each merged .rsrc section.
|
||||||
|
|
||||||
2014-03-17 Tristan Gingold <gingold@adacore.com>
|
2014-03-17 Tristan Gingold <gingold@adacore.com>
|
||||||
|
|
||||||
|
124
bfd/peXXigen.c
124
bfd/peXXigen.c
@ -3477,63 +3477,6 @@ rsrc_merge (struct rsrc_entry * a, struct rsrc_entry * b)
|
|||||||
rsrc_sort_entries (& adir->ids, FALSE, adir);
|
rsrc_sort_entries (& adir->ids, FALSE, adir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bfd_byte *
|
|
||||||
rsrc_align (bfd * abfd, bfd_byte * data, bfd_byte * dataend)
|
|
||||||
{
|
|
||||||
ptrdiff_t d;
|
|
||||||
|
|
||||||
/* Align the data pointer - we no longer have access to the original sections
|
|
||||||
so we do not know the alignment value they used. We default to 1^2 alignment
|
|
||||||
but check to see if 1^3 is better. */
|
|
||||||
d = (ptrdiff_t) data;
|
|
||||||
d = (d + 3) & ~3;
|
|
||||||
|
|
||||||
if ((bfd_byte *) d == (dataend - 4))
|
|
||||||
return dataend;
|
|
||||||
|
|
||||||
if ((d & 0x4) == 0)
|
|
||||||
return (bfd_byte *) d;
|
|
||||||
|
|
||||||
/* Aligning to 1^3 would change the value of the pointer. See if the
|
|
||||||
next 16 bytes (without aligning to 1^3) would form a valid Resource
|
|
||||||
Directory Table. If not then increase the alignment. */
|
|
||||||
data = (bfd_byte *) d;
|
|
||||||
|
|
||||||
if (data + 16 >= dataend)
|
|
||||||
/* Not enough room left for a resource table anyway. Just stop. */
|
|
||||||
return dataend;
|
|
||||||
|
|
||||||
if (bfd_get_32 (abfd, data) != 0)
|
|
||||||
/* A non-zero characteristics field. This should not happen.
|
|
||||||
Possibly the padding between merged .rsrc sections was not zero.
|
|
||||||
Choose to advance the pointer. */
|
|
||||||
return (bfd_byte *) (d + 4);
|
|
||||||
|
|
||||||
if (bfd_get_32 (abfd, data + 4) != 0)
|
|
||||||
/* A non-zero time field. It cannot be the characteristics field
|
|
||||||
of a 1^3 aligned .rsrc section because the characteristics are
|
|
||||||
always zero. Hence we should not increase the alignment. */
|
|
||||||
return (bfd_byte *) d;
|
|
||||||
|
|
||||||
/* Looking at bytes 8..11 does not help. These are either the time stamp
|
|
||||||
or the version fields. They can both have arbitary values, and zero
|
|
||||||
is quite commmon, so we have no way to distinguish them. */
|
|
||||||
|
|
||||||
/* Bytes 12..15 are either the version values or the number of entries
|
|
||||||
to follow. If the value is zero then this must be the version fields,
|
|
||||||
since we must always have at least one entry. A non-zero value on the
|
|
||||||
other hand is ambiguous. */
|
|
||||||
if (bfd_get_32 (abfd, data + 12) == 0)
|
|
||||||
return (bfd_byte *) (d + 4);
|
|
||||||
|
|
||||||
/* Ho Hum, we have no easy way to resolve this problem, so punt for now.
|
|
||||||
FIXME: try parsing the entire remaining .rsrc section. If it fails,
|
|
||||||
try re-aligning data and reparsing. If that works go with the new
|
|
||||||
alignment. Note - this has the potential to be dangerously recursive. */
|
|
||||||
|
|
||||||
return (bfd_byte *) d;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the .rsrc section. If it contains multiple concatenated
|
/* Check the .rsrc section. If it contains multiple concatenated
|
||||||
resources then we must merge them properly. Otherwise Windows
|
resources then we must merge them properly. Otherwise Windows
|
||||||
will ignore all but the first set. */
|
will ignore all but the first set. */
|
||||||
@ -3555,6 +3498,10 @@ rsrc_process_section (bfd * abfd,
|
|||||||
rsrc_directory * type_tables;
|
rsrc_directory * type_tables;
|
||||||
rsrc_write_data write_data;
|
rsrc_write_data write_data;
|
||||||
unsigned int indx;
|
unsigned int indx;
|
||||||
|
bfd * input;
|
||||||
|
unsigned int num_input_rsrc = 0;
|
||||||
|
unsigned int max_num_input_rsrc = 4;
|
||||||
|
ptrdiff_t * rsrc_sizes = NULL;
|
||||||
|
|
||||||
new_table.names.num_entries = 0;
|
new_table.names.num_entries = 0;
|
||||||
new_table.ids.num_entries = 0;
|
new_table.ids.num_entries = 0;
|
||||||
@ -3577,6 +3524,44 @@ rsrc_process_section (bfd * abfd,
|
|||||||
if (! bfd_get_section_contents (abfd, sec, data, 0, size))
|
if (! bfd_get_section_contents (abfd, sec, data, 0, size))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
/* Step zero: Scan the input bfds looking for .rsrc sections and record
|
||||||
|
their lengths. Note - we rely upon the fact that the linker script
|
||||||
|
does *not* sort the input .rsrc sections, so that the order in the
|
||||||
|
linkinfo list matches the order in the output .rsrc section.
|
||||||
|
|
||||||
|
We need to know the lengths because each input .rsrc section has padding
|
||||||
|
at the end of a variable amount. (It does not appear to be based upon
|
||||||
|
the section alignment or the file alignment). We need to skip any
|
||||||
|
padding bytes when parsing the input .rsrc sections. */
|
||||||
|
rsrc_sizes = bfd_malloc (max_num_input_rsrc * sizeof * rsrc_sizes);
|
||||||
|
if (rsrc_sizes == NULL)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
for (input = pfinfo->info->input_bfds;
|
||||||
|
input != NULL;
|
||||||
|
input = input->link_next)
|
||||||
|
{
|
||||||
|
asection * rsrc_sec = bfd_get_section_by_name (input, ".rsrc");
|
||||||
|
|
||||||
|
if (rsrc_sec != NULL)
|
||||||
|
{
|
||||||
|
if (num_input_rsrc == max_num_input_rsrc)
|
||||||
|
{
|
||||||
|
max_num_input_rsrc += 10;
|
||||||
|
rsrc_sizes = bfd_realloc (rsrc_sizes, max_num_input_rsrc
|
||||||
|
* sizeof * rsrc_sizes);
|
||||||
|
if (rsrc_sizes == NULL)
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
BFD_ASSERT (rsrc_sec->size > 0);
|
||||||
|
rsrc_sizes [num_input_rsrc ++] = rsrc_sec->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_input_rsrc < 2)
|
||||||
|
goto end;
|
||||||
|
|
||||||
/* Step one: Walk the section, computing the size of the tables,
|
/* Step one: Walk the section, computing the size of the tables,
|
||||||
leaves and data and decide if we need to do anything. */
|
leaves and data and decide if we need to do anything. */
|
||||||
dataend = data + size;
|
dataend = data + size;
|
||||||
@ -3598,14 +3583,21 @@ rsrc_process_section (bfd * abfd,
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = rsrc_align (abfd, data, dataend);
|
if ((data - p) > rsrc_sizes [num_resource_sets])
|
||||||
|
{
|
||||||
|
_bfd_error_handler (_("%s: .rsrc merge failure: unexpected .rsrc size"),
|
||||||
|
bfd_get_filename (abfd));
|
||||||
|
bfd_set_error (bfd_error_file_truncated);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
/* FIXME: Should we add a check for "data - p" being much smaller
|
||||||
|
than rsrc_sizes[num_resource_sets] ? */
|
||||||
|
|
||||||
|
data = p + rsrc_sizes[num_resource_sets];
|
||||||
rva_bias += data - p;
|
rva_bias += data - p;
|
||||||
++ num_resource_sets;
|
++ num_resource_sets;
|
||||||
}
|
}
|
||||||
|
BFD_ASSERT (num_resource_sets == num_input_rsrc);
|
||||||
if (num_resource_sets < 2)
|
|
||||||
/* No merging necessary. */
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
/* Step two: Walk the data again, building trees of the resources. */
|
/* Step two: Walk the data again, building trees of the resources. */
|
||||||
data = datastart;
|
data = datastart;
|
||||||
@ -3620,11 +3612,11 @@ rsrc_process_section (bfd * abfd,
|
|||||||
{
|
{
|
||||||
bfd_byte * p = data;
|
bfd_byte * p = data;
|
||||||
|
|
||||||
data = rsrc_parse_directory (abfd, type_tables + indx, data, data,
|
(void) rsrc_parse_directory (abfd, type_tables + indx, data, data,
|
||||||
dataend, rva_bias, NULL);
|
dataend, rva_bias, NULL);
|
||||||
data = rsrc_align (abfd, data, dataend);
|
data = p + rsrc_sizes[indx];
|
||||||
rva_bias += data - p;
|
rva_bias += data - p;
|
||||||
indx ++;
|
++ indx;
|
||||||
}
|
}
|
||||||
BFD_ASSERT (indx == num_resource_sets);
|
BFD_ASSERT (indx == num_resource_sets);
|
||||||
|
|
||||||
@ -3681,8 +3673,10 @@ rsrc_process_section (bfd * abfd,
|
|||||||
sec->size = sec->rawsize = size;
|
sec->size = sec->rawsize = size;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
/* Step size: Free all the memory that we have used. */
|
||||||
/* FIXME: Free the resource tree, if we have one. */
|
/* FIXME: Free the resource tree, if we have one. */
|
||||||
free (datastart);
|
free (datastart);
|
||||||
|
free (rsrc_sizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle the .idata section and other things that need symbol table
|
/* Handle the .idata section and other things that need symbol table
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* Makefile.in: Regenerate.
|
* Makefile.in: Regenerate.
|
||||||
* emultempl/default-manifest.rc: Fix typo.
|
* emultempl/default-manifest.rc: Fix typo.
|
||||||
* scripttempl/pe.sc (R_RSRC): Fix default-manifest exclusion.
|
* scripttempl/pe.sc (R_RSRC): Fix default-manifest exclusion.
|
||||||
(.rsrc): Add SUBALIGN(4).
|
(.rsrc): Add SUBALIGN(4). Remove SORT.
|
||||||
* scripttempl/pep.sc: Likewise.
|
* scripttempl/pep.sc: Likewise.
|
||||||
|
|
||||||
2014-03-17 Christopher Faylor <me.cygwin2014@cgf.cx>
|
2014-03-17 Christopher Faylor <me.cygwin2014@cgf.cx>
|
||||||
|
@ -47,15 +47,18 @@ if test "${RELOCATING}"; then
|
|||||||
if test -z "$DEFAULT_MANIFEST"; then
|
if test -z "$DEFAULT_MANIFEST"; then
|
||||||
R_RSRC='
|
R_RSRC='
|
||||||
*(.rsrc)
|
*(.rsrc)
|
||||||
*(SORT(.rsrc$*))'
|
*(.rsrc$*)'
|
||||||
else
|
else
|
||||||
R_RSRC="
|
R_RSRC="
|
||||||
/* The default manifest contains information necessary for
|
/* The default manifest contains information necessary for
|
||||||
binaries to run under Windows 8 (or later). It is included as
|
binaries to run under Windows 8 (or later). It is included as
|
||||||
the last resource file so that if the application has provided
|
the last resource file so that if the application has provided
|
||||||
its own manifest then that one will take precedence. */
|
its own manifest then that one will take precedence.
|
||||||
|
|
||||||
|
Note - the .rsrc section merging code relies upon the fact
|
||||||
|
that the input .rsrc sections are *not* sorted. */
|
||||||
*(EXCLUDE_FILE (*$DEFAULT_MANIFEST) .rsrc)
|
*(EXCLUDE_FILE (*$DEFAULT_MANIFEST) .rsrc)
|
||||||
*(SORT(.rsrc*))
|
*(.rsrc*)
|
||||||
KEEP ($DEFAULT_MANIFEST(.rsrc))"
|
KEEP ($DEFAULT_MANIFEST(.rsrc))"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
@ -47,15 +47,18 @@ if test "${RELOCATING}"; then
|
|||||||
if test -z "$DEFAULT_MANIFEST"; then
|
if test -z "$DEFAULT_MANIFEST"; then
|
||||||
R_RSRC='
|
R_RSRC='
|
||||||
*(.rsrc)
|
*(.rsrc)
|
||||||
*(SORT(.rsrc$*))'
|
*(.rsrc$*)'
|
||||||
else
|
else
|
||||||
R_RSRC="
|
R_RSRC="
|
||||||
/* The default manifest contains information necessary for
|
/* The default manifest contains information necessary for
|
||||||
binaries to run under Windows 8 (or later). It is included as
|
binaries to run under Windows 8 (or later). It is included as
|
||||||
the last resource file so that if the application has provided
|
the last resource file so that if the application has provided
|
||||||
its own manifest then that one will take precedence. */
|
its own manifest then that one will take precedence.
|
||||||
|
|
||||||
|
Note - the .rsrc section merging code relies upon the fact
|
||||||
|
that the input .rsrc sections are *not* sorted. */
|
||||||
*(EXCLUDE_FILE (*$DEFAULT_MANIFEST) .rsrc)
|
*(EXCLUDE_FILE (*$DEFAULT_MANIFEST) .rsrc)
|
||||||
*(SORT(.rsrc*))
|
*(.rsrc*)
|
||||||
KEEP ($DEFAULT_MANIFEST(.rsrc))"
|
KEEP ($DEFAULT_MANIFEST(.rsrc))"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user