This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: PATCH: PR 797: Alignment in empty section changes the output layout
- From: "H. J. Lu" <hjl at lucon dot org>
- To: binutils at sources dot redhat dot com
- Date: Thu, 24 Mar 2005 14:05:56 -0800
- Subject: Re: PATCH: PR 797: Alignment in empty section changes the output layout
- References: <20050324003653.GA28321@lucon.org>
On Wed, Mar 23, 2005 at 04:36:53PM -0800, H. J. Lu wrote:
> This patch tries to undo the damange caused by the unused output
> sections in linker script by removing them and resizing the remaining
> sections.
>
>
> H.J.
> ----
> 2005-03-23 H.J. Lu <hongjiu.lu@intel.com>
>
> PR 797
> * emultempl/elf32.em (gld${EMULATION_NAME}_finish): Remove
> the unused output sections without input sections and the empty
> unused output sections created by linker, if they don't have
> any contents. Resize sections.
>
> * ldlang.c (lang_output_section_statement_lookup_1): Set the
> ignored field to FALSE.
> (lang_size_sections_1): Skip an output section if it should
> be ignored.
>
> * ldlang.h (lang_output_section_statement_type): Add ignored.
>
I missed one place in lang_do_assignments_1. We need to skip the
ignored output section when we assign values to symbols. Otherwise,
their values will be incorrect.
H.J.
----
2005-03-24 H.J. Lu <hongjiu.lu@intel.com>
PR 797
* emultempl/elf32.em (gld${EMULATION_NAME}_finish): Remove
the unused output sections without input sections and the empty
unused output sections created by linker, if they don't have
any contents. Resize sections.
* ldlang.c (lang_output_section_statement_lookup_1): Set the
ignored field to FALSE.
(lang_size_sections_1): Skip an output section if it should
be ignored.
(lang_do_assignments_1): Likewise.
* ldlang.h (lang_output_section_statement_type): Add ignored.
--- ld/emultempl/elf32.em.empty 2005-03-23 11:05:04.000000000 -0800
+++ ld/emultempl/elf32.em 2005-03-24 08:58:05.000000000 -0800
@@ -1472,20 +1472,76 @@ gld${EMULATION_NAME}_finish (void)
if (!link_info.relocatable)
{
lang_output_section_statement_type *os;
+ asection *s, **p;
+ bfd_boolean resize = FALSE;
+
+ /* We want to remove unused output sections and resize the
+ remaining sections so that any alignment changes caused by
+ those removed output sections are reverted. Possible unused
+ output sections are those without input sections or empty.
+ We can't remove all unused output sections without input
+ sections since they may be created by linker scripts. We can't
+ remove all empty unused output sections since they may have
+ empty input sections whose alignments may affect the memory
+ layout of output sections which we don't want to change.
+
+ So we remove the unused output sections without input sections
+ and the empty unused output sections created by linker, if
+ they don't have any contents. */
for (os = &lang_output_section_statement.head->output_section_statement;
os != NULL;
os = os->next)
{
- asection *s;
+ if (os == abs_output_section || os->constraint == -1)
+ continue;
+ s = os->bfd_section;
+ if (s != NULL
+ && (s->linker_has_input == 0
+ || (s->size == 0
+ && (s->flags & SEC_LINKER_CREATED) != 0))
+ && (s->flags & (SEC_KEEP | SEC_HAS_CONTENTS)) == 0)
+ {
+ os->ignored = TRUE;
+ resize = TRUE;
+
+ for (p = &output_bfd->sections; *p; p = &(*p)->next)
+ if (*p == s)
+ {
+ bfd_section_list_remove (output_bfd, p);
+ output_bfd->section_count--;
+ break;
+ }
+ }
+ }
+
+ /* Resize to revert the changes from those removed sections. */
+ if (resize)
+ {
+ lang_reset_memory_regions ();
+
+ /* Resize the sections. */
+ lang_size_sections (stat_ptr->head, abs_output_section,
+ &stat_ptr->head, 0, (bfd_vma) 0,
+ NULL, TRUE);
+
+ /* Redo special stuff. */
+ ldemul_after_allocation ();
+
+ /* Do the assignments again. */
+ lang_do_assignments (stat_ptr->head, abs_output_section,
+ (fill_type *) 0, (bfd_vma) 0);
+ }
+ for (os = &lang_output_section_statement.head->output_section_statement;
+ os != NULL;
+ os = os->next)
+ {
if (os == abs_output_section || os->constraint == -1)
continue;
s = os->bfd_section;
if (s != NULL && s->size == 0 && (s->flags & SEC_KEEP) == 0)
{
- asection **p;
-
for (p = &output_bfd->sections; *p; p = &(*p)->next)
if (*p == s)
{
--- ld/ldlang.c.empty 2005-03-24 11:13:06.000000000 -0800
+++ ld/ldlang.c 2005-03-24 12:37:30.431168331 -0800
@@ -637,6 +637,7 @@ lang_output_section_statement_lookup_1 (
lookup->bfd_section = NULL;
lookup->processed = 0;
lookup->constraint = constraint;
+ lookup->ignored = FALSE;
lookup->sectype = normal_section;
lookup->addr_tree = NULL;
lang_list_init (&lookup->children);
@@ -3418,8 +3419,8 @@ lang_size_sections_1
lang_output_section_statement_type *os;
os = &s->output_section_statement;
- if (os->bfd_section == NULL)
- /* This section was never actually created. */
+ if (os->bfd_section == NULL || os->ignored)
+ /* This section was removed or never actually created. */
break;
/* If this is a COFF shared library section, use the size and
@@ -3914,7 +3915,7 @@ lang_do_assignments_1
lang_output_section_statement_type *os;
os = &(s->output_section_statement);
- if (os->bfd_section != NULL)
+ if (os->bfd_section != NULL && !os->ignored)
{
dot = os->bfd_section->vma;
lang_do_assignments_1 (os->children.head, os, os->fill, dot);
@@ -3928,7 +3929,7 @@ lang_do_assignments_1
{
/* If nothing has been placed into the output section then
it won't have a bfd_section. */
- if (os->bfd_section)
+ if (os->bfd_section && !os->ignored)
{
os->bfd_section->lma
= exp_get_abs_int (os->load_base, 0, "load base",
--- ld/ldlang.h.empty 2005-03-03 08:56:33.000000000 -0800
+++ ld/ldlang.h 2005-03-24 08:58:05.000000000 -0800
@@ -148,6 +148,7 @@ typedef struct lang_output_section_state
int section_alignment; /* Alignment of start of section. */
int constraint;
bfd_boolean all_input_readonly;
+ bfd_boolean ignored;
union etree_union *load_base;