From: Alan Modra Date: Wed, 4 May 2005 11:00:28 +0000 (+0000) Subject: bfd/ X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8423293d34986cfa218f79b2b2f1ff9bf77d468f;p=binutils-gdb.git bfd/ * section.c (struct bfd_section): Replace link_order_head and link_order_tail with map_head and map_tail union. (STD_SECTION): Update. (_bfd_strip_section_from_output): Delete. * aoutx.h: Update throughout for above changes. * coff-ppc.c: Likewise. * cofflink.c: Likewise. * ecoff.c: Likewise. * elf-eh-frame.c: Likewise. * elf-m10300.c: Likewise. * elf.c: Likewise. * elf32-arm.c: Likewise. * elf32-cris.c: Likewise. * elf32-hppa.c: Likewise. * elf32-i386.c: Likewise. * elf32-m32r.c: Likewise. * elf32-m68hc1x.c: Likewise. * elf32-m68k.c: Likewise. * elf32-ppc.c: Likewise. * elf32-s390.c: Likewise. * elf32-sh.c: Likewise. * elf32-vax.c: Likewise. * elf32-xtensa.c: Likewise. * elf64-alpha.c: Likewise. * elf64-hppa.c: Likewise. * elf64-ppc.c: Likewise. * elf64-s390.c: Likewise. * elf64-sh64.c: Likewise. * elf64-x86-64.c: Likewise. * elflink.c: Likewise. * elfxx-ia64.c: Likewise. * elfxx-mips.c: Likewise. * elfxx-sparc.c: Likewise. * linker.c: Likewise. * merge.c: Likewise. * pdp11.c: Likewise. * xcofflink.c: Likewise. * elflink.c (bfd_boolean bfd_elf_size_dynsym_hash_dynstr): Split out from bfd_elf_size_dynamic_sections. * bfd-in.h (bfd_boolean bfd_elf_size_dynsym_hash_dynstr): Declare. * bfd-in2.h: Regenerate. ld/ * ldemul.c: Include bfdlink.h. (ldemul_before_allocation): Assume before_allocation is non-zero. (before_allocation_default): Call strip_excluded_output_sections. * ldlang.c (stripped_excluded_sections): New variable. (lang_add_section): Build input section list for each output section, attached via map_head and map_tail pointers. (strip_excluded_output_sections): Make global. Traverse the input section lists to find which output sections can go. Clear link_order pointers and set stripped_excluded_sections. (lang_process): Call strip_excluded_output_sections. * ldlang.h (strip_excluded_output_sections): Declare. * ldwrite.c: Update throuhout for link_order_head -> map_head change. * emultempl/aix.em (before_allocation): Call strip_excluded_output_sections. * emultempl/armcoff.em (before_allocation): Likewise. * emultempl/beos.em (before_allocation): Likewise. * emultempl/linux.em (before_allocation): Likewise. * emultempl/pe.em (before_allocation): Likewise. * emultempl/sunos.em (before_allocation): Likewise. * emultempl/elf32.em (before_allocation): Likewise. Call bfd_elf_size_dynsym_hash_dynstr too. * emultempl/lnk960.em (lnk960_before_allocation): Delete. (ld_lnk960): Use before_allocation_default. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index e5fb1b28a00..de82e20c0fc 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,47 @@ +2005-05-04 Alan Modra + + * section.c (struct bfd_section): Replace link_order_head and + link_order_tail with map_head and map_tail union. + (STD_SECTION): Update. + (_bfd_strip_section_from_output): Delete. + * aoutx.h: Update throughout for above changes. + * coff-ppc.c: Likewise. + * cofflink.c: Likewise. + * ecoff.c: Likewise. + * elf-eh-frame.c: Likewise. + * elf-m10300.c: Likewise. + * elf.c: Likewise. + * elf32-arm.c: Likewise. + * elf32-cris.c: Likewise. + * elf32-hppa.c: Likewise. + * elf32-i386.c: Likewise. + * elf32-m32r.c: Likewise. + * elf32-m68hc1x.c: Likewise. + * elf32-m68k.c: Likewise. + * elf32-ppc.c: Likewise. + * elf32-s390.c: Likewise. + * elf32-sh.c: Likewise. + * elf32-vax.c: Likewise. + * elf32-xtensa.c: Likewise. + * elf64-alpha.c: Likewise. + * elf64-hppa.c: Likewise. + * elf64-ppc.c: Likewise. + * elf64-s390.c: Likewise. + * elf64-sh64.c: Likewise. + * elf64-x86-64.c: Likewise. + * elflink.c: Likewise. + * elfxx-ia64.c: Likewise. + * elfxx-mips.c: Likewise. + * elfxx-sparc.c: Likewise. + * linker.c: Likewise. + * merge.c: Likewise. + * pdp11.c: Likewise. + * xcofflink.c: Likewise. + * elflink.c (bfd_boolean bfd_elf_size_dynsym_hash_dynstr): Split + out from bfd_elf_size_dynamic_sections. + * bfd-in.h (bfd_boolean bfd_elf_size_dynsym_hash_dynstr): Declare. + * bfd-in2.h: Regenerate. + 2005-05-04 Nick Clifton * COPYING, aix386-core.c, aix5ppc-core.c, aout-adobe.c, diff --git a/bfd/aoutx.h b/bfd/aoutx.h index 8d02a21d01f..18c9f07b258 100644 --- a/bfd/aoutx.h +++ b/bfd/aoutx.h @@ -5318,11 +5318,11 @@ NAME (aout, final_link) (bfd *abfd, { if (obj_textsec (abfd) != NULL) trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd) - ->link_order_head) + ->map_head.link_order) * obj_reloc_entry_size (abfd)); if (obj_datasec (abfd) != NULL) drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd) - ->link_order_head) + ->map_head.link_order) * obj_reloc_entry_size (abfd)); } @@ -5414,7 +5414,7 @@ NAME (aout, final_link) (bfd *abfd, include. */ for (o = abfd->sections; o != NULL; o = o->next) { - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) if (p->type == bfd_indirect_link_order) p->u.indirect.section->linker_mark = TRUE; } @@ -5422,7 +5422,7 @@ NAME (aout, final_link) (bfd *abfd, have_link_order_relocs = FALSE; for (o = abfd->sections; o != NULL; o = o->next) { - for (p = o->link_order_head; + for (p = o->map_head.link_order; p != NULL; p = p->next) { @@ -5467,7 +5467,7 @@ NAME (aout, final_link) (bfd *abfd, { for (o = abfd->sections; o != NULL; o = o->next) { - for (p = o->link_order_head; + for (p = o->map_head.link_order; p != NULL; p = p->next) { diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index 3951094cdf7..2aa6bbb2dc2 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -637,7 +637,10 @@ extern bfd_boolean bfd_elf_get_bfd_needed_list (bfd *, struct bfd_link_needed_list **); extern bfd_boolean bfd_elf_size_dynamic_sections (bfd *, const char *, const char *, const char *, const char * const *, - struct bfd_link_info *, struct bfd_section **, struct bfd_elf_version_tree *); + struct bfd_link_info *, struct bfd_section **, + struct bfd_elf_version_tree *); +extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr + (bfd *, struct bfd_link_info *); extern void bfd_elf_set_dt_needed_name (bfd *, const char *); extern const char *bfd_elf_get_dt_soname diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index eed4dd666d6..45060f8a64a 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -644,7 +644,10 @@ extern bfd_boolean bfd_elf_get_bfd_needed_list (bfd *, struct bfd_link_needed_list **); extern bfd_boolean bfd_elf_size_dynamic_sections (bfd *, const char *, const char *, const char *, const char * const *, - struct bfd_link_info *, struct bfd_section **, struct bfd_elf_version_tree *); + struct bfd_link_info *, struct bfd_section **, + struct bfd_elf_version_tree *); +extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr + (bfd *, struct bfd_link_info *); extern void bfd_elf_set_dt_needed_name (bfd *, const char *); extern const char *bfd_elf_get_dt_soname @@ -1396,8 +1399,14 @@ typedef struct bfd_section struct bfd_symbol *symbol; struct bfd_symbol **symbol_ptr_ptr; - struct bfd_link_order *link_order_head; - struct bfd_link_order *link_order_tail; + /* Early in the link process, map_head and map_tail are used to build + a list of input sections attached to an output section. Later, + output sections use these fields for a list of bfd_link_order + structs. */ + union { + struct bfd_link_order *link_order; + struct bfd_section *s; + } map_head, map_tail; } asection; /* These sections are global, and are managed by BFD. The application @@ -1579,9 +1588,6 @@ bfd_boolean bfd_copy_private_section_data #define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \ BFD_SEND (obfd, _bfd_copy_private_section_data, \ (ibfd, isection, obfd, osection)) -void _bfd_strip_section_from_output - (struct bfd_link_info *info, asection *section); - bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec); bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group); diff --git a/bfd/coff-ppc.c b/bfd/coff-ppc.c index 14c9f56fb94..d7fee94f17f 100644 --- a/bfd/coff-ppc.c +++ b/bfd/coff-ppc.c @@ -2113,7 +2113,7 @@ ppc_bfd_coff_final_link (abfd, info) o->reloc_count = 0; o->lineno_count = 0; - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) { if (p->type == bfd_indirect_link_order) { @@ -2295,7 +2295,7 @@ ppc_bfd_coff_final_link (abfd, info) for (o = abfd->sections; o != NULL; o = o->next) { - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) { if (p->type == bfd_indirect_link_order && (bfd_get_flavour (p->u.indirect.section->owner) diff --git a/bfd/cofflink.c b/bfd/cofflink.c index 325f7875d37..dc1edf63c25 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -693,7 +693,7 @@ _bfd_coff_final_link (bfd *abfd, { o->reloc_count = 0; o->lineno_count = 0; - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) { if (p->type == bfd_indirect_link_order) { @@ -888,7 +888,7 @@ _bfd_coff_final_link (bfd *abfd, for (o = abfd->sections; o != NULL; o = o->next) { - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) { if (p->type == bfd_indirect_link_order && bfd_family_coff (p->u.indirect.section->owner)) diff --git a/bfd/ecoff.c b/bfd/ecoff.c index 2cc3b52db60..beac8942b88 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -76,8 +76,8 @@ static asection bfd_debug_section = NULL, /* symbol_ptr_ptr, */ NULL, - /* link_order_head, link_order_tail */ - NULL, NULL + /* map_head, map_tail */ + { NULL }, { NULL } }; /* Create an ECOFF object. */ @@ -4523,7 +4523,7 @@ _bfd_ecoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info) for (o = abfd->sections; o != NULL; o = o->next) { o->reloc_count = 0; - for (p = o->link_order_head; + for (p = o->map_head.link_order; p != NULL; p = p->next) if (p->type == bfd_indirect_link_order) @@ -4593,7 +4593,7 @@ _bfd_ecoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info) for (o = abfd->sections; o != NULL; o = o->next) { - for (p = o->link_order_head; + for (p = o->map_head.link_order; p != NULL; p = p->next) { diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index 62cb182839d..91dc34532ab 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -853,8 +853,8 @@ _bfd_elf_discard_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info) /* This function is called from size_dynamic_sections. It needs to decide whether .eh_frame_hdr should be output or not, - because later on it is too late for calling _bfd_strip_section_from_output, - since dynamic symbol table has been sized. */ + because when the dynamic symbol table has been sized it is too late + to strip sections. */ bfd_boolean _bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info) @@ -888,7 +888,7 @@ _bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info) if (abfd == NULL) { - _bfd_strip_section_from_output (info, hdr_info->hdr_sec); + hdr_info->hdr_sec->flags |= SEC_EXCLUDE; hdr_info->hdr_sec = NULL; return TRUE; } diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c index 380783e507e..7c8a21d7fa0 100644 --- a/bfd/elf-m10300.c +++ b/bfd/elf-m10300.c @@ -4291,7 +4291,7 @@ _bfd_mn10300_elf_size_dynamic_sections (output_bfd, info) if (strip) { - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } diff --git a/bfd/elf.c b/bfd/elf.c index 5c857a957cd..ae945bdc476 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -2499,7 +2499,7 @@ elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg) struct bfd_link_order *l; asection *elt; - for (l = asect->link_order_head; l != NULL; l = l->next) + for (l = asect->map_head.link_order; l != NULL; l = l->next) if (l->type == bfd_indirect_link_order && (elt = elf_next_in_group (l->u.indirect.section)) != NULL) do @@ -2616,7 +2616,7 @@ elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg) struct bfd_link_order *o; this_hdr->sh_size = 0; - for (o = asect->link_order_head; o != NULL; o = o->next) + for (o = asect->map_head.link_order; o != NULL; o = o->next) if (this_hdr->sh_size < o->offset + o->size) this_hdr->sh_size = o->offset + o->size; if (this_hdr->sh_size) @@ -2722,7 +2722,7 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg) /* If this is a relocatable link, then the above did nothing because SEC is the output section. Look through the input sections instead. */ - for (l = sec->link_order_head; l != NULL; l = l->next) + for (l = sec->map_head.link_order; l != NULL; l = l->next) if (l->type == bfd_indirect_link_order && (elt = elf_next_in_group (l->u.indirect.section)) != NULL) do @@ -2924,7 +2924,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) /* Find out what the corresponding section in output is. */ - for (p = sec->link_order_head; p != NULL; p = p->next) + for (p = sec->map_head.link_order; p != NULL; p = p->next) { s = p->u.indirect.section; if (p->type == bfd_indirect_link_order @@ -4295,7 +4295,7 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info) struct bfd_link_order *o; bfd_vma tbss_size = 0; - for (o = sec->link_order_head; o != NULL; o = o->next) + for (o = sec->map_head.link_order; o != NULL; o = o->next) if (tbss_size < o->offset + o->size) tbss_size = o->offset + o->size; diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 77e76b86535..520a1ea7407 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -5505,7 +5505,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED, if (strip) { - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c index d476723e6fb..d3676f87886 100644 --- a/bfd/elf32-cris.c +++ b/bfd/elf32-cris.c @@ -2991,7 +2991,7 @@ elf_cris_size_dynamic_sections (output_bfd, info) if (strip) { - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index d939b55d0b3..c19b8c55eb0 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -2270,7 +2270,7 @@ elf32_hppa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, adjust_dynamic_symbol is called, and it is that function which decides whether anything needs to go into these sections. */ - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } @@ -2376,7 +2376,7 @@ elf32_hppa_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info) /* We can't use output_bfd->section_count here to find the top output section index as some sections may have been removed, and - _bfd_strip_section_from_output doesn't renumber the indices. */ + strip_excluded_output_sections doesn't renumber the indices. */ for (section = output_bfd->sections, top_index = 0; section != NULL; section = section->next) diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 736c8f71112..943f65a5ec7 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1862,7 +1862,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, function which decides whether anything needs to go into these sections. */ - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c index bd61c5e05b0..fbc2c8cc877 100644 --- a/bfd/elf32-m32r.c +++ b/bfd/elf32-m32r.c @@ -2448,7 +2448,7 @@ printf("m32r_elf_size_dynamic_sections()\n"); adjust_dynamic_symbol is called, and it is that function which decides whether anything needs to go into these sections. */ - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } diff --git a/bfd/elf32-m68hc1x.c b/bfd/elf32-m68hc1x.c index 958715a3c34..fb5e6abc7b3 100644 --- a/bfd/elf32-m68hc1x.c +++ b/bfd/elf32-m68hc1x.c @@ -265,7 +265,7 @@ elf32_m68hc11_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info) /* We can't use output_bfd->section_count here to find the top output section index as some sections may have been removed, and - _bfd_strip_section_from_output doesn't renumber the indices. */ + strip_excluded_output_sections doesn't renumber the indices. */ for (section = output_bfd->sections, top_index = 0; section != NULL; section = section->next) diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c index fc4dbace1c5..d84f6694e47 100644 --- a/bfd/elf32-m68k.c +++ b/bfd/elf32-m68k.c @@ -1241,7 +1241,7 @@ elf_m68k_size_dynamic_sections (output_bfd, info) if (strip) { - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 9e9acec9dcd..6f572da2c39 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -4084,7 +4084,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, if (s->size == 0) { - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index e8471ebf435..70fb7955318 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -2124,7 +2124,7 @@ elf_s390_size_dynamic_sections (output_bfd, info) function which decides whether anything needs to go into these sections. */ - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index 164b35e7602..34c6c3cca72 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -4389,7 +4389,7 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, function which decides whether anything needs to go into these sections. */ - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c index f9114cb3e64..919bcf601e8 100644 --- a/bfd/elf32-vax.c +++ b/bfd/elf32-vax.c @@ -1273,7 +1273,7 @@ elf_vax_size_dynamic_sections (output_bfd, info) if (strip) { - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 8dc18380fd3..639baf7b280 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -1462,7 +1462,7 @@ elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, } if (strip) - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; else { /* Allocate memory for the section contents. */ diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index adbdc8260f1..fdc071a72c6 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -4058,7 +4058,7 @@ elf64_alpha_size_dynamic_sections (output_bfd, info) } if (strip) - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; else { /* Allocate memory for the section contents. */ @@ -5184,7 +5184,7 @@ elf64_alpha_final_link (abfd, info) } } - for (p = o->link_order_head; + for (p = o->map_head.link_order; p != (struct bfd_link_order *) NULL; p = p->next) { @@ -5305,7 +5305,7 @@ elf64_alpha_final_link (abfd, info) /* Skip this section later on (I don't think this currently matters, but someday it might). */ - o->link_order_head = (struct bfd_link_order *) NULL; + o->map_head.link_order = (struct bfd_link_order *) NULL; mdebug_sec = o; } diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c index 84e3d2b8a3c..075863c52e2 100644 --- a/bfd/elf64-hppa.c +++ b/bfd/elf64-hppa.c @@ -1808,7 +1808,7 @@ elf64_hppa_size_dynamic_sections (output_bfd, info) if (strip) { - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index c938dc67166..115610ac0d2 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -5539,7 +5539,7 @@ ppc64_elf_func_desc_adjust (bfd *obfd ATTRIBUTE_UNUSED, elf_link_hash_traverse (&htab->elf, func_desc_adjust, info); if (htab->sfpr->size == 0) - _bfd_strip_section_from_output (info, htab->sfpr); + htab->sfpr->flags |= SEC_EXCLUDE; return TRUE; } @@ -7687,7 +7687,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, if (s->size == 0) { - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } @@ -7716,7 +7716,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, if (s != NULL && s != htab->got) { if (s->size == 0) - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; else { s->contents = bfd_zalloc (ibfd, s->size); @@ -7728,7 +7728,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, if (s != NULL) { if (s->size == 0) - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; else { s->contents = bfd_zalloc (ibfd, s->size); @@ -8336,7 +8336,7 @@ ppc64_elf_setup_section_lists (bfd *output_bfd, /* We can't use output_bfd->section_count here to find the top output section index as some sections may have been removed, and - _bfd_strip_section_from_output doesn't renumber the indices. */ + strip_excluded_output_sections doesn't renumber the indices. */ for (section = output_bfd->sections, top_index = 0; section != NULL; section = section->next) diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index 0bbbcf56251..6f34201e36d 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -2095,7 +2095,7 @@ elf_s390_size_dynamic_sections (output_bfd, info) function which decides whether anything needs to go into these sections. */ - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c index aee8b3bf537..b58d97d3861 100644 --- a/bfd/elf64-sh64.c +++ b/bfd/elf64-sh64.c @@ -3640,7 +3640,7 @@ sh64_elf64_size_dynamic_sections (bfd *output_bfd, if (strip) { - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 00e0bc4b311..40e8b09a145 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -1654,7 +1654,7 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, function which decides whether anything needs to go into these sections. */ - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } diff --git a/bfd/elflink.c b/bfd/elflink.c index 8f3e4c874c1..bc71e98026e 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -5289,12 +5289,8 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, if (elf_hash_table (info)->dynamic_sections_created) { - bfd_size_type dynsymcount; unsigned long section_sym_count; asection *s; - size_t bucketcount = 0; - size_t hash_entry_size; - unsigned int dtagcount; /* Set up the version definition section. */ s = bfd_get_section_by_name (dynobj, ".gnu.version_d"); @@ -5309,7 +5305,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, verdefs = verdefs->next; if (verdefs == NULL && !info->create_default_symver) - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; else { unsigned int cdefs; @@ -5563,7 +5559,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, &sinfo); if (elf_tdata (output_bfd)->verref == NULL) - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; else { Elf_Internal_Verneed *t; @@ -5652,6 +5648,37 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, } } + if ((elf_tdata (output_bfd)->cverrefs == 0 + && elf_tdata (output_bfd)->cverdefs == 0) + || _bfd_elf_link_renumber_dynsyms (output_bfd, info, + §ion_sym_count) == 0) + { + s = bfd_get_section_by_name (dynobj, ".gnu.version"); + s->flags |= SEC_EXCLUDE; + } + } + return TRUE; +} + +bfd_boolean +bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) +{ + if (!is_elf_hash_table (info->hash)) + return TRUE; + + if (elf_hash_table (info)->dynamic_sections_created) + { + bfd *dynobj; + const struct elf_backend_data *bed; + asection *s; + bfd_size_type dynsymcount; + unsigned long section_sym_count; + size_t bucketcount = 0; + size_t hash_entry_size; + unsigned int dtagcount; + + dynobj = elf_hash_table (info)->dynobj; + /* Assign dynsym indicies. In a shared library we generate a section symbol for each output section, which come first. Next come all of the back-end allocated local dynamic syms, @@ -5663,17 +5690,8 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, /* Work out the size of the symbol version section. */ s = bfd_get_section_by_name (dynobj, ".gnu.version"); BFD_ASSERT (s != NULL); - if (dynsymcount == 0 - || (verdefs == NULL && elf_tdata (output_bfd)->verref == NULL - && !info->create_default_symver)) - { - _bfd_strip_section_from_output (info, s); - /* The DYNSYMCOUNT might have changed if we were going to - output a dynamic symbol table entry for S. */ - dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info, - §ion_sym_count); - } - else + if (dynsymcount != 0 + && (s->flags & SEC_EXCLUDE) == 0) { s->size = dynsymcount * sizeof (Elf_External_Versym); s->contents = bfd_zalloc (output_bfd, s->size); @@ -5692,6 +5710,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, section as we went along in elf_link_add_object_symbols. */ s = bfd_get_section_by_name (dynobj, ".dynsym"); BFD_ASSERT (s != NULL); + bed = get_elf_backend_data (output_bfd); s->size = dynsymcount * bed->s->sizeof_sym; if (dynsymcount != 0) @@ -5957,7 +5976,7 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec) count = reldyn->size / ext_size; size = 0; - for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next) + for (lo = reldyn->map_head.link_order; lo != NULL; lo = lo->next) if (lo->type == bfd_indirect_link_order) { asection *o = lo->u.indirect.section; @@ -5982,7 +6001,7 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec) else r_sym_mask = ~(bfd_vma) 0xffffffff; - for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next) + for (lo = reldyn->map_head.link_order; lo != NULL; lo = lo->next) if (lo->type == bfd_indirect_link_order) { bfd_byte *erel, *erelend; @@ -6032,7 +6051,7 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec) qsort (s_non_relative, count - ret, sort_elt, elf_link_sort_cmp2); - for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next) + for (lo = reldyn->map_head.link_order; lo != NULL; lo = lo->next) if (lo->type == bfd_indirect_link_order) { bfd_byte *erel, *erelend; @@ -7655,7 +7674,7 @@ elf_fixup_link_order (bfd *abfd, asection *o) seen_other = 0; seen_linkorder = 0; - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) { if (p->type == bfd_indirect_link_order && (bfd_get_flavour ((sub = p->u.indirect.section->owner)) @@ -7689,7 +7708,7 @@ elf_fixup_link_order (bfd *abfd, asection *o) xmalloc (seen_linkorder * sizeof (struct bfd_link_order *)); seen_linkorder = 0; - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) { sections[seen_linkorder++] = p; } @@ -7803,7 +7822,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) struct bfd_elf_section_data *esdo = elf_section_data (o); o->reloc_count = 0; - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) { unsigned int reloc_count = 0; struct bfd_elf_section_data *esdi = NULL; @@ -8143,7 +8162,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) { struct bfd_link_order *o; - for (o = sec->link_order_head; o != NULL; o = o->next) + for (o = sec->map_head.link_order; o != NULL; o = o->next) if (size < o->offset + o->size) size = o->offset + o->size; } @@ -8185,7 +8204,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) sub->output_has_begun = FALSE; for (o = abfd->sections; o != NULL; o = o->next) { - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) { if (p->type == bfd_indirect_link_order && (bfd_get_flavour ((sub = p->u.indirect.section->owner)) diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index 80b63b45800..4db55a45df8 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -1558,7 +1558,7 @@ elfNN_ia64_modify_segment_map (abfd, info) int i; for (i = m->count - 1; i >= 0; --i) { - struct bfd_link_order *order = m->sections[i]->link_order_head; + struct bfd_link_order *order = m->sections[i]->map_head.link_order; while (order) { if (order->type == bfd_indirect_link_order) @@ -3052,7 +3052,7 @@ elfNN_ia64_size_dynamic_sections (output_bfd, info) } if (strip) - _bfd_strip_section_from_output (info, sec); + sec->flags |= SEC_EXCLUDE; else { /* Allocate memory for the section contents. */ diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index c4d697cb1f7..c881b39b93c 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -962,7 +962,7 @@ mips_elf_create_procedure_table (void *handle, bfd *abfd, /* Skip this section later on (I don't think this currently matters, but someday it might). */ - s->link_order_head = NULL; + s->map_head.link_order = NULL; if (epdr != NULL) free (epdr); @@ -6796,7 +6796,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd, if (strip) { - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } @@ -8986,7 +8986,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info) /* We have found the .reginfo section in the output file. Look through all the link_orders comprising it and merge the information together. */ - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) { asection *input_section; bfd *input_bfd; @@ -9029,7 +9029,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info) /* Skip this section later on (I don't think this currently matters, but someday it might). */ - o->link_order_head = NULL; + o->map_head.link_order = NULL; reginfo_sec = o; } @@ -9102,7 +9102,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info) return FALSE; } - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) { asection *input_section; bfd *input_bfd; @@ -9242,7 +9242,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info) /* Skip this section later on (I don't think this currently matters, but someday it might). */ - o->link_order_head = NULL; + o->map_head.link_order = NULL; mdebug_sec = o; } @@ -9261,7 +9261,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info) not used in executables files. */ if (! info->relocatable) { - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) { asection *input_section; @@ -9281,7 +9281,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info) /* Skip this section later on (I don't think this currently matters, but someday it might). */ - o->link_order_head = NULL; + o->map_head.link_order = NULL; /* Really remove the section. */ bfd_section_list_remove (abfd, o); @@ -9331,7 +9331,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info) tab[0].gt_header.gt_unused = 0; /* Combine the input sections. */ - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) { asection *input_section; bfd *input_bfd; @@ -9454,7 +9454,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info) /* Skip this section later on (I don't think this currently matters, but someday it might). */ - o->link_order_head = NULL; + o->map_head.link_order = NULL; } } diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index 61a210bb489..98f703f3c4b 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -2181,7 +2181,7 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd, if (strip) { - _bfd_strip_section_from_output (info, s); + s->flags |= SEC_EXCLUDE; continue; } diff --git a/bfd/linker.c b/bfd/linker.c index 05058699d36..8500f4fe6db 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -309,7 +309,7 @@ SUBSUBSECTION of the <> structure. Each section in the output file will have a list of - <> structures attached to the <> + <> structures attached to the <> field (the <> structure is defined in <>). These structures describe how to create the contents of the output section in terms of the contents of @@ -2009,7 +2009,7 @@ _bfd_generic_final_link (bfd *abfd, struct bfd_link_info *info) /* Mark all sections which will be included in the output file. */ for (o = abfd->sections; o != NULL; o = o->next) - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) if (p->type == bfd_indirect_link_order) p->u.indirect.section->linker_mark = TRUE; @@ -2038,7 +2038,7 @@ _bfd_generic_final_link (bfd *abfd, struct bfd_link_info *info) for (o = abfd->sections; o != NULL; o = o->next) { o->reloc_count = 0; - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) { if (p->type == bfd_section_reloc_link_order || p->type == bfd_symbol_reloc_link_order) @@ -2094,7 +2094,7 @@ _bfd_generic_final_link (bfd *abfd, struct bfd_link_info *info) /* Handle all the link order information for the sections. */ for (o = abfd->sections; o != NULL; o = o->next) { - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) { switch (p->type) { @@ -2614,11 +2614,11 @@ bfd_new_link_order (bfd *abfd, asection *section) new->type = bfd_undefined_link_order; - if (section->link_order_tail != NULL) - section->link_order_tail->next = new; + if (section->map_tail.link_order != NULL) + section->map_tail.link_order->next = new; else - section->link_order_head = new; - section->link_order_tail = new; + section->map_head.link_order = new; + section->map_tail.link_order = new; return new; } diff --git a/bfd/merge.c b/bfd/merge.c index e302e8f60b6..d973871423e 100644 --- a/bfd/merge.c +++ b/bfd/merge.c @@ -697,8 +697,10 @@ alloc_failure: with _bfd_merge_section. */ bfd_boolean -_bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info, - void *xsinfo, void (*remove_hook) (bfd *, asection *)) +_bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + void *xsinfo, + void (*remove_hook) (bfd *, asection *)) { struct sec_merge_info *sinfo; @@ -763,7 +765,7 @@ _bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info, the hash table at all. */ for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next) if (secinfo->first_str == NULL) - _bfd_strip_section_from_output (info, secinfo->sec); + secinfo->sec->flags |= SEC_EXCLUDE; } return TRUE; diff --git a/bfd/pdp11.c b/bfd/pdp11.c index 9f3942bc1ca..dd2445186b8 100644 --- a/bfd/pdp11.c +++ b/bfd/pdp11.c @@ -3726,11 +3726,11 @@ NAME (aout, final_link) (bfd *abfd, { if (obj_textsec (abfd) != NULL) trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd) - ->link_order_head) + ->map_head.link_order) * obj_reloc_entry_size (abfd)); if (obj_datasec (abfd) != NULL) drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd) - ->link_order_head) + ->map_head.link_order) * obj_reloc_entry_size (abfd)); } @@ -3821,7 +3821,7 @@ NAME (aout, final_link) (bfd *abfd, include. */ for (o = abfd->sections; o != NULL; o = o->next) { - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) if (p->type == bfd_indirect_link_order) p->u.indirect.section->linker_mark = TRUE; } @@ -3829,7 +3829,7 @@ NAME (aout, final_link) (bfd *abfd, have_link_order_relocs = FALSE; for (o = abfd->sections; o != NULL; o = o->next) { - for (p = o->link_order_head; + for (p = o->map_head.link_order; p != NULL; p = p->next) { @@ -3872,7 +3872,7 @@ NAME (aout, final_link) (bfd *abfd, { for (o = abfd->sections; o != NULL; o = o->next) { - for (p = o->link_order_head; + for (p = o->map_head.link_order; p != NULL; p = p->next) { diff --git a/bfd/section.c b/bfd/section.c index 0f396326445..b3b6230f7b8 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -497,8 +497,14 @@ CODE_FRAGMENT . struct bfd_symbol *symbol; . struct bfd_symbol **symbol_ptr_ptr; . -. struct bfd_link_order *link_order_head; -. struct bfd_link_order *link_order_tail; +. {* Early in the link process, map_head and map_tail are used to build +. a list of input sections attached to an output section. Later, +. output sections use these fields for a list of bfd_link_order +. structs. *} +. union { +. struct bfd_link_order *link_order; +. struct bfd_section *s; +. } map_head, map_tail; .} asection; . .{* These sections are global, and are managed by BFD. The application @@ -692,8 +698,8 @@ static const asymbol global_syms[] = /* symbol_ptr_ptr, */ \ (struct bfd_symbol **) &SYM, \ \ - /* link_order_head, link_order_tail */ \ - NULL, NULL \ + /* map_head, map_tail */ \ + { NULL }, { NULL } \ } STD_SECTION (bfd_com_section, SEC_IS_COMMON, bfd_com_symbol, @@ -1441,50 +1447,6 @@ DESCRIPTION . (ibfd, isection, obfd, osection)) */ -/* -FUNCTION - _bfd_strip_section_from_output - -SYNOPSIS - void _bfd_strip_section_from_output - (struct bfd_link_info *info, asection *section); - -DESCRIPTION - Remove @var{section} from the output. If the output section - becomes empty, remove it from the output bfd. - - This function won't actually do anything except twiddle flags - if called too late in the linking process, when it's not safe - to remove sections. -*/ -void -_bfd_strip_section_from_output (struct bfd_link_info *info, asection *s) -{ - asection *os; - asection *is; - bfd *abfd; - - s->flags |= SEC_EXCLUDE; - - /* If the section wasn't assigned to an output section, or the - section has been discarded by the linker script, there's nothing - more to do. */ - os = s->output_section; - if (os == NULL || os->owner == NULL) - return; - - /* If the output section has other (non-excluded) input sections, we - can't remove it. */ - for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next) - for (is = abfd->sections; is != NULL; is = is->next) - if (is->output_section == os && (is->flags & SEC_EXCLUDE) == 0) - return; - - /* If the output section is empty, flag it for removal too. - See ldlang.c:strip_excluded_output_sections for the action. */ - os->flags |= SEC_EXCLUDE; -} - /* FUNCTION bfd_generic_is_group_section diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index d4028f0c46d..2ba50b32645 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -5380,7 +5380,7 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info) { o->reloc_count = 0; o->lineno_count = 0; - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) { if (p->type == bfd_indirect_link_order) { @@ -5669,7 +5669,7 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info) for a single input file at once. */ for (o = abfd->sections; o != NULL; o = o->next) { - for (p = o->link_order_head; p != NULL; p = p->next) + for (p = o->map_head.link_order; p != NULL; p = p->next) { if (p->type == bfd_indirect_link_order && p->u.indirect.section->owner->xvec == abfd->xvec) diff --git a/ld/ChangeLog b/ld/ChangeLog index 938f62e59cb..24481246bbe 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,29 @@ +2005-05-04 Alan Modra + + * ldemul.c: Include bfdlink.h. + (ldemul_before_allocation): Assume before_allocation is non-zero. + (before_allocation_default): Call strip_excluded_output_sections. + * ldlang.c (stripped_excluded_sections): New variable. + (lang_add_section): Build input section list for each output + section, attached via map_head and map_tail pointers. + (strip_excluded_output_sections): Make global. Traverse the + input section lists to find which output sections can go. Clear + link_order pointers and set stripped_excluded_sections. + (lang_process): Call strip_excluded_output_sections. + * ldlang.h (strip_excluded_output_sections): Declare. + * ldwrite.c: Update throuhout for link_order_head -> map_head change. + * emultempl/aix.em (before_allocation): Call + strip_excluded_output_sections. + * emultempl/armcoff.em (before_allocation): Likewise. + * emultempl/beos.em (before_allocation): Likewise. + * emultempl/linux.em (before_allocation): Likewise. + * emultempl/pe.em (before_allocation): Likewise. + * emultempl/sunos.em (before_allocation): Likewise. + * emultempl/elf32.em (before_allocation): Likewise. Call + bfd_elf_size_dynsym_hash_dynstr too. + * emultempl/lnk960.em (lnk960_before_allocation): Delete. + (ld_lnk960): Use before_allocation_default. + 2005-05-02 H.J. Lu * emultempl/elf32.em (gld${EMULATION_NAME}_strip_empty_section): diff --git a/ld/emultempl/aix.em b/ld/emultempl/aix.em index c37cadfe011..480a3c6cfa9 100644 --- a/ld/emultempl/aix.em +++ b/ld/emultempl/aix.em @@ -10,7 +10,7 @@ cat >e${EMULATION_NAME}.c < AIX support by Ian Lance Taylor @@ -787,6 +787,9 @@ gld${EMULATION_NAME}_before_allocation (void) &is->header.next); } } + + if (!link_info.relocatable) + strip_excluded_output_sections (); } static char * diff --git a/ld/emultempl/armcoff.em b/ld/emultempl/armcoff.em index 468c3b08beb..3dc8ee0f724 100644 --- a/ld/emultempl/armcoff.em +++ b/ld/emultempl/armcoff.em @@ -5,7 +5,7 @@ cat >e${EMULATION_NAME}.c <head); + + if (!link_info.relocatable) + strip_excluded_output_sections (); } /* Place an orphan section. We use this to put sections with a '\$' in them diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 2e1dac1a4cb..641cd632114 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -1069,6 +1069,7 @@ gld${EMULATION_NAME}_before_allocation (void) (const char * const *) command_line.auxiliary_filters, &link_info, &sinterp, lang_elf_version_info))) einfo ("%P%F: failed to set dynamic section sizes: %E\n"); + ${ELF_INTERPRETER_SET_DEFAULT} /* Let the user override the dynamic linker we are using. */ if (command_line.interpreter != NULL @@ -1125,6 +1126,12 @@ ${ELF_INTERPRETER_SET_DEFAULT} s->flags |= SEC_EXCLUDE; } } + + if (!link_info.relocatable) + strip_excluded_output_sections (); + + if (!bfd_elf_size_dynsym_hash_dynstr (output_bfd, &link_info)) + einfo ("%P%F: failed to set dynamic section sizes: %E\n"); } EOF diff --git a/ld/emultempl/linux.em b/ld/emultempl/linux.em index 0d2dc5dc560..32a445c9f52 100644 --- a/ld/emultempl/linux.em +++ b/ld/emultempl/linux.em @@ -10,7 +10,7 @@ cat >e${EMULATION_NAME}.c < Linux support by Eric Youngdale @@ -121,6 +121,8 @@ gld${EMULATION_NAME}_before_allocation (void) dynamic linking. */ if (! bfd_${EMULATION_NAME}_size_dynamic_sections (output_bfd, &link_info)) einfo ("%P%F: failed to set dynamic section sizes: %E\n"); + + strip_excluded_output_sections (); } static char * diff --git a/ld/emultempl/lnk960.em b/ld/emultempl/lnk960.em index 7d9176eec86..b58efcc788f 100644 --- a/ld/emultempl/lnk960.em +++ b/ld/emultempl/lnk960.em @@ -129,11 +129,6 @@ lnk960_after_parse (void) add_on (syslib_list, lang_input_file_is_search_file_enum); } -static void -lnk960_before_allocation (void) -{ -} - static void lnk960_after_allocation (void) { @@ -273,7 +268,7 @@ struct ld_emulation_xfer_struct ld_lnk960_emulation = lnk960_after_allocation, lnk960_set_output_arch, lnk960_choose_target, - lnk960_before_allocation, + before_allocation_default, lnk960_get_script, "lnk960", "", diff --git a/ld/emultempl/m68kcoff.em b/ld/emultempl/m68kcoff.em index ba251c12891..2d04ead3c9d 100644 --- a/ld/emultempl/m68kcoff.em +++ b/ld/emultempl/m68kcoff.em @@ -4,7 +4,7 @@ cat >e${EMULATION_NAME}.c <, based on generic.em by Steve Chamberlain , embedded relocs code based on mipsecoff.em by Ian Lance Taylor . diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index 16cc437988b..f2b5c032401 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -1287,6 +1287,9 @@ gld_${EMULATION_NAME}_before_allocation (void) /* We have seen it all. Allocate it, and carry on. */ bfd_arm_pe_allocate_interworking_sections (& link_info); #endif /* TARGET_IS_armpe */ + + if (!link_info.relocatable) + strip_excluded_output_sections (); } #ifdef DLL_SUPPORT diff --git a/ld/emultempl/sunos.em b/ld/emultempl/sunos.em index a84959f3c09..f5595ddf38f 100644 --- a/ld/emultempl/sunos.em +++ b/ld/emultempl/sunos.em @@ -809,6 +809,8 @@ gld${EMULATION_NAME}_before_allocation (void) hdyn->u.def.section = sdyn; else hdyn->u.def.section = bfd_abs_section_ptr; + + strip_excluded_output_sections (); } } diff --git a/ld/ldemul.c b/ld/ldemul.c index abd48fecd80..10cb07c27d5 100644 --- a/ld/ldemul.c +++ b/ld/ldemul.c @@ -1,6 +1,6 @@ /* ldemul.c -- clearing house for ld emulation states Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003 + 2001, 2002, 2003, 2005 Free Software Foundation, Inc. This file is part of GLD, the Gnu Linker. @@ -24,6 +24,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "bfd.h" #include "sysdep.h" #include "getopt.h" +#include "bfdlink.h" #include "ld.h" #include "ldmisc.h" @@ -75,8 +76,7 @@ ldemul_after_allocation (void) void ldemul_before_allocation (void) { - if (ld_emulation->before_allocation) - ld_emulation->before_allocation (); + ld_emulation->before_allocation (); } void @@ -212,6 +212,8 @@ after_allocation_default (void) void before_allocation_default (void) { + if (!link_info.relocatable) + strip_excluded_output_sections (); } void diff --git a/ld/ldlang.c b/ld/ldlang.c index 895eded0bbd..453b7ac202b 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -54,6 +54,7 @@ static struct obstack map_obstack; static const char *startup_file; static lang_statement_list_type input_file_chain; static bfd_boolean placed_commons = FALSE; +static bfd_boolean stripped_excluded_sections = FALSE; static lang_output_section_statement_type *default_common_section; static bfd_boolean map_option_f; static bfd_vma print_dot; @@ -1721,6 +1722,19 @@ lang_add_section (lang_statement_list_type *ptr, first = ! output->bfd_section->linker_has_input; output->bfd_section->linker_has_input = 1; + if (!link_info.relocatable + && !stripped_excluded_sections) + { + asection *s = output->bfd_section->map_tail.s; + output->bfd_section->map_tail.s = section; + section->map_head.s = NULL; + section->map_tail.s = s; + if (s != NULL) + s->map_head.s = section; + else + output->bfd_section->map_head.s = section; + } + /* Add a section reference to the list. */ new = new_stat (lang_input_section, ptr); @@ -3029,7 +3043,7 @@ map_input_to_output_sections added. For example, ldemul_before_allocation can remove dynamic sections if they turn out to be not needed. Clean them up here. */ -static void +void strip_excluded_output_sections (void) { lang_output_section_statement_type *os; @@ -3042,9 +3056,20 @@ strip_excluded_output_sections (void) if (os->constraint == -1) continue; - s = os->bfd_section; - if (s != NULL && (s->flags & SEC_EXCLUDE) != 0) + + if (os->bfd_section == NULL || os->bfd_section->map_head.s == NULL) + continue; + + for (s = os->bfd_section->map_head.s; s != NULL; s = s->map_head.s) + if ((s->flags & SEC_EXCLUDE) == 0) + break; + + os->bfd_section->map_head.link_order = NULL; + os->bfd_section->map_tail.link_order = NULL; + + if (s == NULL) { + s = os->bfd_section; os->bfd_section = NULL; if (!bfd_section_removed_from_list (output_bfd, s)) { @@ -3053,6 +3078,10 @@ strip_excluded_output_sections (void) } } } + + /* Stop future calls to lang_add_section from messing with map_head + and map_tail link_order fields. */ + stripped_excluded_sections = TRUE; } static void @@ -5226,9 +5255,6 @@ lang_process (void) and other back-ends size dynamic sections. */ ldemul_before_allocation (); - if (!link_info.relocatable) - strip_excluded_output_sections (); - /* We must record the program headers before we try to fix the section positions, since they will affect SIZEOF_HEADERS. */ lang_record_phdrs (); diff --git a/ld/ldlang.h b/ld/ldlang.h index 2cf8259c457..7fca8b0dbea 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -549,6 +549,8 @@ extern void lang_for_each_statement (void (*) (lang_statement_union_type *)); extern void *stat_alloc (size_t); +extern void strip_excluded_output_sections + (void); extern void dprint_statement (lang_statement_union_type *, int); extern bfd_vma lang_size_sections diff --git a/ld/ldwrite.c b/ld/ldwrite.c index 56c4d0a3434..5538c65eb34 100644 --- a/ld/ldwrite.c +++ b/ld/ldwrite.c @@ -378,7 +378,7 @@ clone_section (bfd *abfd, asection *s, const char *name, int *count) static void ds (asection *s) { - struct bfd_link_order *l = s->link_order_head; + struct bfd_link_order *l = s->map_head.link_order; printf ("vma %x size %x\n", s->vma, s->size); while (l) { @@ -410,7 +410,7 @@ sanity_check (bfd *abfd) { struct bfd_link_order *p; bfd_vma prev = 0; - for (p = s->link_order_head; p; p = p->next) + for (p = s->map_head.link_order; p; p = p->next) { if (p->offset > 100000) abort (); @@ -447,7 +447,7 @@ split_sections (bfd *abfd, struct bfd_link_info *info) /* Count up the relocations and line entries to see if anything would be too big to fit. Accumulate section size too. */ - for (l = NULL, p = cursor->link_order_head; p != NULL; p = l->next) + for (l = NULL, p = cursor->map_head.link_order; p != NULL; p = l->next) { unsigned int thislines = 0; unsigned int thisrelocs = 0; @@ -488,9 +488,9 @@ split_sections (bfd *abfd, struct bfd_link_info *info) /* Attach the link orders to the new section and snip them off from the old section. */ - n->link_order_head = p; - n->link_order_tail = cursor->link_order_tail; - cursor->link_order_tail = l; + n->map_head.link_order = p; + n->map_tail.link_order = cursor->map_tail.link_order; + cursor->map_tail.link_order = l; l->next = NULL; l = p;