bfd/
authorAlan Modra <amodra@gmail.com>
Tue, 25 May 2004 06:33:51 +0000 (06:33 +0000)
committerAlan Modra <amodra@gmail.com>
Tue, 25 May 2004 06:33:51 +0000 (06:33 +0000)
* 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.

12 files changed:
bfd/ChangeLog
bfd/elf.c
bfd/elflink.c
bfd/libbfd-in.h
bfd/libbfd.h
bfd/merge.c
ld/ChangeLog
ld/emultempl/armelf.em
ld/emultempl/hppaelf.em
ld/emultempl/ppc64elf.em
ld/ldlang.c
ld/ldwrite.c

index dab90b4b6edef5a86e885648715ff995d5d13d89..93ae1f66dd31c08d5db2df34b091b41ec55b8ed5 100644 (file)
@@ -1,3 +1,22 @@
+2004-05-25  Alan Modra  <amodra@bigpond.net.au>
+
+       * 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  <kettenis@gnu.org>
 
        * netbsd-core.c: Correctly indent section that sets architecture
index e5ab09e3f0be46ffd46f1c6ee2a035ef1e63b1a9..93a3d3ac9f837c6c0deacae5a53378efcdb65430 100644 (file)
--- 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;
 }
index 37540aa871d8ef427460f4ac09404484cec3a58b..436ff840e6d2364fd3800a1b11df6bcabca7dda0 100644 (file)
@@ -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.  */
index 956727d4324eee9ba11e21168c8fbc22b3177cb5..fd7f29662f3a53b4ac4fcb2ce335ce501dd3e354 100644 (file)
@@ -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.  */
 
index 96776cac65d26d184eb33830ad522ecefa65f3cc..30890bc15b7650ea5d3f2a1ab5c96ad73a9326e3 100644 (file)
@@ -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.  */
 
index 3811523ecc917a42e87a23c5f723d95a57652882..6b367b5734a1bc85563bc0ef37ab27f7b9a50209 100644 (file)
@@ -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)
index 266d89a141fd8a871a7e9bab6bd766c6a8e3dfac..d923216dec66aa51d6aae1a9b7cd3c8f41b9ff0e 100644 (file)
@@ -1,3 +1,16 @@
+2004-05-25  Alan Modra  <amodra@bigpond.net.au>
+
+       * 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  <schwab@suse.de>
 
        * ld.texinfo (Options): Fix typo in last change.
index beeb40c72076cb93096c867451990f7349eaebd7..5505f1230d0f33520ce3dbbcfd0dbbddd756b9b6 100644 (file)
@@ -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;
index 93e88ad655a0a6dc9f9490fd9f39aa7795c104ae..edd8e0137ccb894bd4cd6a806947fc65bf5423ce 100644 (file)
@@ -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)
     {
index 4f408a9fa29eb4f8c092a56fc8317270e507cdf1..6a60f0cde06f38b5e1e13d1c3454b7f030a319ac 100644 (file)
@@ -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)
     {
index a19b46a4ba4961d8e4e4cc2f93255b3c3b793a8f..7a268c0eb240225233cc5afd791caf8615b32f48 100644 (file)
@@ -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)
        {
index e4bec32cac8b6e1433895a3513691f12643570d0..47a58061d85d7dca9c28340353601cf5b8f4e46b 100644 (file)
@@ -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;