From ce659574b6d95399c357af464d6d7a903ff57f4e Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 25 May 2004 06:33:51 +0000 Subject: [PATCH] bfd/ * elflink.c (elf_link_add_object_symbols): Don't set up merge section data here.. * elf.c (_bfd_elf_merge_sections): .. Do it here instead. * merge.c: Formatting. Remove unnecessary casts. Expand bfd_get_section_alignment macro. (struct sec_merge_sec_info): Rename "first" to "first_str". Update use throughout file. (_bfd_add_merge_section): Rename from _bfd_merge_section. Update comment. Abort on dynamic or non-SEC_MERGE input. Don't test section name to determine sinfo group, instead test output section and alignment. (_bfd_merge_sections): Add struct bfd_link_info param. Call _bfd_strip_section_from_output rather than just twiddling flags. * libbfd-in.h (_bfd_add_merge_section): Rename, update comment. (_bfd_merge_sections): Update prototype. * libbfd.h: Regenerate. ld/ * ldlang.c (lang_process): Call bfd_merge_sections later, and only when not a relocatable link. (print_input_section): Handle SEC_EXCLUDE sections. (size_input_section): Don't update dot on SEC_EXCLUDE sections. (lang_do_assignments_1): Likewise. * ldwrite.c (build_link_order): Ignore SEC_EXCLUDE input sections. * emultempl/armelf.em (arm_elf_set_bfd_for_interworking): Likewise. * emultempl/hppaelf.em (build_section_lists): Likewise. * emultempl/ppc64elf.em (build_toc_list): Likewise. (build_section_lists): Likewise. --- bfd/ChangeLog | 19 +++++++++ bfd/elf.c | 25 ++++++++++- bfd/elflink.c | 22 ---------- bfd/libbfd-in.h | 6 +-- bfd/libbfd.h | 6 +-- bfd/merge.c | 105 +++++++++++++++++++++++------------------------ ld/ChangeLog | 13 ++++++ ld/emultempl/armelf.em | 3 +- ld/emultempl/hppaelf.em | 1 + ld/emultempl/ppc64elf.em | 2 + ld/ldlang.c | 96 ++++++++++++++++++++++++------------------- ld/ldwrite.c | 3 +- 12 files changed, 172 insertions(+), 129 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index dab90b4b6..93ae1f66d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,22 @@ +2004-05-25 Alan Modra + + * elflink.c (elf_link_add_object_symbols): Don't set up merge + section data here.. + * elf.c (_bfd_elf_merge_sections): .. Do it here instead. + * merge.c: Formatting. Remove unnecessary casts. Expand + bfd_get_section_alignment macro. + (struct sec_merge_sec_info): Rename "first" to "first_str". Update + use throughout file. + (_bfd_add_merge_section): Rename from _bfd_merge_section. Update + comment. Abort on dynamic or non-SEC_MERGE input. Don't test + section name to determine sinfo group, instead test output section + and alignment. + (_bfd_merge_sections): Add struct bfd_link_info param. Call + _bfd_strip_section_from_output rather than just twiddling flags. + * libbfd-in.h (_bfd_add_merge_section): Rename, update comment. + (_bfd_merge_sections): Update prototype. + * libbfd.h: Regenerate. + 2004-05-24 Mark Kettenis * netbsd-core.c: Correctly indent section that sets architecture diff --git a/bfd/elf.c b/bfd/elf.c index e5ab09e3f..93a3d3ac9 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -901,10 +901,31 @@ merge_sections_remove_hook (bfd *abfd ATTRIBUTE_UNUSED, bfd_boolean _bfd_elf_merge_sections (bfd *abfd, struct bfd_link_info *info) { + bfd *ibfd; + asection *sec; + if (!is_elf_hash_table (info->hash)) return FALSE; - if (elf_hash_table (info)->merge_info) - _bfd_merge_sections (abfd, elf_hash_table (info)->merge_info, + + for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) + if ((ibfd->flags & DYNAMIC) == 0) + for (sec = ibfd->sections; sec != NULL; sec = sec->next) + if ((sec->flags & SEC_MERGE) != 0 + && !bfd_is_abs_section (sec->output_section)) + { + struct bfd_elf_section_data *secdata; + + secdata = elf_section_data (sec); + if (! _bfd_add_merge_section (abfd, + &elf_hash_table (info)->merge_info, + sec, &secdata->sec_info)) + return FALSE; + else if (secdata->sec_info) + sec->sec_info_type = ELF_INFO_TYPE_MERGE; + } + + if (elf_hash_table (info)->merge_info != NULL) + _bfd_merge_sections (abfd, info, elf_hash_table (info)->merge_info, merge_sections_remove_hook); return TRUE; } diff --git a/bfd/elflink.c b/bfd/elflink.c index 37540aa87..436ff840e 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -4127,28 +4127,6 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) } } - if (! info->relocatable - && ! dynamic - && is_elf_hash_table (hash_table)) - { - asection *s; - - for (s = abfd->sections; s != NULL; s = s->next) - if ((s->flags & SEC_MERGE) != 0 - && !bfd_is_abs_section (s->output_section)) - { - struct bfd_elf_section_data *secdata; - - secdata = elf_section_data (s); - if (! _bfd_merge_section (abfd, - & hash_table->merge_info, - s, &secdata->sec_info)) - goto error_return; - else if (secdata->sec_info) - s->sec_info_type = ELF_INFO_TYPE_MERGE; - } - } - if (is_elf_hash_table (hash_table)) { /* Add this bfd to the loaded list. */ diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index 956727d43..fd7f29662 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -520,15 +520,15 @@ extern bfd_boolean _bfd_write_stab_strings extern bfd_vma _bfd_stab_section_offset (bfd *, void **, asection *, void **, bfd_vma); -/* Attempt to merge a SEC_MERGE section. */ +/* Register a SEC_MERGE section as a candidate for merging. */ -extern bfd_boolean _bfd_merge_section +extern bfd_boolean _bfd_add_merge_section (bfd *, void **, asection *, void **); /* Attempt to merge SEC_MERGE sections. */ extern bfd_boolean _bfd_merge_sections - (bfd *, void *, void (*) (bfd *, asection *)); + (bfd *, struct bfd_link_info *, void *, void (*) (bfd *, asection *)); /* Write out a merged section. */ diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 96776cac6..30890bc15 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -525,15 +525,15 @@ extern bfd_boolean _bfd_write_stab_strings extern bfd_vma _bfd_stab_section_offset (bfd *, void **, asection *, void **, bfd_vma); -/* Attempt to merge a SEC_MERGE section. */ +/* Register a SEC_MERGE section as a candidate for merging. */ -extern bfd_boolean _bfd_merge_section +extern bfd_boolean _bfd_add_merge_section (bfd *, void **, asection *, void **); /* Attempt to merge SEC_MERGE sections. */ extern bfd_boolean _bfd_merge_sections - (bfd *, void *, void (*) (bfd *, asection *)); + (bfd *, struct bfd_link_info *, void *, void (*) (bfd *, asection *)); /* Write out a merged section. */ diff --git a/bfd/merge.c b/bfd/merge.c index 3811523ec..6b367b573 100644 --- a/bfd/merge.c +++ b/bfd/merge.c @@ -90,7 +90,7 @@ struct sec_merge_sec_info /* A hash table used to hold section content. */ struct sec_merge_hash *htab; /* First string in this section. */ - struct sec_merge_hash_entry *first; + struct sec_merge_hash_entry *first_str; /* Original section content. */ unsigned char contents[1]; }; @@ -102,30 +102,28 @@ static struct bfd_hash_entry * sec_merge_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table, const char *string) { - struct sec_merge_hash_entry *ret = (struct sec_merge_hash_entry *) entry; - /* Allocate the structure if it has not already been allocated by a subclass. */ - if (ret == (struct sec_merge_hash_entry *) NULL) - ret = ((struct sec_merge_hash_entry *) - bfd_hash_allocate (table, sizeof (struct sec_merge_hash_entry))); - if (ret == (struct sec_merge_hash_entry *) NULL) + if (entry == NULL) + entry = bfd_hash_allocate (table, sizeof (struct sec_merge_hash_entry)); + if (entry == NULL) return NULL; /* Call the allocation method of the superclass. */ - ret = ((struct sec_merge_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); + entry = bfd_hash_newfunc (entry, table, string); - if (ret) + if (entry != NULL) { /* Initialize the local fields. */ + struct sec_merge_hash_entry *ret = (struct sec_merge_hash_entry *) entry; + ret->u.suffix = NULL; ret->alignment = 0; ret->secinfo = NULL; ret->next = NULL; } - return (struct bfd_hash_entry *) ret; + return entry; } /* Look up an entry in a section merge hash table. */ @@ -192,7 +190,7 @@ sec_merge_hash_lookup (struct sec_merge_hash *table, const char *string, index = hash % table->table.size; for (hashp = (struct sec_merge_hash_entry *) table->table.table[index]; - hashp != (struct sec_merge_hash_entry *) NULL; + hashp != NULL; hashp = (struct sec_merge_hash_entry *) hashp->root.next) { if (hashp->root.hash == hash @@ -216,13 +214,12 @@ sec_merge_hash_lookup (struct sec_merge_hash *table, const char *string, } if (! create) - return (struct sec_merge_hash_entry *) NULL; + return NULL; - hashp = (struct sec_merge_hash_entry *) - sec_merge_hash_newfunc ((struct bfd_hash_entry *) NULL, - (struct bfd_hash_table *) table, string); - if (hashp == (struct sec_merge_hash_entry *) NULL) - return (struct sec_merge_hash_entry *) NULL; + hashp = ((struct sec_merge_hash_entry *) + sec_merge_hash_newfunc (NULL, &table->table, string)); + if (hashp == NULL) + return NULL; hashp->root.string = string; hashp->root.hash = hash; hashp->len = len; @@ -239,9 +236,8 @@ static struct sec_merge_hash * sec_merge_init (unsigned int entsize, bfd_boolean strings) { struct sec_merge_hash *table; - bfd_size_type amt = sizeof (struct sec_merge_hash); - table = (struct sec_merge_hash *) bfd_malloc (amt); + table = bfd_malloc (sizeof (struct sec_merge_hash)); if (table == NULL) return NULL; @@ -294,7 +290,7 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry) asection *sec = secinfo->sec; char *pad = ""; bfd_size_type off = 0; - int alignment_power = bfd_get_section_alignment (abfd, sec->output_section); + int alignment_power = sec->output_section->alignment_power; if (alignment_power) pad = bfd_zmalloc ((bfd_size_type) 1 << alignment_power); @@ -308,7 +304,7 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry) if (len) { len = entry->alignment - len; - if (bfd_bwrite (pad, (bfd_size_type) len, abfd) != len) + if (bfd_bwrite (pad, len, abfd) != len) break; off += len; } @@ -316,7 +312,7 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry) str = entry->root.string; len = entry->len; - if (bfd_bwrite (str, (bfd_size_type) len, abfd) != len) + if (bfd_bwrite (str, len, abfd) != len) break; off += len; @@ -328,20 +324,24 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry) return entry == NULL || entry->secinfo != secinfo; } -/* This function is called for each input file from the add_symbols - pass of the linker. */ +/* Register a SEC_MERGE section as a candidate for merging. + This function is called for all non-dynamic SEC_MERGE input sections. */ bfd_boolean -_bfd_merge_section (bfd *abfd, void **psinfo, asection *sec, void **psecinfo) +_bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec, + void **psecinfo) { struct sec_merge_info *sinfo; struct sec_merge_sec_info *secinfo; unsigned int align; bfd_size_type amt; + if ((abfd->flags & DYNAMIC) != 0 + || (sec->flags & SEC_MERGE) == 0) + abort (); + if (sec->_raw_size == 0 - || (sec->flags & SEC_EXCLUDE) - || (sec->flags & SEC_MERGE) == 0 + || (sec->flags & SEC_EXCLUDE) != 0 || sec->entsize == 0) return TRUE; @@ -351,12 +351,12 @@ _bfd_merge_section (bfd *abfd, void **psinfo, asection *sec, void **psecinfo) return TRUE; } - align = bfd_get_section_alignment (sec->owner, sec); - if ((sec->entsize < (unsigned int)(1 << align) + align = sec->alignment_power; + if ((sec->entsize < (unsigned) 1 << align && ((sec->entsize & (sec->entsize - 1)) || !(sec->flags & SEC_STRINGS))) - || (sec->entsize > (unsigned int)(1 << align) - && (sec->entsize & ((1 << align) - 1)))) + || (sec->entsize > (unsigned) 1 << align + && (sec->entsize & (((unsigned) 1 << align) - 1)))) { /* Sanity check. If string character size is smaller than alignment, then we require character size to be a power @@ -371,14 +371,14 @@ _bfd_merge_section (bfd *abfd, void **psinfo, asection *sec, void **psecinfo) if ((secinfo = sinfo->chain) && ! ((secinfo->sec->flags ^ sec->flags) & (SEC_MERGE | SEC_STRINGS)) && secinfo->sec->entsize == sec->entsize - && ! strcmp (secinfo->sec->name, sec->name)) + && secinfo->sec->alignment_power == sec->alignment_power + && secinfo->sec->output_section == sec->output_section) break; if (sinfo == NULL) { /* Initialize the information we need to keep track of. */ - amt = sizeof (struct sec_merge_info); - sinfo = (struct sec_merge_info *) bfd_alloc (abfd, amt); + sinfo = bfd_alloc (abfd, sizeof (struct sec_merge_info)); if (sinfo == NULL) goto error_return; sinfo->next = (struct sec_merge_info *) *psinfo; @@ -396,7 +396,7 @@ _bfd_merge_section (bfd *abfd, void **psinfo, asection *sec, void **psecinfo) if (*psecinfo == NULL) goto error_return; - secinfo = (struct sec_merge_sec_info *)*psecinfo; + secinfo = (struct sec_merge_sec_info *) *psecinfo; if (sinfo->chain) { secinfo->next = sinfo->chain->next; @@ -408,10 +408,10 @@ _bfd_merge_section (bfd *abfd, void **psinfo, asection *sec, void **psecinfo) secinfo->sec = sec; secinfo->psecinfo = psecinfo; secinfo->htab = sinfo->htab; - secinfo->first = NULL; + secinfo->first_str = NULL; if (! bfd_get_section_contents (sec->owner, sec, secinfo->contents, - (bfd_vma) 0, sec->_raw_size)) + 0, sec->_raw_size)) goto error_return; return TRUE; @@ -433,7 +433,7 @@ record_section (struct sec_merge_info *sinfo, bfd_vma mask, eltalign; unsigned int align, i; - align = bfd_get_section_alignment (sec->owner, sec); + align = sec->alignment_power; end = secinfo->contents + sec->_raw_size; nul = FALSE; mask = ((bfd_vma) 1 << align) - 1; @@ -580,7 +580,7 @@ merge_strings (struct sec_merge_info *sinfo) /* Now sort the strings */ amt = sinfo->htab->size * sizeof (struct sec_merge_hash_entry *); - array = (struct sec_merge_hash_entry **) bfd_malloc (amt); + array = bfd_malloc (amt); if (array == NULL) goto alloc_failure; @@ -643,9 +643,9 @@ alloc_failure: } if (e->alignment) { - if (e->secinfo->first == NULL) + if (e->secinfo->first_str == NULL) { - e->secinfo->first = e; + e->secinfo->first_str = e; size = 0; } size = (size + e->alignment - 1) & ~((bfd_vma) e->alignment - 1); @@ -676,8 +676,8 @@ alloc_failure: with _bfd_merge_section. */ bfd_boolean -_bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, void *xsinfo, - void (*remove_hook) (bfd *, asection *)) +_bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info, + void *xsinfo, void (*remove_hook) (bfd *, asection *)) { struct sec_merge_info *sinfo; @@ -722,11 +722,11 @@ _bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, void *xsinfo, secinfo = NULL; for (e = sinfo->htab->first; e; e = e->next) { - if (e->secinfo->first == NULL) + if (e->secinfo->first_str == NULL) { if (secinfo) secinfo->sec->_cooked_size = size; - e->secinfo->first = e; + e->secinfo->first_str = e; size = 0; } size = (size + e->alignment - 1) @@ -741,11 +741,8 @@ _bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, void *xsinfo, /* Finally remove all input sections which have not made it into the hash table at all. */ for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next) - if (secinfo->first == NULL) - { - secinfo->sec->_cooked_size = 0; - secinfo->sec->flags |= SEC_EXCLUDE; - } + if (secinfo->first_str == NULL) + _bfd_strip_section_from_output (info, secinfo->sec); } return TRUE; @@ -761,14 +758,14 @@ _bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo) secinfo = (struct sec_merge_sec_info *) psecinfo; - if (!secinfo->first) + if (secinfo->first_str == NULL) return TRUE; pos = sec->output_section->filepos + sec->output_offset; if (bfd_seek (output_bfd, pos, SEEK_SET) != 0) return FALSE; - if (! sec_merge_emit (output_bfd, secinfo->first)) + if (! sec_merge_emit (output_bfd, secinfo->first_str)) return FALSE; return TRUE; @@ -797,7 +794,7 @@ _bfd_merged_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, asection **psec, (_("%s: access beyond end of merged section (%ld)"), bfd_get_filename (sec->owner), (long) offset); } - return (secinfo->first ? sec->_cooked_size : 0); + return (secinfo->first_str ? sec->_cooked_size : 0); } if (secinfo->htab->strings) diff --git a/ld/ChangeLog b/ld/ChangeLog index 266d89a14..d923216de 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,16 @@ +2004-05-25 Alan Modra + + * ldlang.c (lang_process): Call bfd_merge_sections later, and + only when not a relocatable link. + (print_input_section): Handle SEC_EXCLUDE sections. + (size_input_section): Don't update dot on SEC_EXCLUDE sections. + (lang_do_assignments_1): Likewise. + * ldwrite.c (build_link_order): Ignore SEC_EXCLUDE input sections. + * emultempl/armelf.em (arm_elf_set_bfd_for_interworking): Likewise. + * emultempl/hppaelf.em (build_section_lists): Likewise. + * emultempl/ppc64elf.em (build_toc_list): Likewise. + (build_section_lists): Likewise. + 2004-05-23 Andreas Schwab * ld.texinfo (Options): Fix typo in last change. diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index beeb40c72..5505f1230 100644 --- a/ld/emultempl/armelf.em +++ b/ld/emultempl/armelf.em @@ -67,7 +67,8 @@ static void arm_elf_set_bfd_for_interworking (lang_statement_union_type *statement) { if (statement->header.type == lang_input_section_enum - && !statement->input_section.ifile->just_syms_flag) + && !statement->input_section.ifile->just_syms_flag + && (statement->input_section.section->flags & SEC_EXCLUDE) == 0) { asection *i = statement->input_section.section; asection *output_section = i->output_section; diff --git a/ld/emultempl/hppaelf.em b/ld/emultempl/hppaelf.em index 93e88ad65..edd8e0137 100644 --- a/ld/emultempl/hppaelf.em +++ b/ld/emultempl/hppaelf.em @@ -239,6 +239,7 @@ build_section_lists (lang_statement_union_type *statement) { if (statement->header.type == lang_input_section_enum && !statement->input_section.ifile->just_syms_flag + && (statement->input_section.section->flags & SEC_EXCLUDE) == 0 && statement->input_section.section->output_section != NULL && statement->input_section.section->output_section->owner == output_bfd) { diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em index 4f408a9fa..6a60f0cde 100644 --- a/ld/emultempl/ppc64elf.em +++ b/ld/emultempl/ppc64elf.em @@ -288,6 +288,7 @@ build_toc_list (lang_statement_union_type *statement) { if (statement->header.type == lang_input_section_enum && !statement->input_section.ifile->just_syms_flag + && (statement->input_section.section->flags & SEC_EXCLUDE) == 0 && statement->input_section.section->output_section == toc_section) ppc64_elf_next_toc_section (&link_info, statement->input_section.section); } @@ -298,6 +299,7 @@ build_section_lists (lang_statement_union_type *statement) { if (statement->header.type == lang_input_section_enum && !statement->input_section.ifile->just_syms_flag + && (statement->input_section.section->flags & SEC_EXCLUDE) == 0 && statement->input_section.section->output_section != NULL && statement->input_section.section->output_section->owner == output_bfd) { diff --git a/ld/ldlang.c b/ld/ldlang.c index a19b46a4b..7a268c0eb 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -2472,54 +2472,59 @@ print_input_section (lang_input_section_type *in) init_opb (); if (size != 0) { - print_space (); + int len; + bfd_vma addr; + print_space (); minfo ("%s", i->name); - if (i->output_section != NULL) + len = 1 + strlen (i->name); + if (len >= SECTION_NAME_MAP_LENGTH - 1) + { + print_nl (); + len = 0; + } + while (len < SECTION_NAME_MAP_LENGTH) { - int len; + print_space (); + ++len; + } - len = 1 + strlen (i->name); - if (len >= SECTION_NAME_MAP_LENGTH - 1) - { - print_nl (); - len = 0; - } - while (len < SECTION_NAME_MAP_LENGTH) - { - print_space (); - ++len; - } + if (i->output_section != NULL && (i->flags & SEC_EXCLUDE) == 0) + addr = i->output_section->vma + i->output_offset; + else + { + addr = print_dot; + size = 0; + } - minfo ("0x%V %W %B\n", - i->output_section->vma + i->output_offset, TO_ADDR (size), - i->owner); + minfo ("0x%V %W %B\n", addr, TO_ADDR (size), i->owner); - if (i->_cooked_size != 0 && i->_cooked_size != i->_raw_size) - { - len = SECTION_NAME_MAP_LENGTH + 3; + if (size != i->_raw_size) + { + len = SECTION_NAME_MAP_LENGTH + 3; #ifdef BFD64 - len += 16; + len += 16; #else - len += 8; + len += 8; #endif - while (len > 0) - { - print_space (); - --len; - } - - minfo (_("%W (size before relaxing)\n"), i->_raw_size); + while (len > 0) + { + print_space (); + --len; } + minfo (_("%W (size before relaxing)\n"), i->_raw_size); + } + + if (i->output_section != NULL && (i->flags & SEC_EXCLUDE) == 0) + { if (command_line.reduce_memory_overheads) bfd_link_hash_traverse (link_info.hash, print_one_symbol, i); else print_all_symbols (i); - print_dot = (i->output_section->vma + i->output_offset - + TO_ADDR (size)); + print_dot = addr + TO_ADDR (size); } } } @@ -2892,7 +2897,7 @@ size_input_section (lang_statement_union_type **this_ptr, lang_input_section_type *is = &((*this_ptr)->input_section); asection *i = is->section; - if (!is->ifile->just_syms_flag) + if (!is->ifile->just_syms_flag && (i->flags & SEC_EXCLUDE) == 0) { unsigned int alignment_needed; asection *o; @@ -3622,10 +3627,13 @@ lang_do_assignments_1 { asection *in = s->input_section.section; - if (in->_cooked_size != 0) - dot += TO_ADDR (in->_cooked_size); - else - dot += TO_ADDR (in->_raw_size); + if ((in->flags & SEC_EXCLUDE) == 0) + { + if (in->_cooked_size != 0) + dot += TO_ADDR (in->_cooked_size); + else + dot += TO_ADDR (in->_raw_size); + } } break; @@ -4384,12 +4392,6 @@ lang_process (void) if (command_line.gc_sections) lang_gc_sections (); - /* If there were any SEC_MERGE sections, finish their merging, so that - section sizes can be computed. This has to be done after GC of sections, - so that GCed sections are not merged, but before assigning output - sections, since removing whole input sections is hard then. */ - bfd_merge_sections (output_bfd, &link_info); - /* Size up the common data. */ lang_common (); @@ -4402,8 +4404,16 @@ lang_process (void) if (! link_info.relocatable) { + asection *found; + + /* Merge SEC_MERGE sections. This has to be done after GC of + sections, so that GCed sections are not merged, but before + assigning dynamic symbols, since removing whole input sections + is hard then. */ + bfd_merge_sections (output_bfd, &link_info); + /* Look for a text section and set the readonly attribute in it. */ - asection *found = bfd_get_section_by_name (output_bfd, ".text"); + found = bfd_get_section_by_name (output_bfd, ".text"); if (found != NULL) { diff --git a/ld/ldwrite.c b/ld/ldwrite.c index e4bec32ca..47a58061d 100644 --- a/ld/ldwrite.c +++ b/ld/ldwrite.c @@ -220,7 +220,8 @@ build_link_order (lang_statement_union_type *statement) case lang_input_section_enum: /* Create a new link_order in the output section with this attached */ - if (!statement->input_section.ifile->just_syms_flag) + if (!statement->input_section.ifile->just_syms_flag + && (statement->input_section.section->flags & SEC_EXCLUDE) == 0) { asection *i = statement->input_section.section; asection *output_section = i->output_section; -- 2.11.4.GIT