PATCH: PR 797: Alignment in empty section changes the output layout
H. J. Lu
hjl@lucon.org
Wed May 4 19:53:00 GMT 2005
The recent linker change makes this bug easier to fix. Here is an
updated patch.
H.J.
---
bfd/
2005-05-04 H.J. Lu <hongjiu.lu@intel.com>
PR 797
* elf32-i386.c (elf_i386_size_dynamic_sections): Also remove
empty sdynbss section.
* elf64-x86-64.c (elf64_x86_64_size_dynamic_sections): Likewise.
ld/
2005-05-04 H.J. Lu <hongjiu.lu@intel.com>
PR 797
* ldlang.c (lang_output_section_statement_lookup_1): Set the
ignored field to FALSE.
(strip_unused_output_sections): New.
(strip_excluded_or_unused_output_sections): This. Accept an
argument to check for unused sections.
(lang_size_sections_1): Skip an output section if it should
be ignored.
(lang_do_assignments_1): Likewise.
(lang_process): Call strip_unused_output_sections to remove
unused output sections after lang_mark_used_section.
* ldlang.h (lang_output_section_statement_type): Change
all_input_readonly to bitfield. Add ignored.
--- binutils/bfd/elf32-i386.c.empty 2005-05-04 08:52:10.000000000 -0700
+++ binutils/bfd/elf32-i386.c 2005-05-04 10:08:02.000000000 -0700
@@ -1830,7 +1830,8 @@ elf_i386_size_dynamic_sections (bfd *out
if (s == htab->splt
|| s == htab->sgot
- || s == htab->sgotplt)
+ || s == htab->sgotplt
+ || s == htab->sdynbss)
{
/* Strip this section if we don't need it; see the
comment below. */
--- binutils/bfd/elf64-x86-64.c.empty 2005-05-04 08:52:16.000000000 -0700
+++ binutils/bfd/elf64-x86-64.c 2005-05-04 10:08:02.000000000 -0700
@@ -1622,7 +1622,8 @@ elf64_x86_64_size_dynamic_sections (bfd
if (s == htab->splt
|| s == htab->sgot
- || s == htab->sgotplt)
+ || s == htab->sgotplt
+ || s == htab->sdynbss)
{
/* Strip this section if we don't need it; see the
comment below. */
--- binutils/ld/ldlang.c.empty 2005-05-04 08:52:34.000000000 -0700
+++ binutils/ld/ldlang.c 2005-05-04 11:03:09.000000000 -0700
@@ -1022,6 +1022,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);
@@ -3084,6 +3085,41 @@ strip_excluded_output_sections (void)
stripped_excluded_sections = TRUE;
}
+/* An output section might have been removed after its statement was
+ added if it isn't used at all. Clean them up here. */
+
+static void
+strip_unused_output_sections (void)
+{
+ lang_output_section_statement_type *os;
+
+ for (os = &lang_output_section_statement.head->output_section_statement;
+ os != NULL;
+ os = os->next)
+ {
+ asection *s;
+
+ if (os->constraint == -1)
+ continue;
+
+ s = os->bfd_section;
+
+ if (s != NULL
+ && s->linker_has_input == 0
+ && (s->flags & (SEC_KEEP | SEC_HAS_CONTENTS)) == 0)
+ {
+ /* We don't set bfd_section to NULL since bfd_section of the
+ removed output section statement may still be used. */
+ os->ignored = TRUE;
+ if (!bfd_section_removed_from_list (output_bfd, s))
+ {
+ bfd_section_list_remove (output_bfd, s);
+ output_bfd->section_count--;
+ }
+ }
+ }
+}
+
static void
print_output_section_statement
(lang_output_section_statement_type *output_section_statement)
@@ -3855,8 +3891,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
@@ -4351,7 +4387,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);
@@ -4365,7 +4401,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",
@@ -5301,9 +5337,19 @@ lang_process (void)
}
}
while (relax_again);
+ }
+ if (command_line.relax || !link_info.relocatable)
+ {
/* Final extra sizing to report errors. */
lang_do_assignments (statement_list.head, abs_output_section, NULL, 0);
+ if (!link_info.relocatable)
+ {
+ lang_mark_used_section ();
+ /* Do it here so that the unused output_sections won't affect
+ memory layout. */
+ strip_unused_output_sections ();
+ }
lang_reset_memory_regions ();
lang_size_sections (statement_list.head, abs_output_section,
&statement_list.head, 0, 0, NULL, TRUE);
@@ -5327,7 +5373,7 @@ lang_process (void)
lang_check_section_addresses ();
/* Final stuffs. */
- lang_mark_used_section ();
+
ldemul_finish ();
lang_finish ();
}
--- binutils/ld/ldlang.h.empty 2005-05-04 08:52:34.000000000 -0700
+++ binutils/ld/ldlang.h 2005-05-04 10:36:53.000000000 -0700
@@ -147,7 +147,8 @@ typedef struct lang_output_section_state
int subsection_alignment; /* Alignment of components. */
int section_alignment; /* Alignment of start of section. */
int constraint;
- bfd_boolean all_input_readonly;
+ unsigned int all_input_readonly : 1;
+ unsigned int ignored : 1;
union etree_union *load_base;
More information about the Binutils
mailing list