diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2005-05-17 16:43:02 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2005-05-17 16:43:02 +0000 |
commit | 75ff45898cb591177506dc60164e167fc8c79c59 (patch) | |
tree | 4a25a8df9a4b7422ad862803d16b906f50e7508c | |
parent | 8e0ed13fa56c0f18e69a559dcace1fc9431874a2 (diff) | |
download | gdb-75ff45898cb591177506dc60164e167fc8c79c59.zip gdb-75ff45898cb591177506dc60164e167fc8c79c59.tar.gz gdb-75ff45898cb591177506dc60164e167fc8c79c59.tar.bz2 |
bfd/
2005-05-17 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-17 H.J. Lu <hongjiu.lu@intel.com>
PR 797
* ldexp.c (exp_fold_tree_1): Renamed from exp_fold_tree and
take take a bfd_boolean, mark_used. Ignore assert failure if
mark_used is TRUE.
(exp_fold_tree) Call exp_fold_tree_1 with mark_used == FALSE.
(exp_fold_tree_no_dot): Updated to take a bfd_boolean,
mark_used and pass down.
(fold_unary): Likewise.
(fold_binary): Likewise.
(fold_trinary): Likewise.
(exp_binop): Add FALSE to call to exp_fold_tree_no_dot.
(exp_trinop): Likewise.
(exp_unop): Likewise.
(exp_nameop): Likewise.
(exp_get_vma): Likewise.
(exp_get_fill): Likewise.
(exp_get_abs_int): Likewise.
(fold_name): Likewise. Set SEC_KEEP in output section flags.
(exp_mark_used_section): New.
* ldexp.h (exp_mark_used_section): New.
* ldlang.c (lang_output_section_statement_lookup_1): Set the
ignored field to FALSE.
(lang_mark_used_section_1): New.
(lang_mark_used_section): Call lang_mark_used_section_1.
(strip_excluded_output_sections): Call lang_mark_used_section
and check for unused sections.
(lang_size_sections_1): Skip an output section if it should
be ignored.
(lang_do_assignments_1): Likewise.
(lang_process): Don't call lang_mark_used_section here.
* ldlang.h (lang_output_section_statement_type): Change
all_input_readonly to bitfield. Add ignored.
ld/testsuite/
2005-05-17 H.J. Lu <hongjiu.lu@intel.com>
PR 797
* empty-aligned.d: New file.
* empty-aligned.exp: Likewise.
* empty-aligned.s: Likewise.
* empty-aligned.t: Likewise.
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 3 | ||||
-rw-r--r-- | bfd/elf64-x86-64.c | 3 | ||||
-rw-r--r-- | ld/ChangeLog | 38 | ||||
-rw-r--r-- | ld/ldexp.c | 261 | ||||
-rw-r--r-- | ld/ldexp.h | 2 | ||||
-rw-r--r-- | ld/ldlang.c | 150 | ||||
-rw-r--r-- | ld/ldlang.h | 3 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/empty-aligned.d | 12 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/empty-aligned.exp | 26 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/empty-aligned.s | 4 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/empty-aligned.t | 16 |
13 files changed, 442 insertions, 91 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index feb815f..e60fbd6 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2005-05-17 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. + 2005-05-17 Tavis Ormandy <taviso@gentoo.org> * elf.c (bfd_section_from_shdr): Add sanity check when parsing diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 491fd9b..bfc3417 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1914,7 +1914,8 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, 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. */ diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index a1c2ea8..179530b 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -1624,7 +1624,8 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, 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. */ diff --git a/ld/ChangeLog b/ld/ChangeLog index 69a483f..08b2f67 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,41 @@ +2005-05-17 H.J. Lu <hongjiu.lu@intel.com> + + PR 797 + * ldexp.c (exp_fold_tree_1): Renamed from exp_fold_tree and + take take a bfd_boolean, mark_used. Ignore assert failure if + mark_used is TRUE. + (exp_fold_tree) Call exp_fold_tree_1 with mark_used == FALSE. + (exp_fold_tree_no_dot): Updated to take a bfd_boolean, + mark_used and pass down. + (fold_unary): Likewise. + (fold_binary): Likewise. + (fold_trinary): Likewise. + (exp_binop): Add FALSE to call to exp_fold_tree_no_dot. + (exp_trinop): Likewise. + (exp_unop): Likewise. + (exp_nameop): Likewise. + (exp_get_vma): Likewise. + (exp_get_fill): Likewise. + (exp_get_abs_int): Likewise. + (fold_name): Likewise. Set SEC_KEEP in output section flags. + (exp_mark_used_section): New. + + * ldexp.h (exp_mark_used_section): New. + + * ldlang.c (lang_output_section_statement_lookup_1): Set the + ignored field to FALSE. + (lang_mark_used_section_1): New. + (lang_mark_used_section): Call lang_mark_used_section_1. + (strip_excluded_output_sections): Call lang_mark_used_section + and check for unused sections. + (lang_size_sections_1): Skip an output section if it should + be ignored. + (lang_do_assignments_1): Likewise. + (lang_process): Don't call lang_mark_used_section here. + + * ldlang.h (lang_output_section_statement_type): Change + all_input_readonly to bitfield. Add ignored. + 2005-05-17 Lennert Buytenhek <buytenh@wantstofly.org> Peter S. Mazinger" <ps.m@gmx.net> @@ -41,8 +41,12 @@ #include "libiberty.h" #include "safe-ctype.h" +static etree_value_type exp_fold_tree_1 + (etree_type *, lang_output_section_statement_type *, + lang_phase_type, bfd_vma, bfd_vma *, bfd_boolean); static etree_value_type exp_fold_tree_no_dot - (etree_type *, lang_output_section_statement_type *, lang_phase_type); + (etree_type *, lang_output_section_statement_type *, lang_phase_type, + bfd_boolean); static bfd_vma align_n (bfd_vma, bfd_vma); @@ -219,13 +223,14 @@ fold_unary (etree_type *tree, lang_output_section_statement_type *current_section, lang_phase_type allocation_done, bfd_vma dot, - bfd_vma *dotp) + bfd_vma *dotp, + bfd_boolean mark_used) { etree_value_type result; - result = exp_fold_tree (tree->unary.child, - current_section, - allocation_done, dot, dotp); + result = exp_fold_tree_1 (tree->unary.child, + current_section, + allocation_done, dot, dotp, mark_used); if (result.valid_p) { switch (tree->type.node_code) @@ -308,12 +313,13 @@ fold_binary (etree_type *tree, lang_output_section_statement_type *current_section, lang_phase_type allocation_done, bfd_vma dot, - bfd_vma *dotp) + bfd_vma *dotp, + bfd_boolean mark_used) { etree_value_type result; - result = exp_fold_tree (tree->binary.lhs, current_section, - allocation_done, dot, dotp); + result = exp_fold_tree_1 (tree->binary.lhs, current_section, + allocation_done, dot, dotp, mark_used); /* The SEGMENT_START operator is special because its first operand is a string, not the name of a symbol. */ @@ -338,9 +344,10 @@ fold_binary (etree_type *tree, { etree_value_type other; - other = exp_fold_tree (tree->binary.rhs, - current_section, - allocation_done, dot, dotp); + other = exp_fold_tree_1 (tree->binary.rhs, + current_section, + allocation_done, + dot, dotp, mark_used); if (other.valid_p) { /* If the values are from different sections, or this is an @@ -498,18 +505,20 @@ fold_trinary (etree_type *tree, lang_output_section_statement_type *current_section, lang_phase_type allocation_done, bfd_vma dot, - bfd_vma *dotp) + bfd_vma *dotp, + bfd_boolean mark_used) { etree_value_type result; - result = exp_fold_tree (tree->trinary.cond, current_section, - allocation_done, dot, dotp); + result = exp_fold_tree_1 (tree->trinary.cond, current_section, + allocation_done, dot, dotp, mark_used); if (result.valid_p) - result = exp_fold_tree ((result.value - ? tree->trinary.lhs - : tree->trinary.rhs), - current_section, - allocation_done, dot, dotp); + result = exp_fold_tree_1 ((result.value + ? tree->trinary.lhs + : tree->trinary.rhs), + current_section, + allocation_done, + dot, dotp, mark_used); return result; } @@ -518,7 +527,8 @@ static etree_value_type fold_name (etree_type *tree, lang_output_section_statement_type *current_section, lang_phase_type allocation_done, - bfd_vma dot) + bfd_vma dot, + bfd_boolean mark_used) { etree_value_type result; @@ -596,6 +606,7 @@ fold_name (etree_type *tree, + h->u.def.section->output_offset), NULL, os); + os->bfd_section->flags |= SEC_KEEP; } } } @@ -619,8 +630,12 @@ fold_name (etree_type *tree, lang_output_section_statement_type *os; os = lang_output_section_find (tree->name.name); - if (os && os->processed > 0) - result = new_rel (0, NULL, os); + if (os) + { + os->bfd_section->flags |= SEC_KEEP; + if (os->processed > 0) + result = new_rel (0, NULL, os); + } } break; @@ -630,14 +645,19 @@ fold_name (etree_type *tree, lang_output_section_statement_type *os; os = lang_output_section_find (tree->name.name); - if (os && os->processed != 0) + if (os) { - if (os->load_base == NULL) - result = new_rel (0, NULL, os); - else - result = exp_fold_tree_no_dot (os->load_base, - abs_output_section, - allocation_done); + os->bfd_section->flags |= SEC_KEEP; + if (os->processed != 0) + { + if (os->load_base == NULL) + result = new_rel (0, NULL, os); + else + result = exp_fold_tree_no_dot (os->load_base, + abs_output_section, + allocation_done, + mark_used); + } } } break; @@ -649,8 +669,12 @@ fold_name (etree_type *tree, lang_output_section_statement_type *os; os = lang_output_section_find (tree->name.name); - if (os && os->processed > 0) - result = new_abs (os->bfd_section->size / opb); + if (os) + { + os->bfd_section->flags |= SEC_KEEP; + if (os->processed > 0) + result = new_abs (os->bfd_section->size / opb); + } } break; @@ -688,12 +712,13 @@ fold_name (etree_type *tree, return result; } -etree_value_type -exp_fold_tree (etree_type *tree, - lang_output_section_statement_type *current_section, - lang_phase_type allocation_done, - bfd_vma dot, - bfd_vma *dotp) +static etree_value_type +exp_fold_tree_1 (etree_type *tree, + lang_output_section_statement_type *current_section, + lang_phase_type allocation_done, + bfd_vma dot, + bfd_vma *dotp, + bfd_boolean mark_used) { etree_value_type result; @@ -721,26 +746,34 @@ exp_fold_tree (etree_type *tree, break; case etree_assert: - result = exp_fold_tree (tree->assert_s.child, - current_section, - allocation_done, dot, dotp); - if (result.valid_p && !result.value) - einfo ("%X%P: %s\n", tree->assert_s.message); + result = exp_fold_tree_1 (tree->assert_s.child, + current_section, + allocation_done, dot, dotp, + mark_used); + if (result.valid_p) + { + if (mark_used) + /* We don't care if assert fails or not when we are just + marking if a section is used or not. */ + result.value = 1; + else if (!result.value) + einfo ("%X%P: %s\n", tree->assert_s.message); + } break; case etree_unary: result = fold_unary (tree, current_section, allocation_done, - dot, dotp); + dot, dotp, mark_used); break; case etree_binary: result = fold_binary (tree, current_section, allocation_done, - dot, dotp); + dot, dotp, mark_used); break; case etree_trinary: result = fold_trinary (tree, current_section, allocation_done, - dot, dotp); + dot, dotp, mark_used); break; case etree_assign: @@ -757,9 +790,10 @@ exp_fold_tree (etree_type *tree, { /* Notify the folder that this is an assignment to dot. */ assigning_to_dot = TRUE; - result = exp_fold_tree (tree->assign.src, - current_section, - allocation_done, dot, dotp); + result = exp_fold_tree_1 (tree->assign.src, + current_section, + allocation_done, + dot, dotp, mark_used); assigning_to_dot = FALSE; if (! result.valid_p) @@ -788,9 +822,9 @@ exp_fold_tree (etree_type *tree, } else { - result = exp_fold_tree (tree->assign.src, - current_section, allocation_done, - dot, dotp); + result = exp_fold_tree_1 (tree->assign.src, + current_section, allocation_done, + dot, dotp, mark_used); if (result.valid_p) { bfd_boolean create; @@ -832,7 +866,8 @@ exp_fold_tree (etree_type *tree, break; case etree_name: - result = fold_name (tree, current_section, allocation_done, dot); + result = fold_name (tree, current_section, allocation_done, dot, + mark_used); break; default: @@ -844,12 +879,25 @@ exp_fold_tree (etree_type *tree, return result; } +etree_value_type +exp_fold_tree (etree_type *tree, + lang_output_section_statement_type *current_section, + lang_phase_type allocation_done, + bfd_vma dot, + bfd_vma *dotp) +{ + return exp_fold_tree_1 (tree, current_section, allocation_done, + dot, dotp, FALSE); +} + static etree_value_type exp_fold_tree_no_dot (etree_type *tree, lang_output_section_statement_type *current_section, - lang_phase_type allocation_done) + lang_phase_type allocation_done, + bfd_boolean mark_used) { - return exp_fold_tree (tree, current_section, allocation_done, 0, NULL); + return exp_fold_tree_1 (tree, current_section, allocation_done, 0, + NULL, mark_used); } etree_type * @@ -864,7 +912,7 @@ exp_binop (int code, etree_type *lhs, etree_type *rhs) value.type.node_class = etree_binary; r = exp_fold_tree_no_dot (&value, abs_output_section, - lang_first_phase_enum); + lang_first_phase_enum, FALSE); if (r.valid_p) { return exp_intop (r.value); @@ -884,7 +932,7 @@ exp_trinop (int code, etree_type *cond, etree_type *lhs, etree_type *rhs) value.trinary.cond = cond; value.trinary.rhs = rhs; value.type.node_class = etree_trinary; - r = exp_fold_tree_no_dot (&value, NULL, lang_first_phase_enum); + r = exp_fold_tree_no_dot (&value, NULL, lang_first_phase_enum, FALSE); if (r.valid_p) return exp_intop (r.value); @@ -903,7 +951,7 @@ exp_unop (int code, etree_type *child) value.unary.child = child; value.unary.type.node_class = etree_unary; r = exp_fold_tree_no_dot (&value, abs_output_section, - lang_first_phase_enum); + lang_first_phase_enum, FALSE); if (r.valid_p) return exp_intop (r.value); @@ -921,7 +969,7 @@ exp_nameop (int code, const char *name) value.name.name = name; value.name.type.node_class = etree_name; - r = exp_fold_tree_no_dot (&value, NULL, lang_first_phase_enum); + r = exp_fold_tree_no_dot (&value, NULL, lang_first_phase_enum, FALSE); if (r.valid_p) return exp_intop (r.value); @@ -1071,7 +1119,8 @@ exp_get_vma (etree_type *tree, if (tree != NULL) { - r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done); + r = exp_fold_tree_no_dot (tree, abs_output_section, + allocation_done, FALSE); if (! r.valid_p && name != NULL) einfo (_("%F%S nonconstant expression for %s\n"), name); return r.value; @@ -1103,7 +1152,8 @@ exp_get_fill (etree_type *tree, if (tree == NULL) return def; - r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done); + r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done, + FALSE); if (! r.valid_p && name != NULL) einfo (_("%F%S nonconstant expression for %s\n"), name); @@ -1154,7 +1204,8 @@ exp_get_abs_int (etree_type *tree, lang_phase_type allocation_done) { etree_value_type res; - res = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done); + res = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done, + FALSE); if (res.valid_p) res.value += res.section->bfd_section->vma; @@ -1173,3 +1224,91 @@ align_n (bfd_vma value, bfd_vma align) value = (value + align - 1) / align; return value * align; } + +void +exp_mark_used_section + (etree_type *tree, + lang_output_section_statement_type *current_section) +{ + switch (tree->type.node_class) + { + case etree_value: + break; + + case etree_rel: + break; + + case etree_assert: + break; + + case etree_unary: + break; + + case etree_binary: + break; + + case etree_trinary: + break; + + case etree_assign: + case etree_provide: + case etree_provided: + if (tree->assign.dst[0] != '.' || tree->assign.dst[1] != 0) + { + etree_value_type result; + bfd_vma dot = 0; + + result = exp_fold_tree_1 (tree->assign.src, + current_section, + lang_allocating_phase_enum, + dot, &dot, TRUE); + if (result.valid_p) + { + bfd_boolean create; + struct bfd_link_hash_entry *h; + + if (tree->type.node_class == etree_assign) + create = TRUE; + else + create = FALSE; + h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst, + create, FALSE, TRUE); + if (h == NULL) + { + if (create) + einfo (_("%P%F:%s: hash creation failed\n"), + tree->assign.dst); + } + else if (tree->type.node_class == etree_provide + && h->type != bfd_link_hash_new + && h->type != bfd_link_hash_undefined + && h->type != bfd_link_hash_common) + { + /* Do nothing. The symbol was defined by some + object. */ + } + else + { + /* FIXME: Should we worry if the symbol is already + defined? */ + lang_update_definedness (tree->assign.dst, h); + h->type = bfd_link_hash_defined; + h->u.def.value = result.value; + h->u.def.section = result.section->bfd_section; + if (tree->type.node_class == etree_provide) + tree->type.node_class = etree_provided; + } + } + } + break; + + case etree_name: + fold_name (tree, current_section, lang_allocating_phase_enum, 0, + TRUE); + break; + + default: + abort (); + break; + } +} @@ -156,5 +156,7 @@ fill_type *exp_get_fill (etree_type *, fill_type *, char *, lang_phase_type); bfd_vma exp_get_abs_int (etree_type *, int, char *, lang_phase_type); +void exp_mark_used_section + (etree_type *, struct lang_output_section_statement_struct *); #endif diff --git a/ld/ldlang.c b/ld/ldlang.c index ee85422..835c93a 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1024,6 +1024,7 @@ lang_output_section_statement_lookup_1 (const char *const name, int constraint) 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); @@ -3042,6 +3043,90 @@ map_input_to_output_sections } } +/* Worker function for lang_mark_used_section. Recursiveness goes + here. */ + +static void +lang_mark_used_section_1 + (lang_statement_union_type *s, + lang_output_section_statement_type *output_section_statement) +{ + for (; s != NULL; s = s->header.next) + { + switch (s->header.type) + { + case lang_constructors_statement_enum: + break; + + case lang_output_section_statement_enum: + { + lang_output_section_statement_type *os; + + os = &(s->output_section_statement); + if (os->bfd_section != NULL) + lang_mark_used_section_1 (os->children.head, os); + } + break; + case lang_wild_statement_enum: + lang_mark_used_section_1 (s->wild_statement.children.head, + output_section_statement); + + break; + + case lang_object_symbols_statement_enum: + case lang_output_statement_enum: + case lang_target_statement_enum: + break; + case lang_data_statement_enum: + exp_mark_used_section (s->data_statement.exp, + abs_output_section); + break; + + case lang_reloc_statement_enum: + break; + + case lang_input_section_enum: + break; + + case lang_input_statement_enum: + break; + case lang_fill_statement_enum: + break; + case lang_assignment_statement_enum: + exp_mark_used_section (s->assignment_statement.exp, + output_section_statement); + break; + case lang_padding_statement_enum: + break; + + case lang_group_statement_enum: + lang_mark_used_section_1 (s->group_statement.children.head, + output_section_statement); + break; + + default: + FAIL (); + break; + case lang_address_statement_enum: + break; + } + } +} + +static void +lang_mark_used_section (void) +{ + unsigned int gc_sections = link_info.gc_sections; + + /* Callers of exp_fold_tree need to increment this. */ + lang_statement_iteration++; + lang_mark_used_section_1 (statement_list.head, abs_output_section); + + link_info.gc_sections = 0; + bfd_gc_sections (output_bfd, &link_info); + link_info.gc_sections = gc_sections; +} + /* An output section might have been removed after its statement was added. For example, ldemul_before_allocation can remove dynamic sections if they turn out to be not needed. Clean them up here. */ @@ -3051,32 +3136,54 @@ strip_excluded_output_sections (void) { lang_output_section_statement_type *os; + lang_mark_used_section (); + for (os = &lang_output_section_statement.head->output_section_statement; os != NULL; os = os->next) { - asection *s; + asection *output_section; + bfd_boolean exclude; if (os->constraint == -1) continue; - if (os->bfd_section == NULL || os->bfd_section->map_head.s == NULL) + output_section = os->bfd_section; + if (output_section == NULL) continue; - for (s = os->bfd_section->map_head.s; s != NULL; s = s->map_head.s) - if ((s->flags & SEC_EXCLUDE) == 0) - break; + exclude = FALSE; + if (output_section->map_head.s != NULL) + { + asection *s; - os->bfd_section->map_head.link_order = NULL; - os->bfd_section->map_tail.link_order = NULL; + for (s = output_section->map_head.s; s != NULL; + s = s->map_head.s) + if ((s->flags & SEC_EXCLUDE) == 0) + break; + + output_section->map_head.link_order = NULL; + output_section->map_tail.link_order = NULL; + + if (s == NULL) + exclude = TRUE; + } - if (s == NULL) + if (exclude + || (output_section->linker_has_input == 0 + && ((output_section->flags + & (SEC_KEEP | SEC_HAS_CONTENTS)) == 0))) { - s = os->bfd_section; - os->bfd_section = NULL; - if (!bfd_section_removed_from_list (output_bfd, s)) + if (exclude) + os->bfd_section = NULL; + else + /* 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, + output_section)) { - bfd_section_list_remove (output_bfd, s); + bfd_section_list_remove (output_bfd, output_section); output_bfd->section_count--; } } @@ -3936,8 +4043,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 @@ -4432,7 +4539,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); @@ -4446,7 +4553,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", @@ -5240,16 +5347,6 @@ lang_gc_sections (void) bfd_gc_sections (output_bfd, &link_info); } -static void -lang_mark_used_section (void) -{ - unsigned int gc_sections = link_info.gc_sections; - - link_info.gc_sections = 0; - bfd_gc_sections (output_bfd, &link_info); - link_info.gc_sections = gc_sections; -} - void lang_process (void) { @@ -5408,7 +5505,6 @@ lang_process (void) lang_check_section_addresses (); /* Final stuffs. */ - lang_mark_used_section (); ldemul_finish (); lang_finish (); } diff --git a/ld/ldlang.h b/ld/ldlang.h index 156adcd..eb4fc5e 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -147,7 +147,8 @@ typedef struct lang_output_section_statement_struct 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; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 4cf3c1b..0734b17 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2005-05-17 H.J. Lu <hongjiu.lu@intel.com> + + PR 797 + * empty-aligned.d: New file. + * empty-aligned.exp: Likewise. + * empty-aligned.s: Likewise. + * empty-aligned.t: Likewise. + 2005-05-11 Bob Wilson <bob.wilson@acm.org> * ld-undefined/undefined.exp: xfail xtensa-*-*. diff --git a/ld/testsuite/ld-scripts/empty-aligned.d b/ld/testsuite/ld-scripts/empty-aligned.d new file mode 100644 index 0000000..493a40c --- /dev/null +++ b/ld/testsuite/ld-scripts/empty-aligned.d @@ -0,0 +1,12 @@ +#source: empty-aligned.s +#ld: -T empty-aligned.t +#readelf: -l --wide + +#... +Program Headers: + +Type +Offset +VirtAddr +PhysAddr +FileSiz +MemSiz +Flg +Align + +LOAD +0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ 0x[0-9a-f]+ [RWE ]+ +0x[0-9a-f]+ + + Section to Segment mapping: + +Segment Sections\.\.\. + +00.*\.text.*\.data.* diff --git a/ld/testsuite/ld-scripts/empty-aligned.exp b/ld/testsuite/ld-scripts/empty-aligned.exp new file mode 100644 index 0000000..17820ed --- /dev/null +++ b/ld/testsuite/ld-scripts/empty-aligned.exp @@ -0,0 +1,26 @@ +# Make sure empty aligned sections do not change output layout. +# Copyright 2005 +# Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + +# PHDRS is only meaningful for ELF. +if ![is_elf_format] { + return +} + +set testname "empty-aligned" + +run_dump_test empty-aligned diff --git a/ld/testsuite/ld-scripts/empty-aligned.s b/ld/testsuite/ld-scripts/empty-aligned.s new file mode 100644 index 0000000..f386e9e --- /dev/null +++ b/ld/testsuite/ld-scripts/empty-aligned.s @@ -0,0 +1,4 @@ + .text + .long 123 + .data + .long 123 diff --git a/ld/testsuite/ld-scripts/empty-aligned.t b/ld/testsuite/ld-scripts/empty-aligned.t new file mode 100644 index 0000000..d3036be --- /dev/null +++ b/ld/testsuite/ld-scripts/empty-aligned.t @@ -0,0 +1,16 @@ +SECTIONS +{ + .text : { *(.text) } + .text2 : + { + . = ALIGN(4096); + *(.text2) + } + .text3 : + { + *(.text3) + . = ALIGN(4096); + } + .data : { *(.data) } + .bss : { *(.bss) } +} |